From afb776d5447e19565c9a826a554911decb9ed92a Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Sat, 23 Apr 2016 14:33:55 -0700 Subject: [PATCH] fix "am start -W" hang on activity start 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(). bug: 28333487 Change-Id: I445b602f495ed0c3cb669e2d81a137280317534f --- .../com/android/server/am/ActivityRecord.java | 18 +++++++++++++++++- .../com/android/server/am/ActivityStack.java | 6 ++++++ .../java/com/android/server/am/TaskRecord.java | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index aaf830126b9ec..a7f43140ca7c4 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 @@ final class ActivityRecord { 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 @@ final class ActivityRecord { //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 3df4a61a3dbff..5249131ae0ac6 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { // 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 5a5f861f72f6f..0165fdf6ae7c0 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 @@ final class TaskRecord { 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