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

Commit cdfc04e7 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fix app transition logging when switching quickly

If an app was set to invisible before the transition started,
which happens when quickly open an app and then closing again
before the animation is starting (only possible if starting
window is slightly delayed), we never receive onWindowsDrawn so we
need to cancel the transition in this case.

Also fixes an issue where the wrong activity was reported as
starting to us in case reusedActivity != null but we'll only reuse
it for the task and not the actual activity.

Test: Open Calendar, press home immediately, open another app, make
sure all logged events and times are correct.
Fixes: 37538546

Change-Id: I5819bd97964ab2dd5cb40b2f4e3bc5a9ac348152
parent 0c215009
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -11,12 +11,12 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_IS_EPHEMERAL;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_HOT_LAUNCH;
@@ -194,6 +194,11 @@ class ActivityMetricsLogger {
        final int stackId = launchedActivity != null && launchedActivity.getStack() != null
                ? launchedActivity.getStack().mStackId
                : INVALID_STACK_ID;

        if (mCurrentTransitionStartTime == INVALID_START_TIME) {
            return;
        }

        final StackTransitionInfo info = mStackTransitionInfo.get(stackId);
        if (launchedActivity != null && info != null) {
            info.launchedActivity = launchedActivity;
@@ -272,6 +277,25 @@ class ActivityMetricsLogger {
        }
    }

    /**
     * Notifies the tracker that the visibility of an app is changing.
     *
     * @param activityRecord the app that is changing its visibility
     * @param visible whether it's going to be visible or not
     */
    void notifyVisibilityChanged(ActivityRecord activityRecord, boolean visible) {
        final StackTransitionInfo info = mStackTransitionInfo.get(activityRecord.getStackId());

        // If we have an active transition that's waiting on a certain activity that will be
        // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
        if (info != null && !visible && info.launchedActivity == activityRecord) {
            mStackTransitionInfo.remove(activityRecord.getStackId());
            if (mStackTransitionInfo.size() == 0) {
                reset(true /* abort */);
            }
        }
    }

    private boolean allStacksWindowsDrawn() {
        for (int index = mStackTransitionInfo.size() - 1; index >= 0; index--) {
            if (!mStackTransitionInfo.valueAt(index).loggedWindowsDrawn) {
+2 −1
Original line number Diff line number Diff line
@@ -1052,7 +1052,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        return task != null ? (T) task.getStack() : null;
    }

    private int getStackId() {
    int getStackId() {
        return getStack() != null ? getStack().mStackId : INVALID_STACK_ID;
    }

@@ -1579,6 +1579,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo

    void setVisibility(boolean visible) {
        mWindowContainerController.setVisibility(visible, mDeferHidingClient);
        mStackSupervisor.mActivityMetricsLogger.notifyVisibilityChanged(this, visible);
    }

    // TODO: Look into merging with #setVisibility()
+3 −3
Original line number Diff line number Diff line
@@ -1045,9 +1045,6 @@ class ActivityStarter {
            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);

            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
            if (outActivity != null && outActivity.length > 0) {
                outActivity[0] = reusedActivity;
            }

            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a new activity, and the client said not to do anything
@@ -1062,6 +1059,9 @@ class ActivityStarter {
                // We didn't do anything...  but it was needed (a.k.a., client don't use that
                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
                resumeTargetStackIfNeeded();
                if (outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }
                return START_TASK_TO_FRONT;
            }
        }