Loading services/core/java/com/android/server/am/BroadcastProcessQueue.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UptimeMillisLong; import android.app.ActivityManager; import android.app.BroadcastOptions; import android.content.Intent; import android.content.pm.ResolveInfo; Loading Loading @@ -1045,6 +1046,7 @@ class BroadcastProcessQueue { static final int REASON_CONTAINS_MANIFEST = 17; static final int REASON_FOREGROUND = 18; static final int REASON_CORE_UID = 19; static final int REASON_TOP_PROCESS = 20; @IntDef(flag = false, prefix = { "REASON_" }, value = { REASON_EMPTY, Loading @@ -1066,6 +1068,7 @@ class BroadcastProcessQueue { REASON_CONTAINS_MANIFEST, REASON_FOREGROUND, REASON_CORE_UID, REASON_TOP_PROCESS, }) @Retention(RetentionPolicy.SOURCE) public @interface Reason {} Loading @@ -1091,6 +1094,7 @@ class BroadcastProcessQueue { case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST"; case REASON_FOREGROUND: return "FOREGROUND"; case REASON_CORE_UID: return "CORE_UID"; case REASON_TOP_PROCESS: return "TOP_PROCESS"; default: return Integer.toString(reason); } } Loading Loading @@ -1132,6 +1136,11 @@ class BroadcastProcessQueue { } else if (mUidForeground) { mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAtReason = REASON_FOREGROUND; } else if (app != null && app.getSetProcState() == ActivityManager.PROCESS_STATE_TOP) { // TODO (b/287676625): Use a callback to check when a process goes in and out of // the TOP state. mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAtReason = REASON_TOP_PROCESS; } else if (mProcessPersistent) { mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS; mRunnableAtReason = REASON_PERSISTENT; Loading services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,11 @@ class ProcessRecord implements WindowProcessListener { return mState.getCurProcState(); } @GuardedBy(anyOf = {"mService", "mProcLock"}) int getSetProcState() { return mState.getSetProcState(); } @GuardedBy({"mService", "mProcLock"}) public void makeActive(IApplicationThread thread, ProcessStatsService tracker) { mProfile.onProcessActive(thread, tracker); Loading services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import static org.mockito.Mockito.times; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.BackgroundStartPrivileges; import android.app.BroadcastOptions; Loading Loading @@ -554,6 +555,33 @@ public final class BroadcastQueueModernImplTest { assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); } @Test public void testRunnableAt_processTop() { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); doReturn(ActivityManager.PROCESS_STATE_TOP).when(mProcess).getSetProcState(); queue.setProcessAndUidState(mProcess, false, false); final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, List.of(makeMockRegisteredReceiver())); enqueueOrReplaceBroadcast(queue, timeTickRecord, 0); assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_TOP_PROCESS, queue.getRunnableAtReason()); doReturn(ActivityManager.PROCESS_STATE_SERVICE).when(mProcess).getSetProcState(); queue.setProcessAndUidState(mProcess, false, false); // The new process state will only be taken into account the next time a broadcast // is sent to the process. enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick, List.of(makeMockRegisteredReceiver())), 0); assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); } @Test public void testRunnableAt_persistentProc() { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, Loading Loading
services/core/java/com/android/server/am/BroadcastProcessQueue.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UptimeMillisLong; import android.app.ActivityManager; import android.app.BroadcastOptions; import android.content.Intent; import android.content.pm.ResolveInfo; Loading Loading @@ -1045,6 +1046,7 @@ class BroadcastProcessQueue { static final int REASON_CONTAINS_MANIFEST = 17; static final int REASON_FOREGROUND = 18; static final int REASON_CORE_UID = 19; static final int REASON_TOP_PROCESS = 20; @IntDef(flag = false, prefix = { "REASON_" }, value = { REASON_EMPTY, Loading @@ -1066,6 +1068,7 @@ class BroadcastProcessQueue { REASON_CONTAINS_MANIFEST, REASON_FOREGROUND, REASON_CORE_UID, REASON_TOP_PROCESS, }) @Retention(RetentionPolicy.SOURCE) public @interface Reason {} Loading @@ -1091,6 +1094,7 @@ class BroadcastProcessQueue { case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST"; case REASON_FOREGROUND: return "FOREGROUND"; case REASON_CORE_UID: return "CORE_UID"; case REASON_TOP_PROCESS: return "TOP_PROCESS"; default: return Integer.toString(reason); } } Loading Loading @@ -1132,6 +1136,11 @@ class BroadcastProcessQueue { } else if (mUidForeground) { mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAtReason = REASON_FOREGROUND; } else if (app != null && app.getSetProcState() == ActivityManager.PROCESS_STATE_TOP) { // TODO (b/287676625): Use a callback to check when a process goes in and out of // the TOP state. mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAtReason = REASON_TOP_PROCESS; } else if (mProcessPersistent) { mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS; mRunnableAtReason = REASON_PERSISTENT; Loading
services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,11 @@ class ProcessRecord implements WindowProcessListener { return mState.getCurProcState(); } @GuardedBy(anyOf = {"mService", "mProcLock"}) int getSetProcState() { return mState.getSetProcState(); } @GuardedBy({"mService", "mProcLock"}) public void makeActive(IApplicationThread thread, ProcessStatsService tracker) { mProfile.onProcessActive(thread, tracker); Loading
services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import static org.mockito.Mockito.times; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.BackgroundStartPrivileges; import android.app.BroadcastOptions; Loading Loading @@ -554,6 +555,33 @@ public final class BroadcastQueueModernImplTest { assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); } @Test public void testRunnableAt_processTop() { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); doReturn(ActivityManager.PROCESS_STATE_TOP).when(mProcess).getSetProcState(); queue.setProcessAndUidState(mProcess, false, false); final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, List.of(makeMockRegisteredReceiver())); enqueueOrReplaceBroadcast(queue, timeTickRecord, 0); assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_TOP_PROCESS, queue.getRunnableAtReason()); doReturn(ActivityManager.PROCESS_STATE_SERVICE).when(mProcess).getSetProcState(); queue.setProcessAndUidState(mProcess, false, false); // The new process state will only be taken into account the next time a broadcast // is sent to the process. enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick, List.of(makeMockRegisteredReceiver())), 0); assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); } @Test public void testRunnableAt_persistentProc() { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, Loading