summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yisroel Forta <yforta@google.com> 2024-08-13 18:09:44 +0000
committer Yisroel Forta <yforta@google.com> 2024-09-24 13:56:00 +0000
commit2cbea9606c89b139196812441698d55da8e615fa (patch)
treeffae75a047263d386a66968e3e3c244b5666629c
parentc5d91e7a1242780c4a954e31b88c0a7f57a6f605 (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
-rw-r--r--core/api/current.txt6
-rw-r--r--core/java/android/app/ApplicationStartInfo.java114
-rw-r--r--core/java/android/app/activity_manager.aconfig7
-rw-r--r--core/proto/android/app/appstartinfo.proto1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/am/AppStartInfoTracker.java53
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java49
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 {