diff options
| author | 2024-08-13 18:09:44 +0000 | |
|---|---|---|
| committer | 2024-09-24 13:56:00 +0000 | |
| commit | 2cbea9606c89b139196812441698d55da8e615fa (patch) | |
| tree | ffae75a047263d386a66968e3e3c244b5666629c | |
| parent | c5d91e7a1242780c4a954e31b88c0a7f57a6f605 (diff) | |
Add start component type to start info
Start component provides a concise and correct way to determine which component
type (activity/service/broadcast/content provider) this start was for. Component
type is one of the key ways that start info can be use for optimizing startup
path. This cannot be correctly inferred from reasons alone as some reasons, like
alarm, can occur for multiple component types.
Test: run startinfo unit tests, dump records and spot check
Bug: 350063699
Flag: android.app.app_start_info_component
Change-Id: I5c8da22161b46f48442c466fe153ef6349aeb2f1
7 files changed, 206 insertions, 31 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index f817241d80da..2c6e1cb44c7f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -5333,6 +5333,7 @@ package android.app { method @NonNull public String getProcessName(); method public int getRealUid(); method public int getReason(); + method @FlaggedApi("android.app.app_start_info_component") public int getStartComponent(); method public int getStartType(); method public int getStartupState(); method @NonNull public java.util.Map<java.lang.Integer,java.lang.Long> getStartupTimestamps(); @@ -5347,6 +5348,11 @@ package android.app { field public static final int STARTUP_STATE_ERROR = 1; // 0x1 field public static final int STARTUP_STATE_FIRST_FRAME_DRAWN = 2; // 0x2 field public static final int STARTUP_STATE_STARTED = 0; // 0x0 + field @FlaggedApi("android.app.app_start_info_component") public static final int START_COMPONENT_ACTIVITY = 1; // 0x1 + field @FlaggedApi("android.app.app_start_info_component") public static final int START_COMPONENT_BROADCAST = 2; // 0x2 + field @FlaggedApi("android.app.app_start_info_component") public static final int START_COMPONENT_CONTENT_PROVIDER = 3; // 0x3 + field @FlaggedApi("android.app.app_start_info_component") public static final int START_COMPONENT_OTHER = 5; // 0x5 + field @FlaggedApi("android.app.app_start_info_component") public static final int START_COMPONENT_SERVICE = 4; // 0x4 field public static final int START_REASON_ALARM = 0; // 0x0 field public static final int START_REASON_BACKUP = 1; // 0x1 field public static final int START_REASON_BOOT_COMPLETE = 2; // 0x2 diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java index 4fb06014d0d1..fad289c1beb8 100644 --- a/core/java/android/app/ApplicationStartInfo.java +++ b/core/java/android/app/ApplicationStartInfo.java @@ -102,10 +102,10 @@ public final class ApplicationStartInfo implements Parcelable { /** Process started due to boot complete. */ public static final int START_REASON_BOOT_COMPLETE = 2; - /** Process started due to broadcast received. */ + /** Process started due to broadcast received for any reason not explicitly listed. */ public static final int START_REASON_BROADCAST = 3; - /** Process started due to access of ContentProvider */ + /** Process started due to access of ContentProvider for any reason not explicitly listed. */ public static final int START_REASON_CONTENT_PROVIDER = 4; /** * Process started to run scheduled job. */ @@ -123,7 +123,7 @@ public final class ApplicationStartInfo implements Parcelable { /** Process started due to push message. */ public static final int START_REASON_PUSH = 9; - /** Process service started. */ + /** Process started due to Service started for any reason not explicitly listed.. */ public static final int START_REASON_SERVICE = 10; /** Process started due to Activity started for any reason not explicitly listed. */ @@ -209,6 +209,26 @@ public final class ApplicationStartInfo implements Parcelable { /** Clock monotonic timestamp of surfaceflinger composition complete. */ public static final int START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE = 7; + /** Process was started for an activity component. */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public static final int START_COMPONENT_ACTIVITY = 1; + + /** Process was started for a broadcast component. */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public static final int START_COMPONENT_BROADCAST = 2; + + /** Process was started for a content provider component. */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public static final int START_COMPONENT_CONTENT_PROVIDER = 3; + + /** Process was started for a service component. */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public static final int START_COMPONENT_SERVICE = 4; + + /** Process was started not for one of the four standard components. */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public static final int START_COMPONENT_OTHER = 5; + /** * @see #getMonoticCreationTimeMs */ @@ -280,6 +300,11 @@ public final class ApplicationStartInfo implements Parcelable { private boolean mWasForceStopped; /** + * @see #getStartComponent() + */ + private @StartComponent int mStartComponent; + + /** * @hide * */ @IntDef( @@ -344,6 +369,21 @@ public final class ApplicationStartInfo implements Parcelable { public @interface LaunchMode {} /** + * @hide * + */ + @IntDef( + prefix = {"START_COMPONENT_"}, + value = { + START_COMPONENT_ACTIVITY, + START_COMPONENT_BROADCAST, + START_COMPONENT_CONTENT_PROVIDER, + START_COMPONENT_SERVICE, + START_COMPONENT_OTHER, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface StartComponent {} + + /** * @see #getStartupState * @hide */ @@ -480,6 +520,14 @@ public final class ApplicationStartInfo implements Parcelable { } /** + * @see #getStartComponent() + * @hide + */ + public void setStartComponent(@StartComponent int startComponent) { + mStartComponent = startComponent; + } + + /** * Current state of startup. * * Can be used to determine whether the object will have additional fields added as it may be @@ -567,6 +615,11 @@ public final class ApplicationStartInfo implements Parcelable { /** * The reason code of what triggered the process's start. * + * Start reason provides granular reasoning on why the app is being started. Start reason should + * not be used for distinguishing between the component the app is being started for as some + * reasons may overlap with multiple components, see {@link #getStartComponent} for this + * functionality instead. + * * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> */ public @StartReason int getReason() { @@ -654,6 +707,22 @@ public final class ApplicationStartInfo implements Parcelable { return mWasForceStopped; } + /** + * The component type that was being started which triggered the start. + * + * Start component should be used to accurately distinguish between the 4 component types: + * activity, service, broadcast, and content provider. This can be useful for optimizing + * startup flow by enabling the caller to only load the necessary dependencies for a specific + * component type. For more granular information on why the app is being started, see + * {@link #getReason}. + * + * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> + */ + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + public @StartComponent int getStartComponent() { + return mStartComponent; + } + @Override public int describeContents() { return 0; @@ -681,6 +750,7 @@ public final class ApplicationStartInfo implements Parcelable { dest.writeInt(mLaunchMode); dest.writeBoolean(mWasForceStopped); dest.writeLong(mMonoticCreationTimeMs); + dest.writeInt(mStartComponent); } /** @hide */ @@ -704,6 +774,7 @@ public final class ApplicationStartInfo implements Parcelable { mLaunchMode = other.mLaunchMode; mWasForceStopped = other.mWasForceStopped; mMonoticCreationTimeMs = other.mMonoticCreationTimeMs; + mStartComponent = other.mStartComponent; } private ApplicationStartInfo(@NonNull Parcel in) { @@ -727,6 +798,7 @@ public final class ApplicationStartInfo implements Parcelable { mLaunchMode = in.readInt(); mWasForceStopped = in.readBoolean(); mMonoticCreationTimeMs = in.readLong(); + mStartComponent = in.readInt(); } private static String intern(@Nullable String source) { @@ -806,6 +878,7 @@ public final class ApplicationStartInfo implements Parcelable { proto.write(ApplicationStartInfoProto.LAUNCH_MODE, mLaunchMode); proto.write(ApplicationStartInfoProto.WAS_FORCE_STOPPED, mWasForceStopped); proto.write(ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS, mMonoticCreationTimeMs); + proto.write(ApplicationStartInfoProto.START_COMPONENT, mStartComponent); proto.end(token); } @@ -893,6 +966,9 @@ public final class ApplicationStartInfo implements Parcelable { mMonoticCreationTimeMs = proto.readLong( ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS); break; + case (int) ApplicationStartInfoProto.START_COMPONENT: + mStartComponent = proto.readInt(ApplicationStartInfoProto.START_COMPONENT); + break; } } proto.end(token); @@ -919,8 +995,11 @@ public final class ApplicationStartInfo implements Parcelable { .append(" reason=").append(reasonToString(mReason)) .append(" startType=").append(startTypeToString(mStartType)) .append(" launchMode=").append(mLaunchMode) - .append(" wasForceStopped=").append(mWasForceStopped) - .append('\n'); + .append(" wasForceStopped=").append(mWasForceStopped); + if (Flags.appStartInfoComponent()) { + sb.append(" startComponent=").append(startComponentToString(mStartComponent)); + } + sb.append('\n'); if (mStartIntent != null) { sb.append(" intent=").append(mStartIntent.toString()) .append('\n'); @@ -964,6 +1043,18 @@ public final class ApplicationStartInfo implements Parcelable { }; } + @FlaggedApi(Flags.FLAG_APP_START_INFO_COMPONENT) + private static String startComponentToString(@StartComponent int startComponent) { + return switch (startComponent) { + case START_COMPONENT_ACTIVITY -> "ACTIVITY"; + case START_COMPONENT_BROADCAST -> "SERVICE"; + case START_COMPONENT_CONTENT_PROVIDER -> "CONTENT PROVIDER"; + case START_COMPONENT_SERVICE -> "SERVICE"; + case START_COMPONENT_OTHER -> "OTHER"; + default -> ""; + }; + } + /** @hide */ @Override public boolean equals(@Nullable Object other) { @@ -972,18 +1063,19 @@ public final class ApplicationStartInfo implements Parcelable { } final ApplicationStartInfo o = (ApplicationStartInfo) other; return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid - && mDefiningUid == o.mDefiningUid && mReason == o.mReason - && mStartupState == o.mStartupState && mStartType == o.mStartType - && mLaunchMode == o.mLaunchMode && TextUtils.equals(mProcessName, o.mProcessName) - && timestampsEquals(o) && mWasForceStopped == o.mWasForceStopped - && mMonoticCreationTimeMs == o.mMonoticCreationTimeMs; + && mDefiningUid == o.mDefiningUid && mReason == o.mReason + && mStartupState == o.mStartupState && mStartType == o.mStartType + && mLaunchMode == o.mLaunchMode && TextUtils.equals(mProcessName, o.mProcessName) + && timestampsEquals(o) && mWasForceStopped == o.mWasForceStopped + && mMonoticCreationTimeMs == o.mMonoticCreationTimeMs + && mStartComponent == o.mStartComponent; } @Override public int hashCode() { return Objects.hash(mPid, mRealUid, mPackageUid, mDefiningUid, mReason, mStartupState, mStartType, mLaunchMode, mProcessName, mStartupTimestampsNs, - mMonoticCreationTimeMs); + mMonoticCreationTimeMs, mStartComponent); } private boolean timestampsEquals(@NonNull ApplicationStartInfo other) { diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig index 56488e7cd296..1f31ab5d1849 100644 --- a/core/java/android/app/activity_manager.aconfig +++ b/core/java/android/app/activity_manager.aconfig @@ -158,3 +158,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + namespace: "system_performance" + name: "app_start_info_component" + description: "Control ApplicationStartInfo component field and API" + bug: "362537357" +} diff --git a/core/proto/android/app/appstartinfo.proto b/core/proto/android/app/appstartinfo.proto index 78cf6f464558..8e9f4478e894 100644 --- a/core/proto/android/app/appstartinfo.proto +++ b/core/proto/android/app/appstartinfo.proto @@ -41,4 +41,5 @@ message ApplicationStartInfoProto { optional AppStartLaunchMode launch_mode = 11; optional bool was_force_stopped = 12; optional int64 monotonic_creation_time_ms = 13; + optional int32 start_component = 14; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 414a4e66591b..396b83982945 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1038,13 +1038,14 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void onIntentStarted(@NonNull Intent intent, long timestampNanos) { synchronized (this) { - mProcessList.getAppStartInfoTracker().onIntentStarted(intent, timestampNanos); + mProcessList.getAppStartInfoTracker() + .onActivityIntentStarted(intent, timestampNanos); } } @Override public void onIntentFailed(long id) { - mProcessList.getAppStartInfoTracker().onIntentFailed(id); + mProcessList.getAppStartInfoTracker().onActivityIntentFailed(id); } @Override @@ -1078,7 +1079,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void onReportFullyDrawn(long id, long timestampNanos) { - mProcessList.getAppStartInfoTracker().onReportFullyDrawn(id, timestampNanos); + mProcessList.getAppStartInfoTracker().onActivityReportFullyDrawn(id, timestampNanos); } }; diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java index 6aadcdc74870..71b64567d062 100644 --- a/services/core/java/com/android/server/am/AppStartInfoTracker.java +++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java @@ -280,7 +280,11 @@ public final class AppStartInfoTracker { mTemporaryInProgressIndexes.clear(); } - void onIntentStarted(@NonNull Intent intent, long timestampNanos) { + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ + void onActivityIntentStarted(@NonNull Intent intent, long timestampNanos) { synchronized (mLock) { if (!mEnabled) { return; @@ -291,6 +295,10 @@ public final class AppStartInfoTracker { start.setStartType(ApplicationStartInfo.START_TYPE_UNSET); start.addStartupTimestamp(ApplicationStartInfo.START_TIMESTAMP_LAUNCH, timestampNanos); + if (android.app.Flags.appStartInfoComponent()) { + start.setStartComponent(ApplicationStartInfo.START_COMPONENT_ACTIVITY); + } + // TODO: handle possible alarm activity start. if (intent != null && intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { @@ -303,7 +311,11 @@ public final class AppStartInfoTracker { } } - void onIntentFailed(long id) { + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ + void onActivityIntentFailed(long id) { synchronized (mLock) { if (!mEnabled) { return; @@ -322,6 +334,10 @@ public final class AppStartInfoTracker { } } + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ void onActivityLaunched(long id, ComponentName name, long temperature, ProcessRecord app) { synchronized (mLock) { if (!mEnabled) { @@ -349,6 +365,10 @@ public final class AppStartInfoTracker { } } + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ void onActivityLaunchCancelled(long id) { synchronized (mLock) { if (!mEnabled) { @@ -368,6 +388,10 @@ public final class AppStartInfoTracker { } } + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ void onActivityLaunchFinished(long id, ComponentName name, long timestampNanos, int launchMode) { synchronized (mLock) { @@ -391,7 +415,11 @@ public final class AppStartInfoTracker { } } - void onReportFullyDrawn(long id, long timestampNanos) { + /** + * Should only be called for Activity launch sequences from an instance of + * {@link ActivityMetricsLaunchObserver}. + */ + void onActivityReportFullyDrawn(long id, long timestampNanos) { synchronized (mLock) { if (!mEnabled) { return; @@ -424,6 +452,10 @@ public final class AppStartInfoTracker { ApplicationStartInfo.START_TIMESTAMP_LAUNCH, startTimeNs); start.setStartType(ApplicationStartInfo.START_TYPE_COLD); + if (android.app.Flags.appStartInfoComponent()) { + start.setStartComponent(ApplicationStartInfo.START_COMPONENT_SERVICE); + } + // TODO: handle possible alarm service start. start.setReason(serviceRecord.permission != null && serviceRecord.permission.contains("android.permission.BIND_JOB_SERVICE") @@ -455,6 +487,11 @@ public final class AppStartInfoTracker { start.setReason(ApplicationStartInfo.START_REASON_BROADCAST); } start.setIntent(intent); + + if (android.app.Flags.appStartInfoComponent()) { + start.setStartComponent(ApplicationStartInfo.START_COMPONENT_BROADCAST); + } + addStartInfoLocked(start); } } @@ -472,6 +509,11 @@ public final class AppStartInfoTracker { ApplicationStartInfo.START_TIMESTAMP_LAUNCH, startTimeNs); start.setStartType(ApplicationStartInfo.START_TYPE_COLD); start.setReason(ApplicationStartInfo.START_REASON_CONTENT_PROVIDER); + + if (android.app.Flags.appStartInfoComponent()) { + start.setStartComponent(ApplicationStartInfo.START_COMPONENT_CONTENT_PROVIDER); + } + addStartInfoLocked(start); } } @@ -490,6 +532,11 @@ public final class AppStartInfoTracker { start.setStartType(cold ? ApplicationStartInfo.START_TYPE_COLD : ApplicationStartInfo.START_TYPE_WARM); start.setReason(ApplicationStartInfo.START_REASON_BACKUP); + + if (android.app.Flags.appStartInfoComponent()) { + start.setStartComponent(ApplicationStartInfo.START_COMPONENT_OTHER); + } + addStartInfoLocked(start); } } 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 1cad255b85d7..e863f1574932 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java @@ -40,7 +40,9 @@ import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; import android.text.TextUtils; import com.android.internal.os.Clock; @@ -87,6 +89,7 @@ public class ApplicationStartInfoTest { private static final String APP_1_PACKAGE_NAME = "com.android.test.stub1"; @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private AppOpsService mAppOpsService; @Mock private PackageManagerInternal mPackageManagerInt; @@ -144,6 +147,7 @@ public class ApplicationStartInfoTest { } @Test + @EnableFlags(android.app.Flags.FLAG_APP_START_INFO_COMPONENT) public void testApplicationStartInfo() throws Exception { // Make sure we can write to the file. assertTrue(FileUtils.createDir(mAppStartInfoTracker.mProcStartStoreDir)); @@ -167,7 +171,7 @@ public class ApplicationStartInfoTest { ArrayList<ApplicationStartInfo> list = new ArrayList<ApplicationStartInfo>(); // Case 1: Activity start intent failed - mAppStartInfoTracker.onIntentStarted(buildIntent(COMPONENT), + mAppStartInfoTracker.onActivityIntentStarted(buildIntent(COMPONENT), appStartTimestampIntentStarted); mAppStartInfoTracker.getStartInfo(APP_1_PACKAGE_NAME, APP_1_UID, APP_1_PID_1, 0, list); verifyInProgressRecordsSize(1); @@ -185,7 +189,7 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_TYPE_UNSET, // state type ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode - mAppStartInfoTracker.onIntentFailed(appStartTimestampIntentStarted); + mAppStartInfoTracker.onActivityIntentFailed(appStartTimestampIntentStarted); list.clear(); mAppStartInfoTracker.getStartInfo(APP_1_PACKAGE_NAME, APP_1_UID, APP_1_PID_1, 0, list); verifyInProgressRecordsSize(0); @@ -194,7 +198,7 @@ public class ApplicationStartInfoTest { mAppStartInfoTracker.clearProcessStartInfo(true); // Case 2: Activity start launch cancelled - mAppStartInfoTracker.onIntentStarted(buildIntent(COMPONENT), + mAppStartInfoTracker.onActivityIntentStarted(buildIntent(COMPONENT), appStartTimestampIntentStarted); list.clear(); mAppStartInfoTracker.getStartInfo(APP_1_PACKAGE_NAME, APP_1_UID, APP_1_PID_1, 0, list); @@ -236,12 +240,13 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_START_ACTIVITY, // reason ApplicationStartInfo.STARTUP_STATE_ERROR, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_ACTIVITY); // start component mAppStartInfoTracker.clearProcessStartInfo(true); // Case 3: Activity start success - mAppStartInfoTracker.onIntentStarted(buildIntent(COMPONENT), + mAppStartInfoTracker.onActivityIntentStarted(buildIntent(COMPONENT), appStartTimestampIntentStarted); list.clear(); mAppStartInfoTracker.getStartInfo(APP_1_PACKAGE_NAME, APP_1_UID, APP_1_PID_1, 0, list); @@ -255,6 +260,7 @@ public class ApplicationStartInfoTest { verifyInProgressRecordsSize(1); assertEquals(list.size(), 1); + // The records will now be in both backing data structures, so verify in each. verifyInProgressApplicationStartInfo( 0, // index APP_1_PID_1, // pid @@ -277,7 +283,8 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_START_ACTIVITY, // reason ApplicationStartInfo.STARTUP_STATE_STARTED, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_ACTIVITY); // start component mAppStartInfoTracker.onActivityLaunchFinished(appStartTimestampIntentStarted, COMPONENT, appStartTimestampActivityLaunchFinished, ApplicationStartInfo.LAUNCH_MODE_STANDARD); @@ -300,7 +307,7 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_TYPE_COLD, // state type ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode - mAppStartInfoTracker.onReportFullyDrawn(appStartTimestampIntentStarted, + mAppStartInfoTracker.onActivityReportFullyDrawn(appStartTimestampIntentStarted, appStartTimestampReportFullyDrawn); list.clear(); mAppStartInfoTracker.getStartInfo(APP_1_PACKAGE_NAME, APP_1_UID, APP_1_PID_1, 0, list); @@ -317,7 +324,8 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_START_ACTIVITY, // reason ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_ACTIVITY); // start component // Don't clear records for use in subsequent cases. @@ -347,7 +355,8 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_SERVICE, // reason ApplicationStartInfo.STARTUP_STATE_STARTED, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_SERVICE); // start component // Case 5: Create an instance of app1 with a different user started for a broadcast sleep(1); @@ -376,7 +385,8 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_BROADCAST, // reason ApplicationStartInfo.STARTUP_STATE_STARTED, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_BROADCAST); // start component // Case 6: User 2 gets removed mAppStartInfoTracker.onPackageRemoved(APP_1_PACKAGE_NAME, APP_1_UID_USER_2, false); @@ -422,7 +432,9 @@ public class ApplicationStartInfoTest { ApplicationStartInfo.START_REASON_CONTENT_PROVIDER, // reason ApplicationStartInfo.STARTUP_STATE_STARTED, // startup state ApplicationStartInfo.START_TYPE_COLD, // state type - ApplicationStartInfo.LAUNCH_MODE_STANDARD); // launch mode + ApplicationStartInfo.LAUNCH_MODE_STANDARD, // launch mode + ApplicationStartInfo.START_COMPONENT_CONTENT_PROVIDER // start component + ); // Case 8: Save and load again ArrayList<ApplicationStartInfo> original = new ArrayList<ApplicationStartInfo>(); @@ -453,6 +465,7 @@ public class ApplicationStartInfoTest { */ @SuppressWarnings("GuardedBy") @Test + @EnableFlags(android.app.Flags.FLAG_APP_START_INFO_COMPONENT) public void testInProgressRecordsLimit() throws Exception { ProcessRecord app = makeProcessRecord( APP_1_PID_1, // pid @@ -466,7 +479,7 @@ public class ApplicationStartInfoTest { // never exceeds the expected size of MAX_IN_PROGRESS_RECORDS. for (int i = 0; i < AppStartInfoTracker.MAX_IN_PROGRESS_RECORDS * 2; i++) { Long startTime = Long.valueOf(i); - mAppStartInfoTracker.onIntentStarted(buildIntent(COMPONENT), startTime); + mAppStartInfoTracker.onActivityIntentStarted(buildIntent(COMPONENT), startTime); verifyInProgressRecordsSize( Math.min(i + 1, AppStartInfoTracker.MAX_IN_PROGRESS_RECORDS)); @@ -618,6 +631,10 @@ public class ApplicationStartInfoTest { } } + /** + * Convenience helper to access the record from the in progress data structure. Only applies for + * activity starts. + */ private void verifyInProgressApplicationStartInfo(int index, Integer pid, Integer uid, Integer packageUid, Integer definingUid, String processName, @@ -625,14 +642,15 @@ public class ApplicationStartInfoTest { synchronized (mAppStartInfoTracker.mLock) { verifyApplicationStartInfo(mAppStartInfoTracker.mInProgressRecords.valueAt(index), pid, uid, packageUid, definingUid, processName, reason, startupState, - startType, launchMode); + startType, launchMode, ApplicationStartInfo.START_COMPONENT_ACTIVITY); } } private void verifyApplicationStartInfo(ApplicationStartInfo info, Integer pid, Integer uid, Integer packageUid, Integer definingUid, String processName, - Integer reason, Integer startupState, Integer startType, Integer launchMode) { + Integer reason, Integer startupState, Integer startType, Integer launchMode, + Integer startComponent) { assertNotNull(info); if (pid != null) { @@ -662,6 +680,9 @@ public class ApplicationStartInfoTest { if (launchMode != null) { assertEquals(launchMode.intValue(), info.getLaunchMode()); } + if (startComponent != null) { + assertEquals(startComponent.intValue(), info.getStartComponent()); + } } private class TestInjector extends Injector { |