diff options
6 files changed, 42 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java index 0728ea8e5604..5686b3d545b3 100644 --- a/services/core/java/com/android/server/am/AppStartInfoTracker.java +++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java @@ -196,6 +196,8 @@ public final class AppStartInfoTracker { start.setIntent(intent); start.setStartType(ApplicationStartInfo.START_TYPE_UNSET); start.addStartupTimestamp(ApplicationStartInfo.START_TIMESTAMP_LAUNCH, timestampNanos); + + // TODO: handle possible alarm activity start. if (intent != null && intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { start.setReason(ApplicationStartInfo.START_REASON_LAUNCHER); @@ -325,6 +327,8 @@ public final class AppStartInfoTracker { ApplicationStartInfo.START_TIMESTAMP_LAUNCH, startTimeNs); start.setStartType(cold ? ApplicationStartInfo.START_TYPE_COLD : ApplicationStartInfo.START_TYPE_WARM); + + // TODO: handle possible alarm service start. start.setReason(serviceRecord.permission != null && serviceRecord.permission.contains("android.permission.BIND_JOB_SERVICE") ? ApplicationStartInfo.START_REASON_JOB @@ -336,8 +340,9 @@ public final class AppStartInfoTracker { } } - public void handleProcessBroadcastStart(long startTimeNs, ProcessRecord app, - BroadcastRecord broadcast, boolean cold) { + /** Process a broadcast triggered app start. */ + public void handleProcessBroadcastStart(long startTimeNs, ProcessRecord app, Intent intent, + boolean isAlarm) { synchronized (mLock) { if (!mEnabled) { return; @@ -347,26 +352,19 @@ public final class AppStartInfoTracker { start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED); start.addStartupTimestamp( ApplicationStartInfo.START_TIMESTAMP_LAUNCH, startTimeNs); - start.setStartType(cold ? ApplicationStartInfo.START_TYPE_COLD - : ApplicationStartInfo.START_TYPE_WARM); - if (broadcast == null) { - start.setReason(ApplicationStartInfo.START_REASON_BROADCAST); - } else if (broadcast.alarm) { + start.setStartType(ApplicationStartInfo.START_TYPE_COLD); + if (isAlarm) { start.setReason(ApplicationStartInfo.START_REASON_ALARM); - } else if (broadcast.pushMessage || broadcast.pushMessageOverQuota) { - start.setReason(ApplicationStartInfo.START_REASON_PUSH); - } else if (Intent.ACTION_BOOT_COMPLETED.equals(broadcast.intent.getAction())) { - start.setReason(ApplicationStartInfo.START_REASON_BOOT_COMPLETE); } else { start.setReason(ApplicationStartInfo.START_REASON_BROADCAST); } - start.setIntent(broadcast != null ? broadcast.intent : null); + start.setIntent(intent); addStartInfoLocked(start); } } - public void handleProcessContentProviderStart(long startTimeNs, ProcessRecord app, - boolean cold) { + /** Process a content provider triggered app start. */ + public void handleProcessContentProviderStart(long startTimeNs, ProcessRecord app) { synchronized (mLock) { if (!mEnabled) { return; @@ -376,8 +374,7 @@ public final class AppStartInfoTracker { start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED); start.addStartupTimestamp( ApplicationStartInfo.START_TIMESTAMP_LAUNCH, startTimeNs); - start.setStartType(cold ? ApplicationStartInfo.START_TYPE_COLD - : ApplicationStartInfo.START_TYPE_WARM); + start.setStartType(ApplicationStartInfo.START_TYPE_COLD); start.setReason(ApplicationStartInfo.START_REASON_CONTENT_PROVIDER); addStartInfoLocked(start); } diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index c08288901157..48dd03922479 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -1030,6 +1030,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue { "startProcessLocked failed"); return true; } + // TODO: b/335420031 - cache receiver intent to avoid multiple calls to getReceiverIntent. + mService.mProcessList.getAppStartInfoTracker().handleProcessBroadcastStart( + SystemClock.elapsedRealtimeNanos(), queue.app, r.getReceiverIntent(receiver), + r.alarm /* isAlarm */); return false; } diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index f76bf37e4d58..28fd1977539c 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -179,6 +179,7 @@ public class ContentProviderHelper { final int expectedUserId = userId; synchronized (mService) { long startTime = SystemClock.uptimeMillis(); + long startElapsedTimeNs = SystemClock.elapsedRealtimeNanos(); ProcessRecord r = null; if (caller != null) { @@ -585,6 +586,8 @@ public class ContentProviderHelper { callingProcessState, ActivityManager.PROCESS_STATE_NONEXISTENT, firstLaunch, 0L /* TODO: stoppedDuration */); + mService.mProcessList.getAppStartInfoTracker() + .handleProcessContentProviderStart(startElapsedTimeNs, proc); } cpr.launchingApp = proc; mLaunchingProviders.add(cpr); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java index 7d3a1103a044..4618cf77a910 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java @@ -350,7 +350,7 @@ public class ApplicationStartInfoTest { app1PackageName); // packageName mAppStartInfoTracker.handleProcessBroadcastStart(appStartTimestampBroadcast, app, - null, true /* isColdStart */); + buildIntent(COMPONENT), false /* isAlarm */); list.clear(); mAppStartInfoTracker.getStartInfo(app1PackageName, app1UidUser2, app1PidUser2, 0, list); assertEquals(list.size(), 1); @@ -395,7 +395,7 @@ public class ApplicationStartInfoTest { app2PackageName); // packageName mAppStartInfoTracker.handleProcessContentProviderStart(appStartTimestampRContentProvider, - app, false); + app); list.clear(); mAppStartInfoTracker.getStartInfo(app2PackageName, app2UidUser2, app2PidUser2, 0, list); assertEquals(list.size(), 1); @@ -409,7 +409,7 @@ public class ApplicationStartInfoTest { app2ProcessName, // processName ApplicationStartInfo.START_REASON_CONTENT_PROVIDER, // reason ApplicationStartInfo.STARTUP_STATE_STARTED, // startup state - ApplicationStartInfo.START_TYPE_WARM, // state type + ApplicationStartInfo.START_TYPE_COLD, // state type ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode // Case 8: Save and load again diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java index ce281daf41c4..586191702578 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java @@ -112,6 +112,9 @@ public abstract class BaseBroadcastQueueTest { @Mock ProcessList mProcessList; + @Mock + AppStartInfoTracker mAppStartInfoTracker; + Context mContext; ActivityManagerService mAms; BroadcastConstants mConstants; @@ -172,6 +175,8 @@ public abstract class BaseBroadcastQueueTest { mSkipPolicy = spy(new BroadcastSkipPolicy(mAms)); doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any()); doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any()); + + doReturn(mAppStartInfoTracker).when(mProcessList).getAppStartInfoTracker(); } public void tearDown() throws Exception { 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 97ae0bd6c7f7..13ba1e5e705c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -2393,6 +2393,20 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { assertNull(mAms.getProcessRecordLocked(PACKAGE_BLUE, getUidForPackage(PACKAGE_BLUE))); } + @Test + public void testBroadcastAppStartInfoReported() throws Exception { + final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); + + final Intent timezone = new Intent(Intent.ACTION_TIME_TICK); + enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, + List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); + + waitForIdle(); + + verify(mAppStartInfoTracker, times(1)).handleProcessBroadcastStart(anyLong(), any(), any(), + anyBoolean()); + } + private long getReceiverScheduledTime(@NonNull BroadcastRecord r, @NonNull Object receiver) { for (int i = 0; i < r.receivers.size(); ++i) { if (isReceiverEquals(receiver, r.receivers.get(i))) { |