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

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

Postpone reporting fully drawn until app is drawn

"Fully drawn" should stand for an usable state of the application.
If its window hasn't drawn, the early reported time may not close
to the real use case.

This change ensures that "Fully drawn" is at least >= "Displayed".

Bug: 131713448
Test: atest ActivityMetricsLaunchObserverTests#testOnReportFullyDrawn
Test: Launch an application (e.g. Settings) that invokes
      Activity#reportFullyDrawn in an early stage. The printed
      duration of "Displayed" and "Fully drawn" should show
      the same time.

Change-Id: Id37425436dc564fc657f0777db8e0f056bbb748d
parent 94da14c5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2577,6 +2577,9 @@ public class Activity extends ContextThemeWrapper
     * entirely drawn your UI and populated with all of the significant data.  You
     * can safely call this method any time after first launch as well, in which case
     * it will simply be ignored.
     * <p>If this method is called before the activity's window is <em>first</em> drawn
     * and displayed as measured by the system, the reported time here will be shifted
     * to the system measured time.
     */
    public void reportFullyDrawn() {
        if (mDoReportFullyDrawn) {
+18 −3
Original line number Diff line number Diff line
@@ -189,6 +189,8 @@ class ActivityMetricsLogger {
        private int reason = APP_TRANSITION_TIMEOUT;
        // TODO(b/132736359) The number may need to consider the visibility change.
        private int numUndrawnActivities = 1;
        /** Non-null if the application has reported drawn but its window hasn't. */
        private Runnable pendingFullyDrawn;
        private boolean loggedStartingWindowDrawn;
        private boolean launchTraceActive;

@@ -716,6 +718,9 @@ class ActivityMetricsLogger {
            BackgroundThread.getHandler().post(() -> logAppTransition(
                    currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
            BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
            if (info.pendingFullyDrawn != null) {
                info.pendingFullyDrawn.run();
            }

            info.launchedActivity.info.launchToken = null;
        }
@@ -839,6 +844,15 @@ class ActivityMetricsLogger {
        if (info == null) {
            return null;
        }
        if (info.numUndrawnActivities > 0 && info.pendingFullyDrawn == null) {
            // There are still undrawn activities, postpone reporting fully drawn until all of its
            // windows are drawn. So that is closer to an usable state.
            info.pendingFullyDrawn = () -> {
                logAppTransitionReportedDrawn(r, restoredFromBundle);
                info.pendingFullyDrawn = null;
            };
            return null;
        }

        // Record the handling of the reportFullyDrawn callback in the trace system. This is not
        // actually used to trace this function, but instead the logical task that this function
@@ -849,9 +863,10 @@ class ActivityMetricsLogger {
        final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
        builder.setPackageName(r.packageName);
        builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
        long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
        long startupTimeMs =
            TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
        final long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
        final long startupTimeMs = info.pendingFullyDrawn != null
                ? info.windowsDrawnDelayMs
                : TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
        builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
        builder.setType(restoredFromBundle
                ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
+6 −0
Original line number Diff line number Diff line
@@ -195,9 +195,15 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
    public void testOnReportFullyDrawn() {
        onActivityLaunched();

        // The activity reports fully drawn before windows drawn, then the fully drawn event will
        // be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}).
        mActivityMetricsLogger.logAppTransitionReportedDrawn(mTopActivity, false);
        notifyTransitionStarting();
        // The pending fully drawn event should send when the actual windows drawn event occurs.
        notifyWindowsDrawn(mTopActivity);

        verifyAsync(mLaunchObserver).onReportFullyDrawn(eqProto(mTopActivity), anyLong());
        verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
        verifyNoMoreInteractions(mLaunchObserver);
    }