adb shell getprop sys.boot_completed
final void finishBooting() {
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1")
}
ANR无响应是在AMS中的UiHandler的handleMessage处理
get the historical process exit reason now.
adb shell dumpsys activity exit-info [package name]
xx@xx:~$ adb shell dumpsys activity exit-info com.android.settings
ACTIVITY MANAGER PROCESS EXIT INFO (dumpsys activity exit-info)
Last Timestamp of Persistence Into Persistent Storage: 2023-06-17 01:46:22.529
package: com.android.settings
Historical Process Exit for uid=1000
ApplicationExitInfo #0:
timestamp=2023-06-17 00:13:02.320 pid=9977 realUid=1000 packageUid=1000 definingUid=1000 user=0
process=com.android.settings reason=10 (USER REQUESTED) subreason=0 (UNKNOWN) status=0
importance=400 pss=66MB rss=178MB description=kill background from process:com.android.htmlviewer state=empty trace=null
ApplicationExitInfo #1:
timestamp=2023-06-15 04:41:17.051 pid=6945 realUid=1000 packageUid=1000 definingUid=1000 user=0
process=com.android.settings reason=13 (OTHER KILLS BY SYSTEM) subreason=0 (UNKNOWN) status=0
importance=400 pss=26MB rss=99MB description=OneKeyClean state=empty trace=null
ApplicationExitInfo #2:
timestamp=2023-06-15 04:37:56.725 pid=13120 realUid=1000 packageUid=1000 definingUid=1000 user=0
process=com.android.settings reason=10 (USER REQUESTED) subreason=0 (UNKNOWN) status=0
importance=400 pss=100MB rss=207MB description=kill background from
AMS通过ProcessList init方法创建sLmkdConnection对象,监听连接。
这里通过socket与native层的服务端进行通信。
// Note: This method is invoked on the main thread but may need to attach various
// handlers to other threads. So take care to be explicit about the looper.
public ActivityManagerService(Context systemContext, ActivityTaskManagerService
atm) {
mProcessList = mInjector.getProcessList(this);
mProcessList.init(this, activeUids, mPlatformCompat);
}
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
void init(ActivityManagerService service, ActiveUids activeUids,
PlatformCompat platformCompat) {
mService = service;
mActiveUids = activeUids;
mPlatformCompat = platformCompat;
mProcLock = service.mProcLock;
// Get this after boot, and won't be changed until it's rebooted, as we don't
// want some apps enabled while some apps disabled
mAppDataIsolationEnabled =
SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true);
mVoldAppDataIsolationEnabled = SystemProperties.getBoolean(
ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
mAppDataIsolationAllowlistedApps = new ArrayList<>(
SystemConfig.getInstance().getAppDataIsolationWhitelistedApps());
if (sKillHandler == null) {
sKillThread = new ServiceThread(TAG + ":kill",
THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
sKillHandler = new KillHandler(sKillThread.getLooper());
sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
new LmkdConnection.LmkdConnectionListener() {
@Override
public boolean onConnect(OutputStream ostream) {
Slog.i(TAG, "Connection with lmkd established");
return onLmkdConnect(ostream);
}
@Override
public void onDisconnect() {
Slog.w(TAG, "Lost connection to lmkd");
// start reconnection after delay to let lmkd restart
sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
}
@Override
public boolean isReplyExpected(ByteBuffer replyBuf,
ByteBuffer dataReceived, int receivedLen) {
// compare the preambule (currently one integer) to check if
// this is the reply packet we are waiting for
return (receivedLen == replyBuf.array().length &&
dataReceived.getInt(0) == replyBuf.getInt(0));
}
@Override
public boolean handleUnsolicitedMessage(DataInputStream inputData,
int receivedLen) {
if (receivedLen < 4) {
return false;
}
try {
switch (inputData.readInt()) {
case LMK_PROCKILL:
if (receivedLen != 12) {
return false;
}
final int pid = inputData.readInt();
final int uid = inputData.readInt();
// MIUI ADD:
Process.killProcessGroup(uid, pid);
mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
return true;
case LMK_KILL_OCCURRED:
if (receivedLen
< LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
return false;
}
LmkdStatsReporter.logKillOccurred(inputData);
return true;
case LMK_STATE_CHANGED:
if (receivedLen
!= LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
return false;
}
final int state = inputData.readInt();
LmkdStatsReporter.logStateChanged(state);
return true;
default:
return false;
}
} catch (IOException e) {
Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
}
return false;
}
}
);
// Start listening on incoming connections from zygotes.
mSystemServerSocketForZygote = createSystemServerSocketForZygote();
if (mSystemServerSocketForZygote != null) {
sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener(
mSystemServerSocketForZygote.getFileDescriptor(),
EVENT_INPUT, this::handleZygoteMessages);
}
mAppExitInfoTracker.init(mService);
mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper());
}
//MIUI MOD: START
if (mService.mHandler != null) {
mService.mHandler.postDelayed(new Runnable() {
@Override
public void run() {
ByteBuffer buf = ByteBuffer.allocate(4);
buf.putInt(LMK_CLEAN_CACHED);
writeLmkd(buf, null);
}
}, KEEP_CACHED_PROCESS_FLAG_TIMEOUT);
}
//END
}
int main(int argc, char **argv) {
if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
if (property_set(LMKD_REINIT_PROP, "")) {
ALOGE("Failed to reset " LMKD_REINIT_PROP " property");
}
return issue_reinit();
}
if (!update_props()) {
ALOGE("Failed to initialize props, exiting.");
return -1;
}
ctx = create_android_logger(KILLINFO_LOG_TAG);
if (!init()) {
....
if (init_reaper()) {
ALOGI("Process reaper initialized with %d threads in the pool",
reaper.thread_cnt());
}
if (!watchdog.init()) {
ALOGE("Failed to initialize the watchdog");
}
mainloop(); //epoll_wait
}
android_log_destroy(&ctx);
ALOGI("exiting");
return 0;
}
init()--->{
ctrl_sock.sock = android_get_control_socket("lmkd");
if (ctrl_sock.sock < 0) {
ALOGE("get lmkd control socket failed");
return -1;
}
ret = listen(ctrl_sock.sock, MAX_DATA_CONN);
}
LMKD更多可参考:Android lmkd 机制从R到T_私房菜的博客-CSDN博客