diff options
| author | 2016-06-21 16:31:37 -0700 | |
|---|---|---|
| committer | 2016-06-21 19:44:09 -0700 | |
| commit | 5022da313f6b2fbd16e55ebabaadbb308e96e908 (patch) | |
| tree | b12e3d20394e7c63939ae7037258ce331cd16bc5 | |
| parent | c211539769dfaa507cfaf7dc22e9feb56065018c (diff) | |
Unblock 'am start -W' if activity is brought to front without launching
If -W is used to start an activity successfully, but this activity just
brings another activity to front without actual launching, the waiting
will be stuck because neither activity will report launch complete.
In this case, we have to treat it as if the -W started an activity and
received return code START_TASK_TO_FRONT. It needs to wait for the new
activity to become visible (or report launch complete if it's already
visible).
This reverts earlier commits afb776d5447e19565c9a826a554911decb9ed92a,
since it's causing problems with launch time reporting.
bug: 28333487
bug: 29451567
Change-Id: I9fd79ab5b3ed8f9de5df34ed9c7b0be3a94620b2
5 files changed, 36 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 6510cb4928d5..50b6c0c7502f 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1157,13 +1157,6 @@ 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); } @@ -1229,22 +1222,13 @@ 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(curTime); + reportLaunchTimeLocked(SystemClock.uptimeMillis()); } 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 fe1df1f7ffa3..a5c34e208583 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -933,9 +933,6 @@ 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; @@ -950,9 +947,6 @@ 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); @@ -1407,6 +1401,7 @@ final class ActivityStack { if (next.nowVisible) { // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. + mStackSupervisor.reportActivityVisibleLocked(next); mStackSupervisor.notifyActivityDrawnForKeyguard(); } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 97bfeaf14ca5..033471c77a11 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -111,6 +111,7 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; import static android.app.ActivityManager.RESIZE_MODE_FORCED; import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; +import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID; @@ -1002,6 +1003,24 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + void reportTaskToFrontNoLaunch(ActivityRecord r) { + boolean changed = false; + for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { + WaitResult w = mWaitingActivityLaunched.remove(i); + if (w.who == null) { + changed = true; + // Set result to START_TASK_TO_FRONT so that startActivityMayWait() knows that + // the starting activity ends up moving another activity to front, and it should + // wait for this new activity to become visible instead. + // Do not modify other fields. + w.result = START_TASK_TO_FRONT; + } + } + if (changed) { + mService.notifyAll(); + } + } + void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long thisTime, long totalTime) { boolean changed = false; @@ -1015,6 +1034,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } w.thisTime = thisTime; w.totalTime = totalTime; + // Do not modify w.result. } } if (changed) { diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 9c1c1cacba20..234a46735865 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -553,6 +553,13 @@ class ActivityStarter { return; } + // We're waiting for an activity launch to finish, but that activity simply + // brought another activity to front. Let startActivityMayWait() know about + // this, so it waits for the new activity to become visible instead. + if (result == START_TASK_TO_FRONT && !mSupervisor.mWaitingActivityLaunched.isEmpty()) { + mSupervisor.reportTaskToFrontNoLaunch(mStartActivity); + } + int startedActivityStackId = INVALID_STACK_ID; if (r.task != null && r.task.stack != null) { startedActivityStackId = r.task.stack.mStackId; @@ -840,8 +847,13 @@ class ActivityStarter { mService.wait(); } catch (InterruptedException e) { } - } while (!outResult.timeout && outResult.who == null); - } else if (res == START_TASK_TO_FRONT) { + } while (outResult.result != START_TASK_TO_FRONT + && !outResult.timeout && outResult.who == null); + if (outResult.result == START_TASK_TO_FRONT) { + res = START_TASK_TO_FRONT; + } + } + if (res == START_TASK_TO_FRONT) { ActivityRecord r = stack.topRunningActivityLocked(); if (r.nowVisible && r.state == RESUMED) { outResult.timeout = false; diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index c84aaacd8aff..3f6db990a5b5 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -154,7 +154,6 @@ 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 |