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

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

Centralize latency measurement of recents animation

So both legacy and shell transition use the same logic to log
the latency number.

Bug: 218847872
Test: Launch any app and swipe from bottom. The logcat should
      contain "LatencyTracker: ACTION_START_RECENTS_ANIMATION".
Change-Id: I5b28ca76f4a7b3d5a22ffc13f919c59003163e6b
parent d9fa425f
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -144,6 +144,12 @@ class ActivityMetricsLogger {
     */
    private static final long UNKNOWN_VISIBILITY_CHECK_DELAY_MS = 3000;

    /**
     * If the recents animation is finished before the delay since the window drawn, do not log the
     * action because the duration is too small that may be just an accidentally touch.
     */
    private static final long LATENCY_TRACKER_RECENTS_DELAY_MS = 300;

    /**
     * The flag for {@link #notifyActivityLaunching} to skip associating a new launch with an active
     * transition, in the case the launch is standalone (e.g. from recents).
@@ -734,10 +740,6 @@ class ActivityMetricsLogger {
        if (info.mLoggedTransitionStarting) {
            done(false /* abort */, info, "notifyWindowsDrawn", timestampNs);
        }
        if (r.mWmService.isRecentsAnimationTarget(r)) {
            r.mWmService.getRecentsAnimationController().logRecentsAnimationStartTime(
                    info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs);
        }
        return infoSnapshot;
    }

@@ -782,12 +784,6 @@ class ActivityMetricsLogger {
            info.mReason = activityToReason.valueAt(index);
            info.mLoggedTransitionStarting = true;
            if (info.mIsDrawn) {
                if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
                    final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
                    final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
                    mLoggerHandler.post(() -> latencyTracker.logAction(
                            LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
                }
                done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
            }
        }
@@ -955,6 +951,9 @@ class ActivityMetricsLogger {
                launchObserverNotifyActivityLaunchFinished(info, timestampNs);
            }
            logAppTransitionFinished(info, isHibernating != null ? isHibernating : false);
            if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
                logRecentsAnimationLatency(info);
            }
        }
        mTransitionInfoList.remove(info);
    }
@@ -1110,6 +1109,22 @@ class ActivityMetricsLogger {
        Log.i(TAG, sb.toString());
    }

    private void logRecentsAnimationLatency(TransitionInfo info) {
        final int duration = info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs;
        final ActivityRecord r = info.mLastLaunchedActivity;
        final long lastTopLossTime = r.topResumedStateLossTime;
        final WindowManagerService wm = mSupervisor.mService.mWindowManager;
        final Object controller = wm.getRecentsAnimationController();
        mLoggerHandler.postDelayed(() -> {
            if (lastTopLossTime != r.topResumedStateLossTime
                    || controller != wm.getRecentsAnimationController()) {
                // Skip if the animation was finished in a short time.
                return;
            }
            wm.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration);
        }, LATENCY_TRACKER_RECENTS_DELAY_MS);
    }

    private static int getAppStartTransitionType(int tronType, boolean relaunched) {
        if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
            return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;
+1 −17
Original line number Diff line number Diff line
@@ -71,9 +71,7 @@ import android.window.TaskSnapshot;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.os.BackgroundThread;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
@@ -99,11 +97,6 @@ import java.util.stream.Collectors;
public class RecentsAnimationController implements DeathRecipient {
    private static final String TAG = RecentsAnimationController.class.getSimpleName();
    private static final long FAILSAFE_DELAY = 1000;
    /**
     * If the recents animation is canceled before the delay since the window drawn, do not log the
     * action because the duration is too small that may be just a mistouch.
     */
    private static final long LATENCY_TRACKER_LOG_DELAY_MS = 300;

    // Constant for a yet-to-be-calculated {@link RemoteAnimationTarget#Mode} state
    private static final int MODE_UNKNOWN = -1;
@@ -144,7 +137,7 @@ public class RecentsAnimationController implements DeathRecipient {
    private boolean mPendingStart = true;

    // Set when the animation has been canceled
    private volatile boolean mCanceled;
    private boolean mCanceled;

    // Whether or not the input consumer is enabled. The input consumer must be both registered and
    // enabled for it to start intercepting touch events.
@@ -785,15 +778,6 @@ public class RecentsAnimationController implements DeathRecipient {
        }, false /* traverseTopToBottom */);
    }

    void logRecentsAnimationStartTime(int durationMs) {
        BackgroundThread.getHandler().postDelayed(() -> {
            if (!mCanceled) {
                mService.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION,
                        durationMs);
            }
        }, LATENCY_TRACKER_LOG_DELAY_MS);
    }

    private boolean removeTaskInternal(int taskId) {
        boolean result = false;
        for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {