Merge "Consider process proc_state when computing runnableAt." into udc-dev

This commit is contained in:
Sudheer Shanka
2023-06-21 03:38:32 +00:00
committed by Android (Google) Code Review
3 changed files with 42 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UptimeMillisLong; import android.annotation.UptimeMillisLong;
import android.app.ActivityManager;
import android.app.BroadcastOptions; import android.app.BroadcastOptions;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
@@ -1045,6 +1046,7 @@ class BroadcastProcessQueue {
static final int REASON_CONTAINS_MANIFEST = 17; static final int REASON_CONTAINS_MANIFEST = 17;
static final int REASON_FOREGROUND = 18; static final int REASON_FOREGROUND = 18;
static final int REASON_CORE_UID = 19; static final int REASON_CORE_UID = 19;
static final int REASON_TOP_PROCESS = 20;
@IntDef(flag = false, prefix = { "REASON_" }, value = { @IntDef(flag = false, prefix = { "REASON_" }, value = {
REASON_EMPTY, REASON_EMPTY,
@@ -1066,6 +1068,7 @@ class BroadcastProcessQueue {
REASON_CONTAINS_MANIFEST, REASON_CONTAINS_MANIFEST,
REASON_FOREGROUND, REASON_FOREGROUND,
REASON_CORE_UID, REASON_CORE_UID,
REASON_TOP_PROCESS,
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface Reason {} public @interface Reason {}
@@ -1091,6 +1094,7 @@ class BroadcastProcessQueue {
case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST"; case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST";
case REASON_FOREGROUND: return "FOREGROUND"; case REASON_FOREGROUND: return "FOREGROUND";
case REASON_CORE_UID: return "CORE_UID"; case REASON_CORE_UID: return "CORE_UID";
case REASON_TOP_PROCESS: return "TOP_PROCESS";
default: return Integer.toString(reason); default: return Integer.toString(reason);
} }
} }
@@ -1132,6 +1136,11 @@ class BroadcastProcessQueue {
} else if (mUidForeground) { } else if (mUidForeground) {
mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
mRunnableAtReason = REASON_FOREGROUND; 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) { } else if (mProcessPersistent) {
mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS; mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
mRunnableAtReason = REASON_PERSISTENT; mRunnableAtReason = REASON_PERSISTENT;

View File

@@ -674,6 +674,11 @@ class ProcessRecord implements WindowProcessListener {
return mState.getCurProcState(); return mState.getCurProcState();
} }
@GuardedBy(anyOf = {"mService", "mProcLock"})
int getSetProcState() {
return mState.getSetProcState();
}
@GuardedBy({"mService", "mProcLock"}) @GuardedBy({"mService", "mProcLock"})
public void makeActive(IApplicationThread thread, ProcessStatsService tracker) { public void makeActive(IApplicationThread thread, ProcessStatsService tracker) {
mProfile.onProcessActive(thread, tracker); mProfile.onProcessActive(thread, tracker);

View File

@@ -66,6 +66,7 @@ import static org.mockito.Mockito.times;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges; import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions; import android.app.BroadcastOptions;
@@ -554,6 +555,33 @@ public final class BroadcastQueueModernImplTest {
assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); 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 @Test
public void testRunnableAt_persistentProc() { public void testRunnableAt_persistentProc() {
final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,