Merge changes from topic "lmkd_async_msg"

am: f802ecca30

Change-Id: I105214f7157b680bce028b12a8f437505907a535
This commit is contained in:
Jing Ji
2019-12-12 16:38:39 -08:00
committed by android-build-merger
2 changed files with 88 additions and 16 deletions

View File

@@ -44,7 +44,7 @@ public class LmkdConnection {
private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM; private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM;
// lmkd reply max size in bytes // 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 // connection listener interface
interface LmkdConnectionListener { interface LmkdConnectionListener {
@@ -62,6 +62,15 @@ public class LmkdConnection {
*/ */
boolean isReplyExpected(ByteBuffer replyBuf, ByteBuffer dataReceived, boolean isReplyExpected(ByteBuffer replyBuf, ByteBuffer dataReceived,
int receivedLen); 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; private final MessageQueue mMsgQueue;
@@ -185,17 +194,17 @@ public class LmkdConnection {
mReplyBuf.rewind(); mReplyBuf.rewind();
// wakeup the waiting thread // wakeup the waiting thread
mReplyBufLock.notifyAll(); mReplyBufLock.notifyAll();
} else { } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
// received asynchronous or unexpected packet // received unexpected packet
// treat this as an error // treat this as an error
mReplyBuf = null; mReplyBuf = null;
mReplyBufLock.notifyAll(); 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 // received asynchronous communication from lmkd
// we don't support this yet // but we don't recognize it.
Slog.w(TAG, "Received an asynchronous packet from lmkd"); Slog.w(TAG, "Received an unexpected packet from lmkd");
} }
} }
} }

View File

@@ -253,14 +253,16 @@ public final class ProcessList {
// LMK_PROCREMOVE <pid> // LMK_PROCREMOVE <pid>
// LMK_PROCPURGE // LMK_PROCPURGE
// LMK_GETKILLCNT // LMK_GETKILLCNT
// LMK_PROCKILL
static final byte LMK_TARGET = 0; static final byte LMK_TARGET = 0;
static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCPRIO = 1;
static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCREMOVE = 2;
static final byte LMK_PROCPURGE = 3; static final byte LMK_PROCPURGE = 3;
static final byte LMK_GETKILLCNT = 4; static final byte LMK_GETKILLCNT = 4;
static final byte LMK_PROCKILL = 5; // Note: this is an unsolicated command
// lmkd reconnect delay in msecs // 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; ActivityManagerService mService = null;
@@ -355,6 +357,12 @@ public final class ProcessList {
ActiveUids mActiveUids; ActiveUids mActiveUids;
/**
* The listener who is intereted with the lmkd kills.
*/
@GuardedBy("mService")
private LmkdKillListener mLmkdKillListener = null;
/** /**
* The currently running isolated processes. * The currently running isolated processes.
*/ */
@@ -373,6 +381,13 @@ public final class ProcessList {
private PlatformCompat mPlatformCompat = null; private PlatformCompat mPlatformCompat = null;
interface LmkdKillListener {
/**
* Called when there is a process kill by lmkd.
*/
void onLmkdKillOccurred(int pid, int uid);
}
final class IsolatedUidRange { final class IsolatedUidRange {
@VisibleForTesting @VisibleForTesting
public final int mFirstUid; public final int mFirstUid;
@@ -525,7 +540,8 @@ public final class ProcessList {
final class KillHandler extends Handler { final class KillHandler extends Handler {
static final int KILL_PROCESS_GROUP_MSG = 4000; 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) { public KillHandler(Looper looper) {
super(looper, null, true); super(looper, null, true);
@@ -539,15 +555,18 @@ public final class ProcessList {
Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break; break;
case LMDK_RECONNECT_MSG: case LMKD_RECONNECT_MSG:
if (!sLmkdConnection.connect()) { if (!sLmkdConnection.connect()) {
Slog.i(TAG, "Failed to connect to lmkd, retry after " Slog.i(TAG, "Failed to connect to lmkd, retry after "
+ LMDK_RECONNECT_DELAY_MS + " ms"); + LMKD_RECONNECT_DELAY_MS + " ms");
// retry after LMDK_RECONNECT_DELAY_MS // retry after LMKD_RECONNECT_DELAY_MS
sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
} }
break; break;
case LMKD_PROC_KILLED_MSG:
handleLmkdProcKilled(msg.arg1 /* pid */, msg.arg2 /* uid */);
break;
default: default:
super.handleMessage(msg); super.handleMessage(msg);
@@ -587,7 +606,7 @@ public final class ProcessList {
Slog.w(TAG, "Lost connection to lmkd"); Slog.w(TAG, "Lost connection to lmkd");
// start reconnection after delay to let lmkd restart // start reconnection after delay to let lmkd restart
sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS); KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
} }
@Override @Override
public boolean isReplyExpected(ByteBuffer replyBuf, public boolean isReplyExpected(ByteBuffer replyBuf,
@@ -597,6 +616,26 @@ public final class ProcessList {
return (receivedLen == replyBuf.array().length return (receivedLen == replyBuf.array().length
&& dataReceived.getInt(0) == replyBuf.getInt(0)); && 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 @@ public final class ProcessList {
if (!sLmkdConnection.isConnected()) { if (!sLmkdConnection.isConnected()) {
// try to connect immediately and then keep retrying // try to connect immediately and then keep retrying
sKillHandler.sendMessage( sKillHandler.sendMessage(
sKillHandler.obtainMessage(KillHandler.LMDK_RECONNECT_MSG)); sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG));
// wait for connection retrying 3 times (up to 3 seconds) // 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; return false;
} }
} }
@@ -3192,4 +3231,28 @@ public final class ProcessList {
mService.doStopUidLocked(uidRec.uid, uidRec); 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));
}
}
}
} }