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

Commit a808b653 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Tell activity metrics logger whether a new activity is created

That helps to distinguish hot/warm launch more accurately. In most
cases it was no problem because the previous foreground activity
needs to be pause first so the activity won't attach to process
when executing the launch request. But if all activities are
already paused and the launching activity can be resumed directly,
ATS#realStartActivityLocked will be called immediately so the
transition type becomes always hot launch. E.g. launch activity
which can occlude keyguard from lockscreen.

Also removed unused ActivityStarter#startResolvedActivity.

Bug: 186692122
Test: ActivityMetricsLoggerTests
      ActivityMetricsLaunchObserverTests

Change-Id: I2bcc4bb3325c2e69e27d0deef188272c943ab6ce
parent 285e3754
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -247,13 +247,14 @@ class ActivityMetricsLogger {
        @Nullable
        static TransitionInfo create(@NonNull ActivityRecord r,
                @NonNull LaunchingState launchingState, @Nullable ActivityOptions options,
                boolean processRunning, boolean processSwitch, int startResult) {
                boolean processRunning, boolean processSwitch, boolean newActivityCreated,
                int startResult) {
            if (startResult != START_SUCCESS && startResult != START_TASK_TO_FRONT) {
                return null;
            }
            final int transitionType;
            if (processRunning) {
                transitionType = r.attachedToProcess()
                transitionType = !newActivityCreated && r.attachedToProcess()
                        ? TYPE_TRANSITION_HOT_LAUNCH
                        : TYPE_TRANSITION_WARM_LAUNCH;
            } else {
@@ -560,10 +561,12 @@ class ActivityMetricsLogger {
     * @param resultCode One of the {@link android.app.ActivityManager}.START_* flags, indicating
     *                   the result of the launch.
     * @param launchedActivity The activity that is being launched
     * @param newActivityCreated Whether a new activity instance is created.
     * @param options The given options of the launching activity.
     */
    void notifyActivityLaunched(@NonNull LaunchingState launchingState, int resultCode,
            @Nullable ActivityRecord launchedActivity, @Nullable ActivityOptions options) {
            boolean newActivityCreated, @Nullable ActivityRecord launchedActivity,
            @Nullable ActivityOptions options) {
        if (launchedActivity == null) {
            // The launch is aborted, e.g. intent not resolved, class not found.
            abort(null /* info */, "nothing launched");
@@ -587,7 +590,8 @@ class ActivityMetricsLogger {
        if (DEBUG_METRICS) {
            Slog.i(TAG, "notifyActivityLaunched" + " resultCode=" + resultCode
                    + " launchedActivity=" + launchedActivity + " processRunning=" + processRunning
                    + " processSwitch=" + processSwitch + " info=" + info);
                    + " processSwitch=" + processSwitch
                    + " newActivityCreated=" + newActivityCreated + " info=" + info);
        }

        if (launchedActivity.isReportedDrawn() && launchedActivity.isVisible()) {
@@ -608,7 +612,7 @@ class ActivityMetricsLogger {
        }

        final TransitionInfo newInfo = TransitionInfo.create(launchedActivity, launchingState,
                options, processRunning, processSwitch, resultCode);
                options, processRunning, processSwitch, newActivityCreated, resultCode);
        if (newInfo == null) {
            abort(info, "unrecognized launch");
            return;
+3 −25
Original line number Diff line number Diff line
@@ -601,30 +601,6 @@ class ActivityStarter {
                || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
    }

    /**
     * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
     * Note that this method is called internally as well as part of {@link #executeRequest}.
     */
    void startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            NeededUriGrants intentGrants) {
        try {
            final LaunchingState launchingState = mSupervisor.getActivityMetricsLogger()
                    .notifyActivityLaunching(r.intent, r.resultTo);
            mLastStartReason = "startResolvedActivity";
            mLastStartActivityTimeMs = System.currentTimeMillis();
            mLastStartActivityRecord = r;
            mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                    voiceInteractor, startFlags, doResume, options, inTask,
                    false /* restrictedBgActivity */, intentGrants);
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
                    mLastStartActivityResult, mLastStartActivityRecord, options);
        } finally {
            onExecutionComplete();
        }
    }

    /**
     * Resolve necessary information according the request parameters provided earlier, and execute
     * the request which begin the journey of starting an activity.
@@ -707,11 +683,13 @@ class ActivityStarter {
                // used here because it may be cleared in setTargetRootTaskIfNeeded.
                final ActivityOptions originalOptions = mRequest.activityOptions != null
                        ? mRequest.activityOptions.getOriginalOptions() : null;
                // If the new record is the one that started, a new activity has created.
                final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
                // Notify ActivityMetricsLogger that the activity has launched.
                // ActivityMetricsLogger will then wait for the windows to be drawn and populate
                // WaitResult.
                mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                        mLastStartActivityRecord, originalOptions);
                        newActivityCreated, mLastStartActivityRecord, originalOptions);
                if (mRequest.waitResult != null) {
                    mRequest.waitResult.result = res;
                    res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
+2 −1
Original line number Diff line number Diff line
@@ -2542,7 +2542,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                    targetActivity.applyOptionsAnimation();
                } finally {
                    mActivityMetricsLogger.notifyActivityLaunched(launchingState,
                            START_TASK_TO_FRONT, targetActivity, activityOptions);
                            START_TASK_TO_FRONT, false /* newActivityCreated */, targetActivity,
                            activityOptions);
                }

                mService.getActivityStartController().postStartActivityProcessingForLastStarter(
+1 −1
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
                options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
            }
            mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
                    START_TASK_TO_FRONT, targetActivity, options);
                    START_TASK_TO_FRONT, !hasExistingActivity, targetActivity, options);

            // Register for root task order changes
            mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(this);
+5 −2
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
    private ActivityRecord mTopActivity;
    private ActivityOptions mActivityOptions;
    private boolean mLaunchTopByTrampoline;
    private boolean mNewActivityCreated = true;

    @Before
    public void setUpAMLO() {
@@ -187,6 +188,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
                .isEqualTo(WaitResult.LAUNCH_STATE_WARM);

        mTopActivity.app = app;
        mNewActivityCreated = false;
        assertWithMessage("Hot launch").that(launchTemplate.applyAsInt(false /* doRelaunch */))
                .isEqualTo(WaitResult.LAUNCH_STATE_HOT);

@@ -194,6 +196,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
                .isEqualTo(WaitResult.LAUNCH_STATE_RELAUNCH);

        mTopActivity.app = null;
        mNewActivityCreated = true;
        doReturn(null).when(mAtm).getProcessController(app.mName, app.mUid);
        assertWithMessage("Cold launch").that(launchTemplate.applyAsInt(false /* doRelaunch */))
                .isEqualTo(WaitResult.LAUNCH_STATE_COLD);
@@ -313,8 +316,8 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
    }

    private void notifyActivityLaunched(int resultCode, ActivityRecord activity) {
        mActivityMetricsLogger.notifyActivityLaunched(mLaunchingState, resultCode, activity,
                mActivityOptions);
        mActivityMetricsLogger.notifyActivityLaunched(mLaunchingState, resultCode,
                mNewActivityCreated, activity, mActivityOptions);
    }

    private void notifyTransitionStarting(ActivityRecord activity) {
Loading