From eb628a5333f43d7b14311a2f0b1a4199690bce08 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 14 Feb 2020 00:48:51 +0800 Subject: [PATCH] Fix invalid launch state reported to "am start -W" If a launching activity starts another activity before it finishes drawing, because it becomes invisible, it is dropped from active transition info. The waiting result should not use the intermediate state as the launch is completed. Bug: 123355661 Bug: 149326995 Test: atest ActivityMetricsLoggerTests#testConsecutiveLaunch Change-Id: I9a5776cc7895a8d62ca28700c18efa4fd8b7c33d --- .../android/server/wm/ActivityMetricsLogger.java | 3 +++ .../com/android/server/wm/ActivityRecord.java | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index 0502d0bfa9335..68a71881b898d 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -581,6 +581,9 @@ class ActivityMetricsLogger { /** * Notifies the tracker that all windows of the app have been drawn. + * + * @return Non-null info if the activity was pending to draw, otherwise it might have been set + * to invisible (removed from active transition) or it was already drawn. */ @Nullable TransitionInfoSnapshot notifyWindowsDrawn(@NonNull ActivityRecord r, long timestampNs) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index e26dac62f3497..f3128a745fa43 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5201,11 +5201,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final TransitionInfoSnapshot info = mStackSupervisor .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs); - final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY; - final @LaunchState int launchState = info != null ? info.getLaunchState() : -1; - mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this, - windowsDrawnDelayMs, launchState); - mStackSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs); + final boolean validInfo = info != null; + final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY; + final @LaunchState int launchState = validInfo ? info.getLaunchState() : -1; + // The activity may have been requested to be invisible (another activity has been launched) + // so there is no valid info. But if it is the current top activity (e.g. sleeping), the + // invalid state is still reported to make sure the waiting result is notified. + if (validInfo || this == mDisplayContent.topRunningActivity()) { + mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this, + windowsDrawnDelayMs, launchState); + mStackSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs); + } finishLaunchTickingLocked(); if (task != null) { task.hasBeenVisible = true;