Loading services/core/java/com/android/server/am/LmkdConnection.java +16 −7 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public class LmkdConnection { private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM; // lmkd reply max size in bytes private static final int LMKD_REPLY_MAX_SIZE = 8; private static final int LMKD_REPLY_MAX_SIZE = 12; // connection listener interface interface LmkdConnectionListener { Loading @@ -62,6 +62,15 @@ public class LmkdConnection { */ boolean isReplyExpected(ByteBuffer replyBuf, ByteBuffer dataReceived, int receivedLen); /** * Handle the received message if it's unsolicited. * * @param dataReceived The buffer holding received data * @param receivedLen Size of the data received * @return True if the message has been handled correctly, false otherwise. */ boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen); } private final MessageQueue mMsgQueue; Loading Loading @@ -185,17 +194,17 @@ public class LmkdConnection { mReplyBuf.rewind(); // wakeup the waiting thread mReplyBufLock.notifyAll(); } else { // received asynchronous or unexpected packet } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) { // received unexpected packet // treat this as an error mReplyBuf = null; mReplyBufLock.notifyAll(); Slog.e(TAG, "Received unexpected packet from lmkd"); Slog.e(TAG, "Received an unexpected packet from lmkd"); } } else { } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) { // received asynchronous communication from lmkd // we don't support this yet Slog.w(TAG, "Received an asynchronous packet from lmkd"); // but we don't recognize it. Slog.w(TAG, "Received an unexpected packet from lmkd"); } } } Loading services/core/java/com/android/server/am/ProcessList.java +72 −9 Original line number Diff line number Diff line Loading @@ -253,14 +253,16 @@ public final class ProcessList { // LMK_PROCREMOVE <pid> // LMK_PROCPURGE // LMK_GETKILLCNT // LMK_PROCKILL static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCPURGE = 3; static final byte LMK_GETKILLCNT = 4; static final byte LMK_PROCKILL = 5; // Note: this is an unsolicated command // lmkd reconnect delay in msecs private static final long LMDK_RECONNECT_DELAY_MS = 1000; private static final long LMKD_RECONNECT_DELAY_MS = 1000; ActivityManagerService mService = null; Loading Loading @@ -355,6 +357,12 @@ public final class ProcessList { ActiveUids mActiveUids; /** * The listener who is intereted with the lmkd kills. */ @GuardedBy("mService") private LmkdKillListener mLmkdKillListener = null; /** * The currently running isolated processes. */ Loading @@ -373,6 +381,13 @@ public final class ProcessList { private PlatformCompat mPlatformCompat = null; interface LmkdKillListener { /** * Called when there is a process kill by lmkd. */ void onLmkdKillOccurred(int pid, int uid); } final class IsolatedUidRange { @VisibleForTesting public final int mFirstUid; Loading Loading @@ -525,7 +540,8 @@ public final class ProcessList { final class KillHandler extends Handler { static final int KILL_PROCESS_GROUP_MSG = 4000; static final int LMDK_RECONNECT_MSG = 4001; static final int LMKD_RECONNECT_MSG = 4001; static final int LMKD_PROC_KILLED_MSG = 4002; public KillHandler(Looper looper) { super(looper, null, true); Loading @@ -539,15 +555,18 @@ public final class ProcessList { Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case LMDK_RECONNECT_MSG: case LMKD_RECONNECT_MSG: if (!sLmkdConnection.connect()) { Slog.i(TAG, "Failed to connect to lmkd, retry after " + LMDK_RECONNECT_DELAY_MS + " ms"); // retry after LMDK_RECONNECT_DELAY_MS + LMKD_RECONNECT_DELAY_MS + " ms"); // retry after LMKD_RECONNECT_DELAY_MS sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); } break; case LMKD_PROC_KILLED_MSG: handleLmkdProcKilled(msg.arg1 /* pid */, msg.arg2 /* uid */); break; default: super.handleMessage(msg); Loading Loading @@ -587,7 +606,7 @@ public final class ProcessList { Slog.w(TAG, "Lost connection to lmkd"); // start reconnection after delay to let lmkd restart sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); } @Override public boolean isReplyExpected(ByteBuffer replyBuf, Loading @@ -597,6 +616,26 @@ public final class ProcessList { return (receivedLen == replyBuf.array().length && dataReceived.getInt(0) == replyBuf.getInt(0)); } @Override public boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen) { if (receivedLen < 4) { return false; } switch (dataReceived.getInt(0)) { case LMK_PROCKILL: if (receivedLen != 12) { return false; } sKillHandler.obtainMessage(KillHandler.LMKD_PROC_KILLED_MSG, dataReceived.getInt(4), dataReceived.getInt(8)) .sendToTarget(); return true; default: return false; } } } ); } Loading Loading @@ -1279,10 +1318,10 @@ public final class ProcessList { if (!sLmkdConnection.isConnected()) { // try to connect immediately and then keep retrying sKillHandler.sendMessage( sKillHandler.obtainMessage(KillHandler.LMDK_RECONNECT_MSG)); sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG)); // wait for connection retrying 3 times (up to 3 seconds) if (!sLmkdConnection.waitForConnection(3 * LMDK_RECONNECT_DELAY_MS)) { if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) { return false; } } Loading Loading @@ -3192,4 +3231,28 @@ public final class ProcessList { mService.doStopUidLocked(uidRec.uid, uidRec); } } void setLmkdKillListener(final LmkdKillListener listener) { synchronized (mService) { mLmkdKillListener = listener; } } private void handleLmkdProcKilled(final int pid, final int uid) { // Log only now if (DEBUG_PROCESSES) { Slog.i(TAG, "lmkd kill: pid=" + pid + " uid=" + uid); } if (mService == null) { return; } // Notify any interesed party regarding the lmkd kills synchronized (mService) { final LmkdKillListener listener = mLmkdKillListener; if (listener != null) { mService.mHandler.post(()-> listener.onLmkdKillOccurred(pid, uid)); } } } } Loading
services/core/java/com/android/server/am/LmkdConnection.java +16 −7 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public class LmkdConnection { private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM; // lmkd reply max size in bytes private static final int LMKD_REPLY_MAX_SIZE = 8; private static final int LMKD_REPLY_MAX_SIZE = 12; // connection listener interface interface LmkdConnectionListener { Loading @@ -62,6 +62,15 @@ public class LmkdConnection { */ boolean isReplyExpected(ByteBuffer replyBuf, ByteBuffer dataReceived, int receivedLen); /** * Handle the received message if it's unsolicited. * * @param dataReceived The buffer holding received data * @param receivedLen Size of the data received * @return True if the message has been handled correctly, false otherwise. */ boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen); } private final MessageQueue mMsgQueue; Loading Loading @@ -185,17 +194,17 @@ public class LmkdConnection { mReplyBuf.rewind(); // wakeup the waiting thread mReplyBufLock.notifyAll(); } else { // received asynchronous or unexpected packet } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) { // received unexpected packet // treat this as an error mReplyBuf = null; mReplyBufLock.notifyAll(); Slog.e(TAG, "Received unexpected packet from lmkd"); Slog.e(TAG, "Received an unexpected packet from lmkd"); } } else { } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) { // received asynchronous communication from lmkd // we don't support this yet Slog.w(TAG, "Received an asynchronous packet from lmkd"); // but we don't recognize it. Slog.w(TAG, "Received an unexpected packet from lmkd"); } } } Loading
services/core/java/com/android/server/am/ProcessList.java +72 −9 Original line number Diff line number Diff line Loading @@ -253,14 +253,16 @@ public final class ProcessList { // LMK_PROCREMOVE <pid> // LMK_PROCPURGE // LMK_GETKILLCNT // LMK_PROCKILL static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCPURGE = 3; static final byte LMK_GETKILLCNT = 4; static final byte LMK_PROCKILL = 5; // Note: this is an unsolicated command // lmkd reconnect delay in msecs private static final long LMDK_RECONNECT_DELAY_MS = 1000; private static final long LMKD_RECONNECT_DELAY_MS = 1000; ActivityManagerService mService = null; Loading Loading @@ -355,6 +357,12 @@ public final class ProcessList { ActiveUids mActiveUids; /** * The listener who is intereted with the lmkd kills. */ @GuardedBy("mService") private LmkdKillListener mLmkdKillListener = null; /** * The currently running isolated processes. */ Loading @@ -373,6 +381,13 @@ public final class ProcessList { private PlatformCompat mPlatformCompat = null; interface LmkdKillListener { /** * Called when there is a process kill by lmkd. */ void onLmkdKillOccurred(int pid, int uid); } final class IsolatedUidRange { @VisibleForTesting public final int mFirstUid; Loading Loading @@ -525,7 +540,8 @@ public final class ProcessList { final class KillHandler extends Handler { static final int KILL_PROCESS_GROUP_MSG = 4000; static final int LMDK_RECONNECT_MSG = 4001; static final int LMKD_RECONNECT_MSG = 4001; static final int LMKD_PROC_KILLED_MSG = 4002; public KillHandler(Looper looper) { super(looper, null, true); Loading @@ -539,15 +555,18 @@ public final class ProcessList { Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case LMDK_RECONNECT_MSG: case LMKD_RECONNECT_MSG: if (!sLmkdConnection.connect()) { Slog.i(TAG, "Failed to connect to lmkd, retry after " + LMDK_RECONNECT_DELAY_MS + " ms"); // retry after LMDK_RECONNECT_DELAY_MS + LMKD_RECONNECT_DELAY_MS + " ms"); // retry after LMKD_RECONNECT_DELAY_MS sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); } break; case LMKD_PROC_KILLED_MSG: handleLmkdProcKilled(msg.arg1 /* pid */, msg.arg2 /* uid */); break; default: super.handleMessage(msg); Loading Loading @@ -587,7 +606,7 @@ public final class ProcessList { Slog.w(TAG, "Lost connection to lmkd"); // start reconnection after delay to let lmkd restart sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); } @Override public boolean isReplyExpected(ByteBuffer replyBuf, Loading @@ -597,6 +616,26 @@ public final class ProcessList { return (receivedLen == replyBuf.array().length && dataReceived.getInt(0) == replyBuf.getInt(0)); } @Override public boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen) { if (receivedLen < 4) { return false; } switch (dataReceived.getInt(0)) { case LMK_PROCKILL: if (receivedLen != 12) { return false; } sKillHandler.obtainMessage(KillHandler.LMKD_PROC_KILLED_MSG, dataReceived.getInt(4), dataReceived.getInt(8)) .sendToTarget(); return true; default: return false; } } } ); } Loading Loading @@ -1279,10 +1318,10 @@ public final class ProcessList { if (!sLmkdConnection.isConnected()) { // try to connect immediately and then keep retrying sKillHandler.sendMessage( sKillHandler.obtainMessage(KillHandler.LMDK_RECONNECT_MSG)); sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG)); // wait for connection retrying 3 times (up to 3 seconds) if (!sLmkdConnection.waitForConnection(3 * LMDK_RECONNECT_DELAY_MS)) { if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) { return false; } } Loading Loading @@ -3192,4 +3231,28 @@ public final class ProcessList { mService.doStopUidLocked(uidRec.uid, uidRec); } } void setLmkdKillListener(final LmkdKillListener listener) { synchronized (mService) { mLmkdKillListener = listener; } } private void handleLmkdProcKilled(final int pid, final int uid) { // Log only now if (DEBUG_PROCESSES) { Slog.i(TAG, "lmkd kill: pid=" + pid + " uid=" + uid); } if (mService == null) { return; } // Notify any interesed party regarding the lmkd kills synchronized (mService) { final LmkdKillListener listener = mLmkdKillListener; if (listener != null) { mService.mHandler.post(()-> listener.onLmkdKillOccurred(pid, uid)); } } } }