Loading core/api/current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -4625,9 +4625,9 @@ package android.app { public class ActivityManager { method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap); method @FlaggedApi("android.app.app_start_info") public void addApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method @FlaggedApi("android.app.app_start_info") public void addStartInfoTimestamp(@IntRange(from=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START, to=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int, long); method public void appNotResponding(@NonNull String); method @FlaggedApi("android.app.app_start_info") public void clearApplicationStartInfoCompletionListener(); method public boolean clearApplicationUserData(); method public void clearWatchHeapLimit(); method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String); Loading Loading @@ -4661,8 +4661,8 @@ 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 @FlaggedApi("android.app.app_start_info") public void removeApplicationStartInfoCompletionListener(@NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method @Deprecated public void restartPackage(String); method @FlaggedApi("android.app.app_start_info") public void setApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method public void setProcessStateSummary(@Nullable byte[]); method public static void setVrThread(int); method public void setWatchHeapLimit(long); core/java/android/app/ActivityManager.java +80 −18 Original line number Diff line number Diff line Loading @@ -4052,10 +4052,28 @@ public class ActivityManager { } } private final ArrayList<AppStartInfoCallbackWrapper> mAppStartInfoCallbacks = new ArrayList<>(); @Nullable private IApplicationStartInfoCompleteListener mAppStartInfoCompleteListener = null; private static final class AppStartInfoCallbackWrapper { @NonNull final Executor mExecutor; @NonNull final Consumer<ApplicationStartInfo> mListener; AppStartInfoCallbackWrapper(@NonNull final Executor executor, @NonNull final Consumer<ApplicationStartInfo> listener) { mExecutor = executor; mListener = listener; } } /** * Sets a callback to be notified when the {@link ApplicationStartInfo} records of this startup * Adds a callback to be notified when the {@link ApplicationStartInfo} records of this startup * are complete. * * <p class="note"> Note: callback will be removed automatically after being triggered.</p> * * <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> Loading @@ -4073,34 +4091,78 @@ public class ActivityManager { * @throws IllegalArgumentException if executor or listener are null. */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public void setApplicationStartInfoCompletionListener(@NonNull final Executor executor, public void addApplicationStartInfoCompletionListener(@NonNull final Executor executor, @NonNull final Consumer<ApplicationStartInfo> listener) { Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(listener, "listener cannot be null"); IApplicationStartInfoCompleteListener callback = new IApplicationStartInfoCompleteListener.Stub() { synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { if (listener.equals(mAppStartInfoCallbacks.get(i).mListener)) { return; } } if (mAppStartInfoCompleteListener == null) { mAppStartInfoCompleteListener = new IApplicationStartInfoCompleteListener.Stub() { @Override public void onApplicationStartInfoComplete(ApplicationStartInfo applicationStartInfo) { executor.execute(() -> listener.accept(applicationStartInfo)); public void onApplicationStartInfoComplete( ApplicationStartInfo applicationStartInfo) { synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { final AppStartInfoCallbackWrapper callback = mAppStartInfoCallbacks.get(i); callback.mExecutor.execute(() -> callback.mListener.accept( applicationStartInfo)); } mAppStartInfoCallbacks.clear(); mAppStartInfoCompleteListener = null; } } }; boolean succeeded = false; try { getService().setApplicationStartInfoCompleteListener(callback, mContext.getUserId()); getService().addApplicationStartInfoCompleteListener( mAppStartInfoCompleteListener, mContext.getUserId()); succeeded = true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } if (succeeded) { mAppStartInfoCallbacks.add(new AppStartInfoCallbackWrapper(executor, listener)); } else { mAppStartInfoCompleteListener = null; mAppStartInfoCallbacks.clear(); } } else { mAppStartInfoCallbacks.add(new AppStartInfoCallbackWrapper(executor, listener)); } } } /** * Removes the callback set by {@link #setApplicationStartInfoCompletionListener} if there is one. * Removes the provided callback set by {@link #addApplicationStartInfoCompletionListener}. */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public void clearApplicationStartInfoCompletionListener() { public void removeApplicationStartInfoCompletionListener( @NonNull final Consumer<ApplicationStartInfo> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { final AppStartInfoCallbackWrapper callback = mAppStartInfoCallbacks.get(i); if (listener.equals(callback.mListener)) { mAppStartInfoCallbacks.remove(i); break; } } if (mAppStartInfoCompleteListener != null && mAppStartInfoCallbacks.isEmpty()) { try { getService().clearApplicationStartInfoCompleteListener(mContext.getUserId()); getService().removeApplicationStartInfoCompleteListener( mAppStartInfoCompleteListener, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mAppStartInfoCompleteListener = null; } } } /** Loading core/java/android/app/ApplicationStartInfo.java +18 −16 Original line number Diff line number Diff line Loading @@ -39,12 +39,17 @@ import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * Provide information related to a processes startup. * Describes information related to an application process's startup. * * <p> * Many aspects concerning why and how an applications process was started are valuable for apps * both for logging and for potential behavior changes. Reason for process start, start type, * start times, throttling, and other useful diagnostic data can be obtained from * {@link ApplicationStartInfo} records. * </p> */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public final class ApplicationStartInfo implements Parcelable { Loading Loading @@ -552,13 +557,12 @@ public final class ApplicationStartInfo implements Parcelable { dest.writeInt(mDefiningUid); dest.writeString(mProcessName); dest.writeInt(mReason); dest.writeInt(mStartupTimestampsNs.size()); Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet(); Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator(); while (iter.hasNext()) { Map.Entry<Integer, Long> entry = iter.next(); dest.writeInt(entry.getKey()); dest.writeLong(entry.getValue()); dest.writeInt(mStartupTimestampsNs == null ? 0 : mStartupTimestampsNs.size()); if (mStartupTimestampsNs != null) { for (int i = 0; i < mStartupTimestampsNs.size(); i++) { dest.writeInt(mStartupTimestampsNs.keyAt(i)); dest.writeLong(mStartupTimestampsNs.valueAt(i)); } } dest.writeInt(mStartType); dest.writeParcelable(mStartIntent, flags); Loading Loading @@ -740,13 +744,11 @@ public final class ApplicationStartInfo implements Parcelable { sb.append(" intent=").append(mStartIntent.toString()) .append('\n'); } if (mStartupTimestampsNs.size() > 0) { if (mStartupTimestampsNs != null && mStartupTimestampsNs.size() > 0) { sb.append(" timestamps: "); Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet(); Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator(); while (iter.hasNext()) { Map.Entry<Integer, Long> entry = iter.next(); sb.append(entry.getKey()).append("=").append(entry.getValue()).append(" "); for (int i = 0; i < mStartupTimestampsNs.size(); i++) { sb.append(mStartupTimestampsNs.keyAt(i)).append("=").append(mStartupTimestampsNs .valueAt(i)).append(" "); } sb.append('\n'); } Loading core/java/android/app/IActivityManager.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -715,7 +715,7 @@ interface IActivityManager { * @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, void addApplicationStartInfoCompleteListener(IApplicationStartInfoCompleteListener listener, int userId); Loading @@ -724,7 +724,8 @@ interface IActivityManager { * * @param userId The userId in the multi-user environment. */ void clearApplicationStartInfoCompleteListener(int userId); void removeApplicationStartInfoCompleteListener(IApplicationStartInfoCompleteListener listener, int userId); /** Loading services/core/java/com/android/server/am/ActivityManagerService.java +5 −3 Original line number Diff line number Diff line Loading @@ -9858,7 +9858,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setApplicationStartInfoCompleteListener( public void addApplicationStartInfoCompleteListener( IApplicationStartInfoCompleteListener listener, int userId) { enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener"); Loading @@ -9873,7 +9873,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void clearApplicationStartInfoCompleteListener(int userId) { public void removeApplicationStartInfoCompleteListener( IApplicationStartInfoCompleteListener listener, int userId) { enforceNotIsolatedCaller("clearApplicationStartInfoCompleteListener"); // For the simplification, we don't support USER_ALL nor USER_CURRENT here. Loading @@ -9882,7 +9883,8 @@ public class ActivityManagerService extends IActivityManager.Stub } final int callingUid = Binder.getCallingUid(); mProcessList.getAppStartInfoTracker().clearStartInfoCompleteListener(callingUid, true); mProcessList.getAppStartInfoTracker().removeStartInfoCompleteListener(listener, callingUid, true); } @Override Loading Loading
core/api/current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -4625,9 +4625,9 @@ package android.app { public class ActivityManager { method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap); method @FlaggedApi("android.app.app_start_info") public void addApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method @FlaggedApi("android.app.app_start_info") public void addStartInfoTimestamp(@IntRange(from=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START, to=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int, long); method public void appNotResponding(@NonNull String); method @FlaggedApi("android.app.app_start_info") public void clearApplicationStartInfoCompletionListener(); method public boolean clearApplicationUserData(); method public void clearWatchHeapLimit(); method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String); Loading Loading @@ -4661,8 +4661,8 @@ 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 @FlaggedApi("android.app.app_start_info") public void removeApplicationStartInfoCompletionListener(@NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method @Deprecated public void restartPackage(String); method @FlaggedApi("android.app.app_start_info") public void setApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>); method public void setProcessStateSummary(@Nullable byte[]); method public static void setVrThread(int); method public void setWatchHeapLimit(long);
core/java/android/app/ActivityManager.java +80 −18 Original line number Diff line number Diff line Loading @@ -4052,10 +4052,28 @@ public class ActivityManager { } } private final ArrayList<AppStartInfoCallbackWrapper> mAppStartInfoCallbacks = new ArrayList<>(); @Nullable private IApplicationStartInfoCompleteListener mAppStartInfoCompleteListener = null; private static final class AppStartInfoCallbackWrapper { @NonNull final Executor mExecutor; @NonNull final Consumer<ApplicationStartInfo> mListener; AppStartInfoCallbackWrapper(@NonNull final Executor executor, @NonNull final Consumer<ApplicationStartInfo> listener) { mExecutor = executor; mListener = listener; } } /** * Sets a callback to be notified when the {@link ApplicationStartInfo} records of this startup * Adds a callback to be notified when the {@link ApplicationStartInfo} records of this startup * are complete. * * <p class="note"> Note: callback will be removed automatically after being triggered.</p> * * <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> Loading @@ -4073,34 +4091,78 @@ public class ActivityManager { * @throws IllegalArgumentException if executor or listener are null. */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public void setApplicationStartInfoCompletionListener(@NonNull final Executor executor, public void addApplicationStartInfoCompletionListener(@NonNull final Executor executor, @NonNull final Consumer<ApplicationStartInfo> listener) { Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(listener, "listener cannot be null"); IApplicationStartInfoCompleteListener callback = new IApplicationStartInfoCompleteListener.Stub() { synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { if (listener.equals(mAppStartInfoCallbacks.get(i).mListener)) { return; } } if (mAppStartInfoCompleteListener == null) { mAppStartInfoCompleteListener = new IApplicationStartInfoCompleteListener.Stub() { @Override public void onApplicationStartInfoComplete(ApplicationStartInfo applicationStartInfo) { executor.execute(() -> listener.accept(applicationStartInfo)); public void onApplicationStartInfoComplete( ApplicationStartInfo applicationStartInfo) { synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { final AppStartInfoCallbackWrapper callback = mAppStartInfoCallbacks.get(i); callback.mExecutor.execute(() -> callback.mListener.accept( applicationStartInfo)); } mAppStartInfoCallbacks.clear(); mAppStartInfoCompleteListener = null; } } }; boolean succeeded = false; try { getService().setApplicationStartInfoCompleteListener(callback, mContext.getUserId()); getService().addApplicationStartInfoCompleteListener( mAppStartInfoCompleteListener, mContext.getUserId()); succeeded = true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } if (succeeded) { mAppStartInfoCallbacks.add(new AppStartInfoCallbackWrapper(executor, listener)); } else { mAppStartInfoCompleteListener = null; mAppStartInfoCallbacks.clear(); } } else { mAppStartInfoCallbacks.add(new AppStartInfoCallbackWrapper(executor, listener)); } } } /** * Removes the callback set by {@link #setApplicationStartInfoCompletionListener} if there is one. * Removes the provided callback set by {@link #addApplicationStartInfoCompletionListener}. */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public void clearApplicationStartInfoCompletionListener() { public void removeApplicationStartInfoCompletionListener( @NonNull final Consumer<ApplicationStartInfo> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); synchronized (mAppStartInfoCallbacks) { for (int i = 0; i < mAppStartInfoCallbacks.size(); i++) { final AppStartInfoCallbackWrapper callback = mAppStartInfoCallbacks.get(i); if (listener.equals(callback.mListener)) { mAppStartInfoCallbacks.remove(i); break; } } if (mAppStartInfoCompleteListener != null && mAppStartInfoCallbacks.isEmpty()) { try { getService().clearApplicationStartInfoCompleteListener(mContext.getUserId()); getService().removeApplicationStartInfoCompleteListener( mAppStartInfoCompleteListener, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mAppStartInfoCompleteListener = null; } } } /** Loading
core/java/android/app/ApplicationStartInfo.java +18 −16 Original line number Diff line number Diff line Loading @@ -39,12 +39,17 @@ import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * Provide information related to a processes startup. * Describes information related to an application process's startup. * * <p> * Many aspects concerning why and how an applications process was started are valuable for apps * both for logging and for potential behavior changes. Reason for process start, start type, * start times, throttling, and other useful diagnostic data can be obtained from * {@link ApplicationStartInfo} records. * </p> */ @FlaggedApi(Flags.FLAG_APP_START_INFO) public final class ApplicationStartInfo implements Parcelable { Loading Loading @@ -552,13 +557,12 @@ public final class ApplicationStartInfo implements Parcelable { dest.writeInt(mDefiningUid); dest.writeString(mProcessName); dest.writeInt(mReason); dest.writeInt(mStartupTimestampsNs.size()); Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet(); Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator(); while (iter.hasNext()) { Map.Entry<Integer, Long> entry = iter.next(); dest.writeInt(entry.getKey()); dest.writeLong(entry.getValue()); dest.writeInt(mStartupTimestampsNs == null ? 0 : mStartupTimestampsNs.size()); if (mStartupTimestampsNs != null) { for (int i = 0; i < mStartupTimestampsNs.size(); i++) { dest.writeInt(mStartupTimestampsNs.keyAt(i)); dest.writeLong(mStartupTimestampsNs.valueAt(i)); } } dest.writeInt(mStartType); dest.writeParcelable(mStartIntent, flags); Loading Loading @@ -740,13 +744,11 @@ public final class ApplicationStartInfo implements Parcelable { sb.append(" intent=").append(mStartIntent.toString()) .append('\n'); } if (mStartupTimestampsNs.size() > 0) { if (mStartupTimestampsNs != null && mStartupTimestampsNs.size() > 0) { sb.append(" timestamps: "); Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet(); Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator(); while (iter.hasNext()) { Map.Entry<Integer, Long> entry = iter.next(); sb.append(entry.getKey()).append("=").append(entry.getValue()).append(" "); for (int i = 0; i < mStartupTimestampsNs.size(); i++) { sb.append(mStartupTimestampsNs.keyAt(i)).append("=").append(mStartupTimestampsNs .valueAt(i)).append(" "); } sb.append('\n'); } Loading
core/java/android/app/IActivityManager.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -715,7 +715,7 @@ interface IActivityManager { * @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, void addApplicationStartInfoCompleteListener(IApplicationStartInfoCompleteListener listener, int userId); Loading @@ -724,7 +724,8 @@ interface IActivityManager { * * @param userId The userId in the multi-user environment. */ void clearApplicationStartInfoCompleteListener(int userId); void removeApplicationStartInfoCompleteListener(IApplicationStartInfoCompleteListener listener, int userId); /** Loading
services/core/java/com/android/server/am/ActivityManagerService.java +5 −3 Original line number Diff line number Diff line Loading @@ -9858,7 +9858,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setApplicationStartInfoCompleteListener( public void addApplicationStartInfoCompleteListener( IApplicationStartInfoCompleteListener listener, int userId) { enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener"); Loading @@ -9873,7 +9873,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void clearApplicationStartInfoCompleteListener(int userId) { public void removeApplicationStartInfoCompleteListener( IApplicationStartInfoCompleteListener listener, int userId) { enforceNotIsolatedCaller("clearApplicationStartInfoCompleteListener"); // For the simplification, we don't support USER_ALL nor USER_CURRENT here. Loading @@ -9882,7 +9883,8 @@ public class ActivityManagerService extends IActivityManager.Stub } final int callingUid = Binder.getCallingUid(); mProcessList.getAppStartInfoTracker().clearStartInfoCompleteListener(callingUid, true); mProcessList.getAppStartInfoTracker().removeStartInfoCompleteListener(listener, callingUid, true); } @Override Loading