[DO NOT MERGE] AM: Fix invalid hot launch app metrics seen with quickstep
When quickstep is enabled, and the home button is pressed, AML receives two launches. The second launch is always incomplete. When an activity is then launched, the Launcher activity is treated as a trampoline activity and the launch will be reported as a hot launch with inflated times. The second launch is incomplete because we never get a window's drawn message for the second launch. We solve this by keeping track of windows drawn state in the Activity Record. If an activity is launched and its windows are already drawn, then we abort the launch metrics. Test: manual test with quickstep Test: atest ActivityMetricsLoggerTest Bug: 119221454 Change-Id: Id34a1c42c9b2ea356757109fedf5e2a1a3b020c8
This commit is contained in:
@@ -372,7 +372,7 @@ class ActivityMetricsLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
if (launchedActivity != null && launchedActivity.nowVisible) {
|
||||
if (launchedActivity != null && launchedActivity.drawn) {
|
||||
// Launched activity is already visible. We cannot measure windows drawn delay.
|
||||
reset(true /* abort */, info);
|
||||
return;
|
||||
|
||||
@@ -308,6 +308,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
// process that it is hidden.
|
||||
boolean sleeping; // have we told the activity to sleep?
|
||||
boolean nowVisible; // is this activity's window visible?
|
||||
boolean drawn; // is this activity's window drawn?
|
||||
boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
|
||||
boolean idle; // has the activity gone idle?
|
||||
boolean hasBeenLaunched;// has this activity ever been launched?
|
||||
@@ -871,6 +872,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
inHistory = false;
|
||||
visible = false;
|
||||
nowVisible = false;
|
||||
drawn = false;
|
||||
idle = false;
|
||||
hasBeenLaunched = false;
|
||||
mStackSupervisor = supervisor;
|
||||
@@ -1999,6 +2001,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
@Override
|
||||
public void onWindowsDrawn(long timestamp) {
|
||||
synchronized (service) {
|
||||
drawn = true;
|
||||
final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
|
||||
.getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
|
||||
final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
|
||||
@@ -2012,6 +2015,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowsNotDrawn(long timestamp) {
|
||||
synchronized (service) {
|
||||
drawn = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowsVisible() {
|
||||
synchronized (service) {
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.android.server.wm;
|
||||
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
|
||||
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
|
||||
import static android.view.WindowManager.TRANSIT_UNSET;
|
||||
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
|
||||
@@ -65,6 +65,7 @@ public class AppWindowContainerController
|
||||
private final class H extends Handler {
|
||||
public static final int NOTIFY_WINDOWS_DRAWN = 1;
|
||||
public static final int NOTIFY_STARTING_WINDOW_DRAWN = 2;
|
||||
public static final int NOTIFY_WINDOWS_NOTDRAWN = 3;
|
||||
|
||||
public H(Looper looper) {
|
||||
super(looper);
|
||||
@@ -85,10 +86,18 @@ public class AppWindowContainerController
|
||||
if (mListener == null) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting drawn in "
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting starting window drawn in "
|
||||
+ AppWindowContainerController.this.mToken);
|
||||
mListener.onStartingWindowDrawn(msg.getWhen());
|
||||
break;
|
||||
case NOTIFY_WINDOWS_NOTDRAWN:
|
||||
if (mListener == null) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting undrawn in "
|
||||
+ AppWindowContainerController.this.mToken);
|
||||
mListener.onWindowsNotDrawn(msg.getWhen());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -740,6 +749,10 @@ public class AppWindowContainerController
|
||||
mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_DRAWN));
|
||||
}
|
||||
|
||||
void reportWindowsNotDrawn() {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_NOTDRAWN));
|
||||
}
|
||||
|
||||
void reportWindowsVisible() {
|
||||
mHandler.post(mOnWindowsVisible);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ package com.android.server.wm;
|
||||
public interface AppWindowContainerListener extends WindowContainerListener {
|
||||
/** Called when the windows associated app window container are drawn. */
|
||||
void onWindowsDrawn(long timestamp);
|
||||
/** Called when the windows associated app window container are no longer drawn. */
|
||||
default void onWindowsNotDrawn(long timestamp) {}
|
||||
/** Called when the windows associated app window container are visible. */
|
||||
void onWindowsVisible();
|
||||
/** Called when the windows associated app window container are no longer visible. */
|
||||
|
||||
@@ -354,6 +354,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
|
||||
if (controller != null) {
|
||||
controller.reportWindowsDrawn();
|
||||
}
|
||||
} else {
|
||||
if (controller != null) {
|
||||
controller.reportWindowsNotDrawn();
|
||||
}
|
||||
}
|
||||
reportedDrawn = nowDrawn;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user