diff options
| author | 2015-12-17 17:15:29 -0800 | |
|---|---|---|
| committer | 2015-12-17 17:31:27 -0800 | |
| commit | 393819709787326a38cde883493ebf04fe62bd8b (patch) | |
| tree | 20fa8565f39ff628b29dbc823c5402ea785882a8 | |
| parent | 92e432c30e2304272c2f5b1b33366f32c3d763cf (diff) | |
Fixed some issues with tasks with the same affinity in different stacks
- It is possible for tasks in different stacks to have the same root
affinity. This can be an issue when we are looking for the best task to
launch an acitivty into since there can be a better match in a different
stack based on class name. We now save the task matched by root afinity
and try to find a better match by class name. If we don't find a better
match we use the match based on root affinity.
- For pinned stack we don't allow root affinity matching as no other
task should be launching in the stack based on affinity.
- Correct ASS#moveActivityToStackLocked to use the passed in stack id
instead of the PINNED_STACK_ID.
Bug: 26015860
Change-Id: I6ec44bc97bf3c669c2305a58563518cf9bfc7804
3 files changed, 42 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index bfd17b2e1bf9..52f32e82591d 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -28,6 +28,7 @@ import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN; import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; +import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.MOVING; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; @@ -569,10 +570,10 @@ final class ActivityStack { } /** - * Returns the top activity in any existing task matching the given - * Intent. Returns null if no such task is found. + * Returns the top activity in any existing task matching the given Intent in the input result. + * Returns null if no such task is found. */ - ActivityRecord findTaskLocked(ActivityRecord target) { + void findTaskLocked(ActivityRecord target, FindTaskResult result) { Intent intent = target.intent; ActivityInfo info = target.info; ComponentName cls = intent.getComponent(); @@ -627,10 +628,15 @@ final class ActivityStack { + taskIntent.getComponent().flattenToShortString() + "/aff=" + r.task.rootAffinity + " to new cls=" + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); - if (!isDocument && !taskIsDocument && task.rootAffinity != null) { + if (!isDocument && !taskIsDocument + && result.r == null && task.canMatchRootAffinity()) { if (task.rootAffinity.equals(target.taskAffinity)) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity!"); - return r; + if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!"); + // It is possible for multiple tasks to have the same root affinity especially + // if they are in separate stacks. We save off this candidate, but keep looking + // to see if there is a better candidate. + result.r = r; + result.matchedByRootAffinity = true; } } else if (taskIntent != null && taskIntent.getComponent() != null && taskIntent.getComponent().compareTo(cls) == 0 && @@ -639,7 +645,9 @@ final class ActivityStack { //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); - return r; + result.r = r; + result.matchedByRootAffinity = false; + break; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { @@ -647,11 +655,11 @@ final class ActivityStack { //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); - return r; + result.r = r; + result.matchedByRootAffinity = false; + break; } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); } - - return null; } /** diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 80d531e71f3e..2d5f76c2c2e2 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -418,6 +418,12 @@ public final class ActivityStackSupervisor implements DisplayListener { private final ActivityMetricsLogger mActivityMetricsLogger; + static class FindTaskResult { + ActivityRecord r; + boolean matchedByRootAffinity; + } + private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); + /** * Description of a request to start a new activity, which has been held * due to app switches being disabled. @@ -3640,7 +3646,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } if (bounds != null) { - resizeStackLocked(PINNED_STACK_ID, bounds, !PRESERVE_WINDOWS, true); + resizeStackLocked(stackId, bounds, !PRESERVE_WINDOWS, true); } // The task might have already been running and its visibility needs to be synchronized with @@ -3669,6 +3675,8 @@ public final class ActivityStackSupervisor implements DisplayListener { } ActivityRecord findTaskLocked(ActivityRecord r) { + mTmpFindTaskResult.r = null; + mTmpFindTaskResult.matchedByRootAffinity = false; if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; @@ -3683,14 +3691,18 @@ public final class ActivityStackSupervisor implements DisplayListener { "Skipping stack: (new task not allowed) " + stack); continue; } - final ActivityRecord ar = stack.findTaskLocked(r); - if (ar != null) { - return ar; + stack.findTaskLocked(r, mTmpFindTaskResult); + // It is possible to have task in multiple stacks with the same root affinity. + // If the match we found was based on root affinity we keep on looking to see if + // there is a better match in another stack. We eventually return the match based + // on root affinity if we don't find a better match. + if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) { + return mTmpFindTaskResult.r; } } } - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "No task found"); - return null; + if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found"); + return mTmpFindTaskResult.r; } ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 5ee9eea48e33..4647d77bef89 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1394,6 +1394,12 @@ final class TaskRecord { return mLastNonFullscreenBounds; } + boolean canMatchRootAffinity() { + // We don't allow root affinity matching on the pinned stack as no other task should + // be launching in it based on affinity. + return rootAffinity != null && (stack == null || stack.mStackId != PINNED_STACK_ID); + } + void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("userId="); pw.print(userId); pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid); |