Merge "Add ApplicationStartInfo API and objects"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a61ddcbd41
@@ -4614,6 +4614,7 @@ package android.app {
|
||||
method public java.util.List<android.app.ActivityManager.AppTask> getAppTasks();
|
||||
method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
|
||||
method @NonNull public java.util.List<android.app.ApplicationExitInfo> getHistoricalProcessExitReasons(@Nullable String, @IntRange(from=0) int, @IntRange(from=0) int);
|
||||
method @NonNull public java.util.List<android.app.ApplicationStartInfo> getHistoricalProcessStartReasons(@IntRange(from=0) int);
|
||||
method public int getLargeMemoryClass();
|
||||
method public int getLauncherLargeIconDensity();
|
||||
method public int getLauncherLargeIconSize();
|
||||
@@ -4639,7 +4640,9 @@ package android.app {
|
||||
method @RequiresPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) public void killBackgroundProcesses(String);
|
||||
method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int);
|
||||
method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int, android.os.Bundle);
|
||||
method public void removeApplicationStartInfoCompleteListener();
|
||||
method @Deprecated public void restartPackage(String);
|
||||
method public void setApplicationStartInfoCompleteListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.ActivityManager.ApplicationStartInfoCompleteListener);
|
||||
method public void setProcessStateSummary(@Nullable byte[]);
|
||||
method public static void setVrThread(int);
|
||||
method public void setWatchHeapLimit(long);
|
||||
@@ -4662,6 +4665,10 @@ package android.app {
|
||||
method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
|
||||
}
|
||||
|
||||
public static interface ActivityManager.ApplicationStartInfoCompleteListener {
|
||||
method public void onApplicationStartInfoComplete(@NonNull android.app.ApplicationStartInfo);
|
||||
}
|
||||
|
||||
public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
|
||||
ctor public ActivityManager.MemoryInfo();
|
||||
method public int describeContents();
|
||||
@@ -5221,6 +5228,52 @@ package android.app {
|
||||
field public static final int REASON_USER_STOPPED = 11; // 0xb
|
||||
}
|
||||
|
||||
public final class ApplicationStartInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getDefiningUid();
|
||||
method @Nullable public android.content.Intent getIntent();
|
||||
method public int getLaunchMode();
|
||||
method public int getPackageUid();
|
||||
method public int getPid();
|
||||
method @NonNull public String getProcessName();
|
||||
method public int getRealUid();
|
||||
method public int getReason();
|
||||
method public int getStartType();
|
||||
method public int getStartupState();
|
||||
method @NonNull public java.util.Map<java.lang.Integer,java.lang.Long> getStartupTimestamps();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.app.ApplicationStartInfo> CREATOR;
|
||||
field public static final int LAUNCH_MODE_SINGLE_INSTANCE = 2; // 0x2
|
||||
field public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4; // 0x4
|
||||
field public static final int LAUNCH_MODE_SINGLE_TASK = 3; // 0x3
|
||||
field public static final int LAUNCH_MODE_SINGLE_TOP = 1; // 0x1
|
||||
field public static final int LAUNCH_MODE_STANDARD = 0; // 0x0
|
||||
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 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
|
||||
field public static final int START_REASON_BROADCAST = 3; // 0x3
|
||||
field public static final int START_REASON_CONTENT_PROVIDER = 4; // 0x4
|
||||
field public static final int START_REASON_JOB = 5; // 0x5
|
||||
field public static final int START_REASON_LAUNCHER = 6; // 0x6
|
||||
field public static final int START_REASON_OTHER = 7; // 0x7
|
||||
field public static final int START_REASON_PUSH = 8; // 0x8
|
||||
field public static final int START_REASON_RESUMED_ACTIVITY = 9; // 0x9
|
||||
field public static final int START_REASON_SERVICE = 10; // 0xa
|
||||
field public static final int START_REASON_START_ACTIVITY = 11; // 0xb
|
||||
field public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2; // 0x2
|
||||
field public static final int START_TIMESTAMP_BIND_APPLICATION = 3; // 0x3
|
||||
field public static final int START_TIMESTAMP_FIRST_FRAME = 4; // 0x4
|
||||
field public static final int START_TIMESTAMP_FULLY_DRAWN = 5; // 0x5
|
||||
field public static final int START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE = 1; // 0x1
|
||||
field public static final int START_TIMESTAMP_LAUNCH = 0; // 0x0
|
||||
field public static final int START_TYPE_COLD = 0; // 0x0
|
||||
field public static final int START_TYPE_HOT = 2; // 0x2
|
||||
field public static final int START_TYPE_WARM = 1; // 0x1
|
||||
}
|
||||
|
||||
public final class AsyncNotedAppOp implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @Nullable public String getAttributionTag();
|
||||
|
||||
@@ -525,6 +525,7 @@ package android.app {
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
|
||||
method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void forceStopPackage(String);
|
||||
method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public static int getCurrentUser();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List<android.app.ApplicationStartInfo> getExternalHistoricalProcessStartReasons(@NonNull String, @IntRange(from=0) int);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
|
||||
method @NonNull public java.util.Collection<java.util.Locale> getSupportedLocales();
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
|
||||
|
||||
@@ -3675,6 +3675,123 @@ public class ActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of {@link ApplicationStartInfo} records containing the information about the
|
||||
* most recent app startups.
|
||||
*
|
||||
* <p class="note"> Note: System stores this historical information in a ring buffer and only
|
||||
* the most recent records will be returned. </p>
|
||||
*
|
||||
* @param maxNum The maximum number of results to be returned; a value of 0
|
||||
* means to ignore this parameter and return all matching records. If fewer
|
||||
* records exist, all existing records will be returned.
|
||||
*
|
||||
* @return a list of {@link ApplicationStartInfo} records matching the criteria, sorted in
|
||||
* the order from most recent to least recent.
|
||||
*/
|
||||
@NonNull
|
||||
public List<ApplicationStartInfo> getHistoricalProcessStartReasons(
|
||||
@IntRange(from = 0) int maxNum) {
|
||||
try {
|
||||
ParceledListSlice<ApplicationStartInfo> startInfos = getService()
|
||||
.getHistoricalProcessStartReasons(null, maxNum, mContext.getUserId());
|
||||
return startInfos == null ? Collections.emptyList() : startInfos.getList();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of {@link ApplicationStartInfo} records containing the information about the
|
||||
* most recent app startups.
|
||||
*
|
||||
* <p class="note"> Note: System stores this historical information in a ring buffer and only
|
||||
* the most recent records will be returned. </p>
|
||||
*
|
||||
* @param packageName Package name for which app startups to receive.
|
||||
* @param maxNum The maximum number of results to be returned; a value of 0
|
||||
* means to ignore this parameter and return all matching records. If fewer
|
||||
* records exist, all existing records will be returned.
|
||||
*
|
||||
* @return a list of {@link ApplicationStartInfo} records matching the criteria, sorted in
|
||||
* the order from most recent to least recent.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.DUMP)
|
||||
public List<ApplicationStartInfo> getExternalHistoricalProcessStartReasons(
|
||||
@NonNull String packageName, @IntRange(from = 0) int maxNum) {
|
||||
try {
|
||||
ParceledListSlice<ApplicationStartInfo> startInfos = getService()
|
||||
.getHistoricalProcessStartReasons(packageName, maxNum, mContext.getUserId());
|
||||
return startInfos == null ? Collections.emptyList() : startInfos.getList();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to receive {@link ApplicationStartInfo} object once recording of startup related
|
||||
* metrics is complete.
|
||||
* Use with {@link #setApplicationStartInfoCompleteListener}.
|
||||
*/
|
||||
public interface ApplicationStartInfoCompleteListener {
|
||||
/** {@link ApplicationStartInfo} is complete, no more info will be added. */
|
||||
void onApplicationStartInfoComplete(@NonNull ApplicationStartInfo applicationStartInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a callback to be notified when the {@link ApplicationStartInfo} records of this startup
|
||||
* are complete.
|
||||
*
|
||||
* <p class="note"> Note: callback will not wait for {@link Activity#reportFullyDrawn} to occur.
|
||||
* Timestamp for fully drawn may be added after callback occurs. Set callback after invoking
|
||||
* {@link Activity#reportFullyDrawn} if timestamp for fully drawn is required.</p>
|
||||
*
|
||||
* <p class="note"> Note: if start records have already been retrieved, the callback will be
|
||||
* invoked immediately on the specified executor with the previously resolved AppStartInfo.</p>
|
||||
*
|
||||
* <p class="note"> Note: callback is asynchronous and should be made from a background thread.
|
||||
* </p>
|
||||
*
|
||||
* @param executor The executor on which the listener should be called.
|
||||
* @param listener Callback to be called when collection of {@link ApplicationStartInfo} is
|
||||
* complete. Will replace existing listener if one is already attached.
|
||||
*
|
||||
* @throws IllegalArgumentException if executor or listener are null.
|
||||
*/
|
||||
public void setApplicationStartInfoCompleteListener(@NonNull final Executor executor,
|
||||
@NonNull final ApplicationStartInfoCompleteListener listener) {
|
||||
Preconditions.checkNotNull(executor, "executor cannot be null");
|
||||
Preconditions.checkNotNull(listener, "listener cannot be null");
|
||||
IApplicationStartInfoCompleteListener callback =
|
||||
new IApplicationStartInfoCompleteListener.Stub() {
|
||||
@Override
|
||||
public void onApplicationStartInfoComplete(ApplicationStartInfo applicationStartInfo) {
|
||||
executor.execute(() ->
|
||||
listener.onApplicationStartInfoComplete(applicationStartInfo));
|
||||
}
|
||||
};
|
||||
try {
|
||||
getService().setApplicationStartInfoCompleteListener(callback, mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the callback set by {@link #setApplicationStartInfoCompleteListener} if there is one.
|
||||
*/
|
||||
public void removeApplicationStartInfoCompleteListener() {
|
||||
try {
|
||||
getService().removeApplicationStartInfoCompleteListener(mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of {@link ApplicationExitInfo} records containing the reasons for the most
|
||||
* recent app deaths.
|
||||
|
||||
19
core/java/android/app/ApplicationStartInfo.aidl
Normal file
19
core/java/android/app/ApplicationStartInfo.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
|
||||
parcelable ApplicationStartInfo;
|
||||
598
core/java/android/app/ApplicationStartInfo.java
Normal file
598
core/java/android/app/ApplicationStartInfo.java
Normal file
@@ -0,0 +1,598 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Provide information related to a processes startup. */
|
||||
public final class ApplicationStartInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* State indicating process startup has started. Some information is available in
|
||||
* {@link ApplicationStartInfo} and more will be added.
|
||||
*/
|
||||
public static final int STARTUP_STATE_STARTED = 0;
|
||||
|
||||
/**
|
||||
* State indicating process startup has failed. Startup information in
|
||||
* {@link ApplicationStartInfo} is incomplete, but no more will be added.
|
||||
*/
|
||||
public static final int STARTUP_STATE_ERROR = 1;
|
||||
|
||||
/**
|
||||
* State indicating process startup has made it to first frame draw. Startup
|
||||
* information in {@link ApplicationStartInfo} is complete with potential exception
|
||||
* of fully drawn timestamp which is not guaranteed to be set.
|
||||
*/
|
||||
public static final int STARTUP_STATE_FIRST_FRAME_DRAWN = 2;
|
||||
|
||||
/** Process started due to alarm. */
|
||||
public static final int START_REASON_ALARM = 0;
|
||||
|
||||
/** Process started to run backup. */
|
||||
public static final int START_REASON_BACKUP = 1;
|
||||
|
||||
/** Process started due to boot complete. */
|
||||
public static final int START_REASON_BOOT_COMPLETE = 2;
|
||||
|
||||
/** Process started due to broadcast received. */
|
||||
public static final int START_REASON_BROADCAST = 3;
|
||||
|
||||
/** Process started due to access of ContentProvider */
|
||||
public static final int START_REASON_CONTENT_PROVIDER = 4;
|
||||
|
||||
/** * Process started to run scheduled job. */
|
||||
public static final int START_REASON_JOB = 5;
|
||||
|
||||
/** Process started due to click app icon or widget from launcher. */
|
||||
public static final int START_REASON_LAUNCHER = 6;
|
||||
|
||||
/** Process started not for any of the listed reasons. */
|
||||
public static final int START_REASON_OTHER = 7;
|
||||
|
||||
/** Process started due to push message. */
|
||||
public static final int START_REASON_PUSH = 8;
|
||||
|
||||
/** Process started to resume activity. */
|
||||
public static final int START_REASON_RESUMED_ACTIVITY = 9;
|
||||
|
||||
/** Process service started. */
|
||||
public static final int START_REASON_SERVICE = 10;
|
||||
|
||||
/** Process started due to Activity started for any reason not explicitly listed. */
|
||||
public static final int START_REASON_START_ACTIVITY = 11;
|
||||
|
||||
/** Process started from scratch. */
|
||||
public static final int START_TYPE_COLD = 0;
|
||||
|
||||
/** Process retained minimally SavedInstanceState. */
|
||||
public static final int START_TYPE_WARM = 1;
|
||||
|
||||
/** Process brought back to foreground. */
|
||||
public static final int START_TYPE_HOT = 2;
|
||||
|
||||
/**
|
||||
* Default. The system always creates a new instance of the activity in the target task and
|
||||
* routes the intent to it.
|
||||
*/
|
||||
public static final int LAUNCH_MODE_STANDARD = 0;
|
||||
|
||||
/**
|
||||
* If an instance of the activity already exists at the top of the target task, the system
|
||||
* routes the intent to that instance through a call to its onNewIntent() method, rather than
|
||||
* creating a new instance of the activity.
|
||||
*/
|
||||
public static final int LAUNCH_MODE_SINGLE_TOP = 1;
|
||||
|
||||
/**
|
||||
* The system creates the activity at the root of a new task or locates the activity on an
|
||||
* existing task with the same affinity. If an instance of the activity already exists and is at
|
||||
* the root of the task, the system routes the intent to existing instance through a call to its
|
||||
* onNewIntent() method, rather than creating a new one.
|
||||
*/
|
||||
public static final int LAUNCH_MODE_SINGLE_INSTANCE = 2;
|
||||
|
||||
/**
|
||||
* Same as "singleTask", except that the system doesn't launch any other activities into the
|
||||
* task holding the instance. The activity is always the single and only member of its task.
|
||||
*/
|
||||
public static final int LAUNCH_MODE_SINGLE_TASK = 3;
|
||||
|
||||
/**
|
||||
* The activity can only be running as the root activity of the task, the first activity that
|
||||
* created the task, and therefore there will only be one instance of this activity in a task;
|
||||
* but activity can be instantiated multiple times in different tasks.
|
||||
*/
|
||||
public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4;
|
||||
|
||||
/** Clock monotonic timestamp of launch started. */
|
||||
public static final int START_TIMESTAMP_LAUNCH = 0;
|
||||
|
||||
/** Clock monotonic timestamp of finish java classloading. */
|
||||
public static final int START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE = 1;
|
||||
|
||||
/** Clock monotonic timestamp of Application onCreate called. */
|
||||
public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2;
|
||||
|
||||
/** Clock monotonic timestamp of bindApplication called. */
|
||||
public static final int START_TIMESTAMP_BIND_APPLICATION = 3;
|
||||
|
||||
/** Clock monotonic timestamp of first frame drawn. */
|
||||
public static final int START_TIMESTAMP_FIRST_FRAME = 4;
|
||||
|
||||
/** Clock monotonic timestamp of reportFullyDrawn called by application. */
|
||||
public static final int START_TIMESTAMP_FULLY_DRAWN = 5;
|
||||
|
||||
/**
|
||||
* @see #getStartupState
|
||||
*/
|
||||
private @StartupState int mStartupState;
|
||||
|
||||
/**
|
||||
* @see #getPid
|
||||
*/
|
||||
private int mPid;
|
||||
|
||||
/**
|
||||
* @see #getRealUid
|
||||
*/
|
||||
private int mRealUid;
|
||||
|
||||
/**
|
||||
* @see #getPackageUid
|
||||
*/
|
||||
private int mPackageUid;
|
||||
|
||||
/**
|
||||
* @see #getDefiningUid
|
||||
*/
|
||||
private int mDefiningUid;
|
||||
|
||||
/**
|
||||
* @see #getProcessName
|
||||
*/
|
||||
private String mProcessName;
|
||||
|
||||
/**
|
||||
* @see #getReason
|
||||
*/
|
||||
private @StartReason int mReason;
|
||||
|
||||
/**
|
||||
* @see #getStartupTimestamps
|
||||
*/
|
||||
private Map<@StartupTimestamp Integer, Long> mStartupTimestampsNs;
|
||||
|
||||
/**
|
||||
* @see #getStartType
|
||||
*/
|
||||
private @StartType int mStartType;
|
||||
|
||||
/**
|
||||
* @see #getStartIntent
|
||||
*/
|
||||
private Intent mStartIntent;
|
||||
|
||||
/**
|
||||
* @see #getLaunchMode
|
||||
*/
|
||||
private @LaunchMode int mLaunchMode;
|
||||
|
||||
/**
|
||||
* @hide *
|
||||
*/
|
||||
@IntDef(
|
||||
prefix = {"STARTUP_STATE_"},
|
||||
value = {
|
||||
STARTUP_STATE_STARTED,
|
||||
STARTUP_STATE_ERROR,
|
||||
STARTUP_STATE_FIRST_FRAME_DRAWN,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StartupState {}
|
||||
|
||||
/**
|
||||
* @hide *
|
||||
*/
|
||||
@IntDef(
|
||||
prefix = {"START_REASON_"},
|
||||
value = {
|
||||
START_REASON_ALARM,
|
||||
START_REASON_BACKUP,
|
||||
START_REASON_BOOT_COMPLETE,
|
||||
START_REASON_BROADCAST,
|
||||
START_REASON_CONTENT_PROVIDER,
|
||||
START_REASON_JOB,
|
||||
START_REASON_LAUNCHER,
|
||||
START_REASON_OTHER,
|
||||
START_REASON_PUSH,
|
||||
START_REASON_RESUMED_ACTIVITY,
|
||||
START_REASON_SERVICE,
|
||||
START_REASON_START_ACTIVITY,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StartReason {}
|
||||
|
||||
/**
|
||||
* @hide *
|
||||
*/
|
||||
@IntDef(
|
||||
prefix = {"START_TYPE_"},
|
||||
value = {
|
||||
START_TYPE_COLD,
|
||||
START_TYPE_WARM,
|
||||
START_TYPE_HOT,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StartType {}
|
||||
|
||||
/**
|
||||
* @hide *
|
||||
*/
|
||||
@IntDef(
|
||||
prefix = {"LAUNCH_MODE_"},
|
||||
value = {
|
||||
LAUNCH_MODE_STANDARD,
|
||||
LAUNCH_MODE_SINGLE_TOP,
|
||||
LAUNCH_MODE_SINGLE_INSTANCE,
|
||||
LAUNCH_MODE_SINGLE_TASK,
|
||||
LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface LaunchMode {}
|
||||
|
||||
/**
|
||||
* @hide *
|
||||
*/
|
||||
@IntDef(
|
||||
prefix = {"START_TIMESTAMP_"},
|
||||
value = {
|
||||
START_TIMESTAMP_LAUNCH,
|
||||
START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE,
|
||||
START_TIMESTAMP_APPLICATION_ONCREATE,
|
||||
START_TIMESTAMP_BIND_APPLICATION,
|
||||
START_TIMESTAMP_FULLY_DRAWN,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
|
||||
public @interface StartupTimestamp {}
|
||||
|
||||
/**
|
||||
* @see #getStartupState
|
||||
* @hide
|
||||
*/
|
||||
public void setStartupState(final @StartupState int startupState) {
|
||||
mStartupState = startupState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getPid
|
||||
* @hide
|
||||
*/
|
||||
public void setPid(final int pid) {
|
||||
mPid = pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRealUid
|
||||
* @hide
|
||||
*/
|
||||
public void setRealUid(final int uid) {
|
||||
mRealUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getPackageUid
|
||||
* @hide
|
||||
*/
|
||||
public void setPackageUid(final int uid) {
|
||||
mPackageUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getDefiningUid
|
||||
* @hide
|
||||
*/
|
||||
public void setDefiningUid(final int uid) {
|
||||
mDefiningUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getProcessName
|
||||
* @hide
|
||||
*/
|
||||
public void setProcessName(final String processName) {
|
||||
mProcessName = intern(processName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getReason
|
||||
* @hide
|
||||
*/
|
||||
public void setReason(@StartReason int reason) {
|
||||
mReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStartupTimestamps
|
||||
* @hide
|
||||
*/
|
||||
public void addStartupTimestamp(@StartupTimestamp int key, long timestampNs) {
|
||||
if (mStartupTimestampsNs == null) {
|
||||
mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
|
||||
}
|
||||
mStartupTimestampsNs.put(key, timestampNs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStartType
|
||||
* @hide
|
||||
*/
|
||||
public void setStartType(@StartType int startType) {
|
||||
mStartType = startType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStartIntent
|
||||
* @hide
|
||||
*/
|
||||
public void setIntent(Intent startIntent) {
|
||||
mStartIntent = startIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getLaunchMode
|
||||
* @hide
|
||||
*/
|
||||
public void setLaunchMode(@LaunchMode int launchMode) {
|
||||
mLaunchMode = launchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current state of startup.
|
||||
*
|
||||
* Can be used to determine whether the object will have additional fields added as it may be
|
||||
* queried before all data is collected.
|
||||
*
|
||||
* <p class="note"> Note: field will always be set and available.</p>
|
||||
*/
|
||||
public @StartupState int getStartupState() {
|
||||
return mStartupState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The process id.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public int getPid() {
|
||||
return mPid;
|
||||
}
|
||||
|
||||
/**
|
||||
* The kernel user identifier of the process, most of the time the system uses this to do access
|
||||
* control checks. It's typically the uid of the package where the component is running from,
|
||||
* except the case of isolated process, where this field identifies the kernel user identifier
|
||||
* that this process is actually running with, while the {@link #getPackageUid} identifies the
|
||||
* kernel user identifier that is assigned at the package installation time.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public int getRealUid() {
|
||||
return mRealUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the
|
||||
* package installation time.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public int getPackageUid() {
|
||||
return mPackageUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the defining kernel user identifier, maybe different from {@link #getRealUid} and
|
||||
* {@link #getPackageUid}, if an external service has the {@link
|
||||
* android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set to <code>
|
||||
* true</code> and was bound with the flag {@link android.content.Context#BIND_EXTERNAL_SERVICE}
|
||||
* - in this case, this field here will be the kernel user identifier of the external service
|
||||
* provider.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public int getDefiningUid() {
|
||||
return mDefiningUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual process name it was running with.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public @NonNull String getProcessName() {
|
||||
return mProcessName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reason code of what triggered the process's start.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public @StartReason int getReason() {
|
||||
return mReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Various clock monotonic timestamps in nanoseconds throughout the startup process.
|
||||
*
|
||||
* <p class="note"> Note: different timestamps will be available for different values of
|
||||
* {@link #getStartupState}:
|
||||
*
|
||||
* (Subsequent rows contain all timestamps of proceding states.)
|
||||
*
|
||||
* For {@link #STARTUP_STATE_STARTED}, timestamp {@link #START_TIMESTAMP_LAUNCH} will be
|
||||
* available.
|
||||
* For {@link #STARTUP_STATE_ERROR}, no additional timestamps are guaranteed available.
|
||||
* For {@link #STARTUP_STATE_FIRST_FRAME_DRAWN}, timestamps
|
||||
* {@link #START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE}, {@link #START_TIMESTAMP_APPLICATION_ONCREATE},
|
||||
* {@link #START_TIMESTAMP_BIND_APPLICATION}, and {@link #START_TIMESTAMP_FIRST_FRAME} will
|
||||
* additionally be available.
|
||||
*
|
||||
* Timestamp {@link #START_TIMESTAMP_FULLY_DRAWN} is never guaranteed to be available as it is
|
||||
* dependant on devloper calling {@link Activity#reportFullyDrawn}.
|
||||
* </p>
|
||||
*/
|
||||
public @NonNull Map<@StartupTimestamp Integer, Long> getStartupTimestamps() {
|
||||
if (mStartupTimestampsNs == null) {
|
||||
mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
|
||||
}
|
||||
return mStartupTimestampsNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of the app at startup.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for {@link #getStartupState} value
|
||||
* {@link #STARTUP_STATE_FIRST_FRAME_DRAWN}. Not guaranteed for other states.</p>
|
||||
*/
|
||||
public @StartType int getStartType() {
|
||||
return mStartType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The intent used to launch the application.
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
@SuppressLint("IntentBuilderName")
|
||||
@Nullable
|
||||
public Intent getIntent() {
|
||||
return mStartIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction on how the activity should be launched. There are five modes that work in
|
||||
* conjunction with activity flags in Intent objects to determine what should happen when the
|
||||
* activity is called upon to handle an intent.
|
||||
*
|
||||
* Modes:
|
||||
* {@link #LAUNCH_MODE_STANDARD}
|
||||
* {@link #LAUNCH_MODE_SINGLE_TOP}
|
||||
* {@link #LAUNCH_MODE_SINGLE_INSTANCE}
|
||||
* {@link #LAUNCH_MODE_SINGLE_TASK}
|
||||
* {@link #LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK}
|
||||
*
|
||||
* <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p>
|
||||
*/
|
||||
public @LaunchMode int getLaunchMode() {
|
||||
return mLaunchMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mStartupState);
|
||||
dest.writeInt(mPid);
|
||||
dest.writeInt(mRealUid);
|
||||
dest.writeInt(mPackageUid);
|
||||
dest.writeInt(mDefiningUid);
|
||||
dest.writeString(mProcessName);
|
||||
dest.writeInt(mReason);
|
||||
dest.writeInt(mStartupTimestampsNs.size());
|
||||
for (@StartupTimestamp int key : mStartupTimestampsNs.keySet()) {
|
||||
dest.writeInt(key);
|
||||
dest.writeLong(mStartupTimestampsNs.get(key));
|
||||
}
|
||||
dest.writeInt(mStartType);
|
||||
dest.writeParcelable(mStartIntent, flags);
|
||||
dest.writeInt(mLaunchMode);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public ApplicationStartInfo() {}
|
||||
|
||||
/** @hide */
|
||||
public ApplicationStartInfo(ApplicationStartInfo other) {
|
||||
mStartupState = other.mStartupState;
|
||||
mPid = other.mPid;
|
||||
mRealUid = other.mRealUid;
|
||||
mPackageUid = other.mPackageUid;
|
||||
mDefiningUid = other.mDefiningUid;
|
||||
mProcessName = other.mProcessName;
|
||||
mReason = other.mReason;
|
||||
mStartupTimestampsNs = other.mStartupTimestampsNs;
|
||||
mStartType = other.mStartType;
|
||||
mStartIntent = other.mStartIntent;
|
||||
mLaunchMode = other.mLaunchMode;
|
||||
}
|
||||
|
||||
private ApplicationStartInfo(@NonNull Parcel in) {
|
||||
mStartupState = in.readInt();
|
||||
mPid = in.readInt();
|
||||
mRealUid = in.readInt();
|
||||
mPackageUid = in.readInt();
|
||||
mDefiningUid = in.readInt();
|
||||
mProcessName = intern(in.readString());
|
||||
mReason = in.readInt();
|
||||
int starupTimestampCount = in.readInt();
|
||||
for (int i = 0; i < starupTimestampCount; i++) {
|
||||
int key = in.readInt();
|
||||
long val = in.readLong();
|
||||
addStartupTimestamp(key, val);
|
||||
}
|
||||
mStartType = in.readInt();
|
||||
mStartIntent =
|
||||
in.readParcelable(Intent.class.getClassLoader(), android.content.Intent.class);
|
||||
mLaunchMode = in.readInt();
|
||||
}
|
||||
|
||||
private static String intern(@Nullable String source) {
|
||||
return source != null ? source.intern() : null;
|
||||
}
|
||||
|
||||
public @NonNull static final Creator<ApplicationStartInfo> CREATOR =
|
||||
new Creator<ApplicationStartInfo>() {
|
||||
@Override
|
||||
public ApplicationStartInfo createFromParcel(Parcel in) {
|
||||
return new ApplicationStartInfo(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationStartInfo[] newArray(int size) {
|
||||
return new ApplicationStartInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -19,10 +19,12 @@ package android.app;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.PendingIntentInfo;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ApplicationStartInfo;
|
||||
import android.app.ApplicationErrorReport;
|
||||
import android.app.ApplicationExitInfo;
|
||||
import android.app.ContentProviderHolder;
|
||||
import android.app.GrantedUriPermission;
|
||||
import android.app.IApplicationStartInfoCompleteListener;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.IActivityController;
|
||||
import android.app.IAppTask;
|
||||
@@ -633,6 +635,45 @@ interface IActivityManager {
|
||||
*/
|
||||
void appNotResponding(String reason);
|
||||
|
||||
/**
|
||||
* Return a list of {@link ApplicationStartInfo} records.
|
||||
*
|
||||
* <p class="note"> Note: System stores historical information in a ring buffer, older
|
||||
* records would be overwritten by newer records. </p>
|
||||
*
|
||||
* @param packageName Optional, an empty value means match all packages belonging to the
|
||||
* caller's UID. If this package belongs to another UID, you must hold
|
||||
* {@link android.Manifest.permission#DUMP} in order to retrieve it.
|
||||
* @param maxNum Optional, the maximum number of results should be returned; A value of 0
|
||||
* means to ignore this parameter and return all matching records
|
||||
* @param userId The userId in the multi-user environment.
|
||||
*
|
||||
* @return a list of {@link ApplicationStartInfo} records with the matching criteria, sorted in
|
||||
* the order from most recent to least recent.
|
||||
*/
|
||||
ParceledListSlice<ApplicationStartInfo> getHistoricalProcessStartReasons(String packageName,
|
||||
int maxNum, int userId);
|
||||
|
||||
|
||||
/**
|
||||
* Sets a callback for {@link ApplicationStartInfo} upon completion of collecting startup data.
|
||||
*
|
||||
* <p class="note"> Note: completion of startup is no guaranteed and as such this callback may not occur.</p>
|
||||
*
|
||||
* @param listener A listener to for the callback upon completion of startup data collection.
|
||||
* @param userId The userId in the multi-user environment.
|
||||
*/
|
||||
void setApplicationStartInfoCompleteListener(IApplicationStartInfoCompleteListener listener,
|
||||
int userId);
|
||||
|
||||
|
||||
/**
|
||||
* Removes callback for {@link ApplicationStartInfo} upon completion of collecting startup data.
|
||||
*
|
||||
* @param userId The userId in the multi-user environment.
|
||||
*/
|
||||
void removeApplicationStartInfoCompleteListener(int userId);
|
||||
|
||||
/**
|
||||
* Return a list of {@link ApplicationExitInfo} records.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.app.ApplicationStartInfo;
|
||||
|
||||
/**
|
||||
* Notify the client when compilation of app start info is complete.
|
||||
* Will not be called in case of an error that disrupts startup.
|
||||
* @param applicationStartInfo the completed ApplicationStartInfo object.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface IApplicationStartInfoCompleteListener {
|
||||
void onApplicationStartInfoComplete(in ApplicationStartInfo applicationStartInfo);
|
||||
}
|
||||
@@ -260,6 +260,10 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
*/
|
||||
private static final String KEY_LOW_SWAP_THRESHOLD_PERCENT = "low_swap_threshold_percent";
|
||||
|
||||
/** Default value for mFlagApplicationStartInfoEnabled. Defaults to false. */
|
||||
private static final String KEY_DEFAULT_APPLICATION_START_INFO_ENABLED =
|
||||
"enable_app_start_info";
|
||||
|
||||
/**
|
||||
* Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in
|
||||
* Settings.Global. This allows it to be set experimentally unless it has been
|
||||
@@ -550,6 +554,9 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
|
||||
volatile boolean mFlagActivityStartsLoggingEnabled;
|
||||
|
||||
// Indicates whether ApplicationStartInfo is enabled.
|
||||
volatile boolean mFlagApplicationStartInfoEnabled;
|
||||
|
||||
// Indicates whether the background activity starts is enabled.
|
||||
// Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED.
|
||||
// If not set explicitly the default is controlled by DeviceConfig.
|
||||
@@ -996,6 +1003,9 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
case KEY_MAX_CACHED_PROCESSES:
|
||||
updateMaxCachedProcesses();
|
||||
break;
|
||||
case KEY_DEFAULT_APPLICATION_START_INFO_ENABLED:
|
||||
updateApplicationStartInfoEnabled();
|
||||
break;
|
||||
case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
|
||||
updateBackgroundActivityStarts();
|
||||
break;
|
||||
@@ -1390,6 +1400,14 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1;
|
||||
}
|
||||
|
||||
private void updateApplicationStartInfoEnabled() {
|
||||
mFlagApplicationStartInfoEnabled =
|
||||
DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
KEY_DEFAULT_APPLICATION_START_INFO_ENABLED,
|
||||
/*defaultValue*/ false);
|
||||
}
|
||||
|
||||
private void updateBackgroundActivityStarts() {
|
||||
mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
@@ -1970,6 +1988,10 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
pw.println(mFgToBgFgsGraceDuration);
|
||||
pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
|
||||
pw.println(mFgsStartForegroundTimeoutMs);
|
||||
pw.print(" ");
|
||||
pw.print(KEY_DEFAULT_APPLICATION_START_INFO_ENABLED);
|
||||
pw.print("=");
|
||||
pw.println(mFlagApplicationStartInfoEnabled);
|
||||
pw.print(" "); pw.print(KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED); pw.print("=");
|
||||
pw.println(mFlagBackgroundActivityStartsEnabled);
|
||||
pw.print(" "); pw.print(KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED);
|
||||
|
||||
@@ -184,6 +184,7 @@ import android.app.AppOpsManager.AttributionFlags;
|
||||
import android.app.AppOpsManagerInternal.CheckOpsDelegate;
|
||||
import android.app.ApplicationErrorReport;
|
||||
import android.app.ApplicationExitInfo;
|
||||
import android.app.ApplicationStartInfo;
|
||||
import android.app.ApplicationThreadConstants;
|
||||
import android.app.BackgroundStartPrivileges;
|
||||
import android.app.BroadcastOptions;
|
||||
@@ -192,6 +193,7 @@ import android.app.ContentProviderHolder;
|
||||
import android.app.ForegroundServiceDelegationOptions;
|
||||
import android.app.IActivityController;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.IApplicationStartInfoCompleteListener;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.IForegroundServiceObserver;
|
||||
import android.app.IInstrumentationWatcher;
|
||||
@@ -9451,6 +9453,37 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
return retList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<ApplicationStartInfo> getHistoricalProcessStartReasons(
|
||||
String packageName, int maxNum, int userId) {
|
||||
if (!mConstants.mFlagApplicationStartInfoEnabled) {
|
||||
return new ParceledListSlice<ApplicationStartInfo>(
|
||||
new ArrayList<ApplicationStartInfo>());
|
||||
}
|
||||
enforceNotIsolatedCaller("getHistoricalProcessStartReasons");
|
||||
|
||||
final ArrayList<ApplicationStartInfo> results = new ArrayList<ApplicationStartInfo>();
|
||||
|
||||
return new ParceledListSlice<ApplicationStartInfo>(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationStartInfoCompleteListener(
|
||||
IApplicationStartInfoCompleteListener listener, int userId) {
|
||||
if (!mConstants.mFlagApplicationStartInfoEnabled) {
|
||||
return;
|
||||
}
|
||||
enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeApplicationStartInfoCompleteListener(int userId) {
|
||||
if (!mConstants.mFlagApplicationStartInfoEnabled) {
|
||||
return;
|
||||
}
|
||||
enforceNotIsolatedCaller("removeApplicationStartInfoCompleteListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<ApplicationExitInfo> getHistoricalProcessExitReasons(
|
||||
String packageName, int pid, int maxNum, int userId) {
|
||||
|
||||
Reference in New Issue
Block a user