diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index a781520c48d93..2b6a83896cc63 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -102,7 +102,6 @@ import com.android.server.apphibernation.AppHibernationManagerInternal; import com.android.server.apphibernation.AppHibernationService; import java.util.ArrayList; -import java.util.LinkedList; import java.util.concurrent.TimeUnit; /** @@ -216,7 +215,7 @@ class ActivityMetricsLogger { /** whether the process of the launching activity didn't have any active activity. */ final boolean mProcessSwitch; /** The activities that should be drawn. */ - final LinkedList mPendingDrawActivities = new LinkedList<>(); + final ArrayList mPendingDrawActivities = new ArrayList<>(2); /** The latest activity to have been launched. */ @NonNull ActivityRecord mLastLaunchedActivity; @@ -328,6 +327,17 @@ class ActivityMetricsLogger { return mPendingDrawActivities.isEmpty(); } + /** Only keep the records which can be drawn. */ + void updatePendingDraw() { + for (int i = mPendingDrawActivities.size() - 1; i >= 0; i--) { + final ActivityRecord r = mPendingDrawActivities.get(i); + if (!r.mVisibleRequested) { + if (DEBUG_METRICS) Slog.i(TAG, "Discard pending draw " + r); + mPendingDrawActivities.remove(i); + } + } + } + /** * @return {@code true} if the transition info should be sent to MetricsLogger, StatsLog, or * LaunchObserver. @@ -701,6 +711,7 @@ class ActivityMetricsLogger { info.mCurrentTransitionDelayMs = info.calculateDelay(timestampNs); info.mReason = activityToReason.valueAt(index); info.mLoggedTransitionStarting = true; + info.updatePendingDraw(); if (info.allDrawn()) { done(false /* abort */, info, "notifyTransitionStarting - all windows drawn", timestampNs); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java index beff3862df010..82c459c6868a4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java @@ -353,8 +353,22 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { mTrampolineActivity.setVisibility(false); notifyWindowsDrawn(mTopActivity); - assertWithMessage("Trampoline activity is invisble so there should be no undrawn windows") + assertWithMessage("Trampoline activity is invisible so there should be no undrawn windows") .that(mLaunchingState.allDrawn()).isTrue(); + + // Since the activity is drawn, the launch event should be reported. + notifyTransitionStarting(mTopActivity); + verifyOnActivityLaunchFinished(mTopActivity); + mLaunchTopByTrampoline = false; + clearInvocations(mLaunchObserver); + + // Another round without setting visibility of the trampoline activity. + onActivityLaunchedTrampoline(); + notifyWindowsDrawn(mTopActivity); + // If the transition can start, the invisible activities should be discarded and the launch + // event be reported successfully. + notifyTransitionStarting(mTopActivity); + verifyOnActivityLaunchFinished(mTopActivity); } @Test