From c41bfb089c5357d956a0d8e06a4358037ee811a7 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 11 Jul 2023 15:06:07 -0700 Subject: [PATCH] Handle uid state changes on the handler thread. onUidStateChanged callbacks are invoked on android.ui thread, so to avoid blocking it for too long, offload the work to handle the uid state changes to a different thread. Bug: 289157124 Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java Change-Id: I005ee6a7486ec1cc6dfe0c7ad4b488309dbda270 --- .../server/am/BroadcastQueueModernImpl.java | 27 ++++++++++++------- .../android/server/am/BroadcastQueueTest.java | 6 +++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index f420619db4907..5d0fefc75a28d 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -249,6 +249,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private static final int MSG_CHECK_HEALTH = 5; private static final int MSG_CHECK_PENDING_COLD_START_VALIDITY = 6; private static final int MSG_PROCESS_FREEZABLE_CHANGED = 7; + private static final int MSG_UID_STATE_CHANGED = 8; private void enqueueUpdateRunningList() { mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST); @@ -295,6 +296,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } return true; } + case MSG_UID_STATE_CHANGED: { + final int uid = (int) msg.obj; + final int procState = msg.arg1; + synchronized (mService) { + if (procState == ActivityManager.PROCESS_STATE_TOP) { + mUidForeground.put(uid, true); + } else { + mUidForeground.delete(uid); + } + refreshProcessQueuesLocked(uid); + } + return true; + } } return false; }; @@ -672,7 +686,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { @Override public void onProcessFreezableChangedLocked(@NonNull ProcessRecord app) { mLocalHandler.removeMessages(MSG_PROCESS_FREEZABLE_CHANGED, app); - mLocalHandler.sendMessage(mHandler.obtainMessage(MSG_PROCESS_FREEZABLE_CHANGED, app)); + mLocalHandler.obtainMessage(MSG_PROCESS_FREEZABLE_CHANGED, app).sendToTarget(); } @Override @@ -1601,14 +1615,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { - synchronized (mService) { - if (procState == ActivityManager.PROCESS_STATE_TOP) { - mUidForeground.put(uid, true); - } else { - mUidForeground.delete(uid); - } - refreshProcessQueuesLocked(uid); - } + mLocalHandler.removeMessages(MSG_UID_STATE_CHANGED, uid); + mLocalHandler.obtainMessage(MSG_UID_STATE_CHANGED, procState, 0, uid) + .sendToTarget(); } }, ActivityManager.UID_OBSERVER_PROCSTATE, ActivityManager.PROCESS_STATE_TOP, "android"); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 73eb237fa9e76..72c5333e0a02f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -125,6 +125,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; @@ -707,6 +708,9 @@ public class BroadcastQueueTest { private void waitForIdle() throws Exception { mLooper.release(); mQueue.waitForIdle(LOG_WRITER_INFO); + final CountDownLatch latch = new CountDownLatch(1); + mHandlerThread.getThreadHandler().post(latch::countDown); + latch.await(); mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() .acquireLooperManager(mHandlerThread.getLooper())); } @@ -2342,6 +2346,7 @@ public class BroadcastQueueTest { mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); + waitForIdle(); final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); @@ -2375,6 +2380,7 @@ public class BroadcastQueueTest { mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); + waitForIdle(); final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);