[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:
Vishnu Nair
2018-11-08 16:50:12 -08:00
parent cf23504955
commit c1d2ff60f0
5 changed files with 32 additions and 3 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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. */

View File

@@ -354,6 +354,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
if (controller != null) {
controller.reportWindowsDrawn();
}
} else {
if (controller != null) {
controller.reportWindowsNotDrawn();
}
}
reportedDrawn = nowDrawn;
}