Merge "fix "am start -W" hang on activity start" into nyc-dev
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index aaf8301..a7f4314 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1123,6 +1123,13 @@
 
     public void reportFullyDrawnLocked() {
         final long curTime = SystemClock.uptimeMillis();
+        // Normally launch time counts from the point when the activity is resumed, to when the
+        // first window is drawn. However the activity could become visible before it is resumed,
+        // due to some other activity in the same task being launched. In this case we still need
+        // to report launch time to unblock ActivityStarter.startActivityMayWait().
+        if (displayStartTime == 0 && task != null && task.isLaunching) {
+            displayStartTime = curTime;
+        }
         if (displayStartTime != 0) {
             reportLaunchTimeLocked(curTime);
         }
@@ -1188,13 +1195,22 @@
             //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
         }
         displayStartTime = 0;
+        task.isLaunching = false;
         stack.mLaunchStartTime = 0;
     }
 
     void windowsDrawnLocked() {
         mStackSupervisor.mActivityMetricsLogger.notifyWindowsDrawn();
+        final long curTime = SystemClock.uptimeMillis();
+        // Normally launch time counts from the point when the activity is resumed, to when the
+        // first window is drawn. However the activity could become visible before it is resumed,
+        // due to some other activity in the same task being launched. In this case we still need
+        // to report launch time to unblock ActivityStarter.startActivityMayWait().
+        if (displayStartTime == 0 && task != null && task.isLaunching) {
+            displayStartTime = curTime;
+        }
         if (displayStartTime != 0) {
-            reportLaunchTimeLocked(SystemClock.uptimeMillis());
+            reportLaunchTimeLocked(curTime);
         }
         mStackSupervisor.sendWaitingVisibleReportLocked(this);
         startTime = 0;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3df4a61..5249131 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -912,6 +912,9 @@
     void setLaunchTime(ActivityRecord r) {
         if (r.displayStartTime == 0) {
             r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
+            if (r.task != null) {
+                r.task.isLaunching = true;
+            }
             if (mLaunchStartTime == 0) {
                 startLaunchTraces(r.packageName);
                 mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
@@ -926,6 +929,9 @@
         // Make sure that there is no activity waiting for this to launch.
         if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
             r.displayStartTime = r.fullyDrawnStartTime = 0;
+            if (r.task != null) {
+                r.task.isLaunching = false;
+            }
         } else {
             mStackSupervisor.removeTimeoutsForActivityLocked(r);
             mStackSupervisor.scheduleIdleTimeoutLocked(r);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5a5f861..0165fdf 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -151,6 +151,7 @@
     long lastActiveTime;    // Last time this task was active, including sleep.
     boolean inRecents;      // Actually in the recents list?
     boolean isAvailable;    // Is the activity available to be launched?
+    boolean isLaunching;    // Is an activity in this task launching?
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
     boolean autoRemoveRecents;  // If true, we should automatically remove the task from