Merge changes from topic "lmkd_async_msg"
am: f802ecca30
Change-Id: I105214f7157b680bce028b12a8f437505907a535
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index 0a2f608..cacf676 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -44,7 +44,7 @@
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 {
@@ -62,6 +62,15 @@
*/
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;
@@ -185,17 +194,17 @@
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");
}
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 197829a..3b8d39b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -253,14 +253,16 @@
// 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;
@@ -356,6 +358,12 @@
ActiveUids mActiveUids;
/**
+ * The listener who is intereted with the lmkd kills.
+ */
+ @GuardedBy("mService")
+ private LmkdKillListener mLmkdKillListener = null;
+
+ /**
* The currently running isolated processes.
*/
final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
@@ -373,6 +381,13 @@
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;
@@ -525,7 +540,8 @@
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);
@@ -539,15 +555,18 @@
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);
@@ -587,7 +606,7 @@
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,
@@ -597,6 +616,26 @@
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;
+ }
+ }
}
);
}
@@ -1279,10 +1318,10 @@
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;
}
}
@@ -3192,4 +3231,28 @@
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));
+ }
+ }
+ }
}