Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbd39b78 authored by Yisroel Forta's avatar Yisroel Forta Committed by Android (Google) Code Review
Browse files

Merge "AppStartInfo API Updates" into main

parents 7ac51097 d7864133
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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);
+80 −18
Original line number Diff line number Diff line
@@ -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>
@@ -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;
            }
        }
    }

    /**
+18 −16
Original line number Diff line number Diff line
@@ -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 {
@@ -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);
@@ -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');
        }
+3 −2
Original line number Diff line number Diff line
@@ -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);


@@ -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);


    /**
+5 −3
Original line number Diff line number Diff line
@@ -9858,7 +9858,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void setApplicationStartInfoCompleteListener(
    public void addApplicationStartInfoCompleteListener(
            IApplicationStartInfoCompleteListener listener, int userId) {
        enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener");
@@ -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.
@@ -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