summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wale Ogunwale <ogunwale@google.com> 2015-03-13 10:26:26 -0700
committer Wale Ogunwale <ogunwale@google.com> 2015-03-13 15:12:24 -0700
commitd80c263e2a45f0a2b65fd9762aa8deea49c8ca72 (patch)
treeec00523f9f6b7555a4d76a0092365ba98ec2d99f
parent4011e209215d19a1633ed5d1643f3b7643001667 (diff)
Remove duplicate move of home stack that can cause animation jank.
Each move of the home stack in the ActivityManager ends up calling into the WindowManager which causes layout to be performed. Also, fixed issue where ActivityStack.moveTaskToFrontLocked() could move a task to the front without the focus been adjusted to the new top activity. Bug: 19692494 Change-Id: Ib4c999c6dfa1af3fda0fced52b58da614b154d00
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java15
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java57
3 files changed, 47 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e7952c1a9b60..1766fb246816 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2468,7 +2468,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
final void setFocusedActivityLocked(ActivityRecord r, String reason) {
- if (mFocusedActivity != r) {
+ if (r != null && mFocusedActivity != r) {
if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
mFocusedActivity = r;
if (r.task != null && r.task.voiceInteractor != null) {
@@ -2476,7 +2476,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} else {
finishRunningVoiceLocked();
}
- if (r != null && mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
+ if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
mWindowManager.setFocusedApp(r.appToken, true);
}
applyUpdateLockStateLocked(r);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 8a7e3d3c2c5e..62c18a8d2885 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -507,6 +507,8 @@ final class ActivityStack {
mStacks.remove(this);
mStacks.add(this);
}
+ // TODO(multi-display): Focus stack currently adjusted in call to move home stack.
+ // Needs to also work if focus is moving to the non-home display.
if (isOnHomeDisplay()) {
mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);
}
@@ -2570,7 +2572,11 @@ final class ActivityStack {
}
// Move the home stack to the top if this stack is fullscreen or there is no
// other visible stack.
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), myReason);
+ if (mStackSupervisor.moveHomeStackTaskToTop(
+ task.getTaskToReturnTo(), myReason)) {
+ // Activity focus was already adjusted. Nothing else to do...
+ return;
+ }
}
}
@@ -3572,7 +3578,6 @@ final class ActivityStack {
mTaskHistory.remove(taskNdx);
mTaskHistory.add(top, task);
updateTaskMovement(task, true);
- mWindowManager.moveTaskToTop(task.taskId);
return;
}
}
@@ -3597,12 +3602,14 @@ final class ActivityStack {
// Shift all activities with this task up to the top
// of the stack, keeping them in the same internal order.
insertTaskAtTop(tr);
- moveToFront(reason);
+
+ // Set focus to the top running activity of this stack.
+ ActivityRecord r = topRunningActivityLocked(null);
+ mService.setFocusedActivityLocked(r, reason);
if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
if (noAnimation) {
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
- ActivityRecord r = topRunningActivityLocked(null);
if (r != null) {
mNoAnimActivities.add(r);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index cbbb11a8dfb3..8c0c2e3ee9b3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,6 +17,8 @@
package com.android.server.am;
import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -441,13 +443,21 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
- void moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
+ /** Returns true if the focus activity was adjusted to the home stack top activity. */
+ boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
mWindowManager.showRecentApps();
- return;
+ return false;
}
- moveHomeStack(true, reason);
+
mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+
+ final ActivityRecord top = mHomeStack.topRunningActivityLocked(null);
+ if (top == null) {
+ return false;
+ }
+ mService.setFocusedActivityLocked(top, reason);
+ return true;
}
boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
@@ -460,14 +470,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
mWindowManager.showRecentApps();
return false;
}
- moveHomeStackTaskToTop(homeStackTaskType, reason);
+
if (prev != null) {
prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
}
ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
- // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
- if (r != null && r.isHomeActivity()) {
+ if (r != null) {
mService.setFocusedActivityLocked(r, reason);
return resumeTopActivitiesLocked(mHomeStack, prev, null);
}
@@ -1874,11 +1883,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
if (r.task == null) {
r.task = intentActivity.task;
}
- targetStack = intentActivity.task.stack;
- targetStack.mLastPausedActivity = null;
- if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
- + " from " + intentActivity);
- targetStack.moveToFront("intentActivityFound");
if (intentActivity.task.intent == null) {
// This task was started because of movement of
// the activity based on affinity... now that we
@@ -1886,29 +1890,31 @@ public final class ActivityStackSupervisor implements DisplayListener {
// base intent.
intentActivity.task.setIntent(r);
}
+ targetStack = intentActivity.task.stack;
+ targetStack.mLastPausedActivity = null;
// If the target task is not in the front, then we need
// to bring it to the front... except... well, with
// SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
// to have the same behavior as if a new instance was
// being started, which means not bringing it to the front
// if the caller is not itself in the front.
- final ActivityStack lastStack = getLastStack();
- ActivityRecord curTop = lastStack == null?
- null : lastStack.topRunningNonDelayedActivityLocked(notTop);
+ final ActivityStack focusStack = getFocusedStack();
+ ActivityRecord curTop = (focusStack == null)
+ ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
boolean movedToFront = false;
if (curTop != null && (curTop.task != intentActivity.task ||
- curTop.task != lastStack.topTask())) {
+ curTop.task != focusStack.topTask())) {
r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
if (sourceRecord == null || (sourceStack.topActivity() != null &&
sourceStack.topActivity().task == sourceRecord.task)) {
- // We really do want to push this one into the
- // user's face, right now.
+ // We really do want to push this one into the user's face, right now.
if (launchTaskBehind && sourceRecord != null) {
intentActivity.setTaskToAffiliateWith(sourceRecord.task);
}
movedHome = true;
targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
options, "bringingFoundTaskToFront");
+ movedToFront = true;
if ((launchFlags &
(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
@@ -1916,9 +1922,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
}
options = null;
- movedToFront = true;
}
}
+ if (!movedToFront) {
+ if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
+ + " from " + intentActivity);
+ targetStack.moveToFront("intentActivityFound");
+ }
+
// If the caller has requested that the target task be
// reset, then do so.
if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
@@ -1943,15 +1954,15 @@ public final class ActivityStackSupervisor implements DisplayListener {
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
if ((launchFlags &
- (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
- == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
+ (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+ == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
// The caller has requested to completely replace any
// existing task with its new activity. Well that should
// not be too hard...
reuseTask = intentActivity.task;
reuseTask.performClearTaskLocked();
reuseTask.setIntent(r);
- } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
+ } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| launchSingleInstance || launchSingleTask) {
// In this situation we want to remove all activities
// from the task up to the one being started. In most
@@ -2120,8 +2131,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
if (!movedHome) {
if ((launchFlags &
- (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
- == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
+ (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
+ == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity, so before starting
// their own activity we will bring home to the front.
r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);