Merge "AM: Fix invalid hot launch app metrics seen with quickstep"
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 61e1414..1c08d03 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -383,7 +383,7 @@
             return;
         }
 
-        if (launchedActivity != null && launchedActivity.nowVisible) {
+        if (launchedActivity != null && launchedActivity.mDrawn) {
             // Launched activity is already visible. We cannot measure windows drawn delay.
             reset(true /* abort */, info, "launched activity already visible");
             return;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 23f8125..c43e64e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
 import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
 import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
 import static android.app.WaitResult.INVALID_DELAY;
@@ -75,6 +76,25 @@
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
 
+import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
+import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
+import static com.android.server.am.ActivityRecordProto.PROC_ID;
+import static com.android.server.am.ActivityRecordProto.STATE;
+import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
+import static com.android.server.am.ActivityRecordProto.VISIBLE;
+import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
+import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
+import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
+import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
+import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
+import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -89,34 +109,14 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
-import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
-import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
-import static com.android.server.am.ActivityRecordProto.PROC_ID;
-import static com.android.server.am.ActivityRecordProto.STATE;
-import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
-import static com.android.server.am.ActivityRecordProto.VISIBLE;
-import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
-import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
-import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
-import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
-import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
-import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
-import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
-import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
-import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
-import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
-import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
-import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
-import static com.android.server.wm.TaskPersister.DEBUG;
-import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
 import static com.android.server.wm.IdentifierProto.USER_ID;
+import static com.android.server.wm.TaskPersister.DEBUG;
+import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
@@ -179,9 +179,9 @@
 import com.android.server.AttributeCache.Entry;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.am.PendingIntentRecord;
+import com.android.server.uri.UriPermissionOwner;
 import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
 import com.android.server.wm.ActivityStack.ActivityState;
-import com.android.server.uri.UriPermissionOwner;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -303,6 +303,7 @@
                                         // process that it is hidden.
     boolean sleeping;       // have we told the activity to sleep?
     boolean nowVisible;     // is this activity's window visible?
+    boolean mDrawn;          // 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?
@@ -869,6 +870,7 @@
         inHistory = false;
         visible = false;
         nowVisible = false;
+        mDrawn = false;
         idle = false;
         hasBeenLaunched = false;
         mStackSupervisor = supervisor;
@@ -1944,8 +1946,12 @@
     }
 
     @Override
-    public void onWindowsDrawn(long timestamp) {
+    public void onWindowsDrawn(boolean drawn, long timestamp) {
         synchronized (service.mGlobalLock) {
+            mDrawn = drawn;
+            if (!drawn) {
+                return;
+            }
             final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
                     .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
             final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 3cbb2577..bd1460a 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -82,6 +82,7 @@
     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);
@@ -96,16 +97,24 @@
                     }
                     if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting drawn in "
                             + AppWindowContainerController.this.mToken);
-                    mListener.onWindowsDrawn(msg.getWhen());
+                    mListener.onWindowsDrawn(true /* drawn */, msg.getWhen());
                     break;
                 case NOTIFY_STARTING_WINDOW_DRAWN:
                     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 not drawn in "
+                            + AppWindowContainerController.this.mToken);
+                    mListener.onWindowsDrawn(false /* drawn */, msg.getWhen());
+                    break;
                 default:
                     break;
             }
@@ -762,6 +771,10 @@
         mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_DRAWN));
     }
 
+    void reportWindowsNotDrawn() {
+        mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_NOTDRAWN));
+    }
+
     void reportWindowsVisible() {
         mHandler.post(mOnWindowsVisible);
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
index 8a39a74..ad27669 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerListener.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
@@ -18,8 +18,8 @@
 
 /** Interface used by the creator of the controller to listen to changes with the container. */
 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 drawn state changes. */
+    void onWindowsDrawn(boolean drawn, 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. */
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 1709588..111c921 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -366,6 +366,10 @@
                 if (controller != null) {
                     controller.reportWindowsDrawn();
                 }
+            } else {
+                if (controller != null) {
+                    controller.reportWindowsNotDrawn();
+                }
             }
             reportedDrawn = nowDrawn;
         }