Loading services/core/java/com/android/server/am/ActivityDisplay.java +40 −0 Original line number Diff line number Diff line Loading @@ -39,10 +39,13 @@ import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY; import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.TAG_STATES; import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS; import android.annotation.Nullable; import android.app.ActivityOptions; Loading Loading @@ -121,6 +124,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> private DisplayWindowController mWindowContainerController; private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); @VisibleForTesting ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) { this(supervisor, supervisor.mDisplayManager.getDisplay(displayId)); Loading Loading @@ -445,6 +450,41 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> return someActivityPaused; } /** * Find task for putting the Activity in. */ void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay, FindTaskResult result) { mTmpFindTaskResult.clear(); for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = getChildAt(stackNdx); if (!r.hasCompatibleActivityType(stack)) { if (DEBUG_TASKS) { Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); } continue; } stack.findTaskLocked(r, mTmpFindTaskResult); // It is possible to have tasks in multiple stacks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a // better match in another stack. Also, task affinity isn't a good enough reason // to target a display which isn't the source of the intent, so skip any affinity // matches not on the specified display. if (mTmpFindTaskResult.mRecord != null) { if (mTmpFindTaskResult.mIdealMatch) { result.setTo(mTmpFindTaskResult); return; } else if (isPreferredDisplay) { // Note: since the traversing through the stacks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen stacks result.setTo(mTmpFindTaskResult); } } } } /** * Removes stacks in the input windowing modes from the system if they are of activity type * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED Loading services/core/java/com/android/server/am/ActivityStack.java +7 −7 Original line number Diff line number Diff line Loading @@ -1176,8 +1176,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); result.r = r; result.matchedByRootAffinity = false; result.mRecord = r; result.mIdealMatch = true; break; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Loading @@ -1186,18 +1186,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); result.r = r; result.matchedByRootAffinity = false; result.mRecord = r; result.mIdealMatch = true; break; } else if (!isDocument && !taskIsDocument && result.r == null && task.rootAffinity != null) { && result.mRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(target.taskAffinity)) { 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; result.mRecord = r; result.mIdealMatch = false; } } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); } Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +34 −34 Original line number Diff line number Diff line Loading @@ -533,9 +533,20 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } static class FindTaskResult { ActivityRecord r; boolean matchedByRootAffinity; ActivityRecord mRecord; boolean mIdealMatch; void clear() { mRecord = null; mIdealMatch = false; } void setTo(FindTaskResult result) { mRecord = result.mRecord; mIdealMatch = result.mIdealMatch; } } private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); /** Loading Loading @@ -3459,44 +3470,33 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return true; } ActivityRecord findTaskLocked(ActivityRecord r, int displayId) { mTmpFindTaskResult.r = null; mTmpFindTaskResult.matchedByRootAffinity = false; ActivityRecord affinityMatch = null; ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); mTmpFindTaskResult.clear(); // Looking up task on preferred display first final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId); if (preferredDisplay != null) { preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; } } for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.get(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); if (!r.hasCompatibleActivityType(stack)) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); if (display.mDisplayId == preferredDisplayId) { continue; } stack.findTaskLocked(r, mTmpFindTaskResult); // It is possible to have tasks in multiple stacks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a // better match in another stack. Also, task affinity isn't a good enough reason // to target a display which isn't the source of the intent, so skip any affinity // matches not on the specified display. if (mTmpFindTaskResult.r != null) { if (!mTmpFindTaskResult.matchedByRootAffinity) { return mTmpFindTaskResult.r; } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) { // Note: since the traversing through the stacks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen stacks affinityMatch = mTmpFindTaskResult.r; } else if (DEBUG_TASKS && mTmpFindTaskResult.matchedByRootAffinity) { Slog.d(TAG_TASKS, "Skipping match on different display " + mTmpFindTaskResult.r.getDisplayId() + " " + displayId); } } display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; } } if (DEBUG_TASKS && affinityMatch == null) Slog.d(TAG_TASKS, "No task found"); return affinityMatch; if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); return mTmpFindTaskResult.mRecord; } ActivityRecord findActivityLocked(Intent intent, ActivityInfo info, Loading services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -189,7 +189,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(task.getTopActivity(false /* includeOverlays */), r); assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay); assertNotNull(result.r); assertNotNull(result.mRecord); } @Test Loading Loading
services/core/java/com/android/server/am/ActivityDisplay.java +40 −0 Original line number Diff line number Diff line Loading @@ -39,10 +39,13 @@ import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY; import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.TAG_STATES; import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS; import android.annotation.Nullable; import android.app.ActivityOptions; Loading Loading @@ -121,6 +124,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> private DisplayWindowController mWindowContainerController; private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); @VisibleForTesting ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) { this(supervisor, supervisor.mDisplayManager.getDisplay(displayId)); Loading Loading @@ -445,6 +450,41 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> return someActivityPaused; } /** * Find task for putting the Activity in. */ void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay, FindTaskResult result) { mTmpFindTaskResult.clear(); for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = getChildAt(stackNdx); if (!r.hasCompatibleActivityType(stack)) { if (DEBUG_TASKS) { Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); } continue; } stack.findTaskLocked(r, mTmpFindTaskResult); // It is possible to have tasks in multiple stacks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a // better match in another stack. Also, task affinity isn't a good enough reason // to target a display which isn't the source of the intent, so skip any affinity // matches not on the specified display. if (mTmpFindTaskResult.mRecord != null) { if (mTmpFindTaskResult.mIdealMatch) { result.setTo(mTmpFindTaskResult); return; } else if (isPreferredDisplay) { // Note: since the traversing through the stacks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen stacks result.setTo(mTmpFindTaskResult); } } } } /** * Removes stacks in the input windowing modes from the system if they are of activity type * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED Loading
services/core/java/com/android/server/am/ActivityStack.java +7 −7 Original line number Diff line number Diff line Loading @@ -1176,8 +1176,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); result.r = r; result.matchedByRootAffinity = false; result.mRecord = r; result.mIdealMatch = true; break; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Loading @@ -1186,18 +1186,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai //dump(); if (DEBUG_TASKS) Slog.d(TAG_TASKS, "For Intent " + intent + " bringing to top: " + r.intent); result.r = r; result.matchedByRootAffinity = false; result.mRecord = r; result.mIdealMatch = true; break; } else if (!isDocument && !taskIsDocument && result.r == null && task.rootAffinity != null) { && result.mRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(target.taskAffinity)) { 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; result.mRecord = r; result.mIdealMatch = false; } } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); } Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +34 −34 Original line number Diff line number Diff line Loading @@ -533,9 +533,20 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } static class FindTaskResult { ActivityRecord r; boolean matchedByRootAffinity; ActivityRecord mRecord; boolean mIdealMatch; void clear() { mRecord = null; mIdealMatch = false; } void setTo(FindTaskResult result) { mRecord = result.mRecord; mIdealMatch = result.mIdealMatch; } } private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); /** Loading Loading @@ -3459,44 +3470,33 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return true; } ActivityRecord findTaskLocked(ActivityRecord r, int displayId) { mTmpFindTaskResult.r = null; mTmpFindTaskResult.matchedByRootAffinity = false; ActivityRecord affinityMatch = null; ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); mTmpFindTaskResult.clear(); // Looking up task on preferred display first final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId); if (preferredDisplay != null) { preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; } } for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.get(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); if (!r.hasCompatibleActivityType(stack)) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); if (display.mDisplayId == preferredDisplayId) { continue; } stack.findTaskLocked(r, mTmpFindTaskResult); // It is possible to have tasks in multiple stacks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a // better match in another stack. Also, task affinity isn't a good enough reason // to target a display which isn't the source of the intent, so skip any affinity // matches not on the specified display. if (mTmpFindTaskResult.r != null) { if (!mTmpFindTaskResult.matchedByRootAffinity) { return mTmpFindTaskResult.r; } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) { // Note: since the traversing through the stacks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen stacks affinityMatch = mTmpFindTaskResult.r; } else if (DEBUG_TASKS && mTmpFindTaskResult.matchedByRootAffinity) { Slog.d(TAG_TASKS, "Skipping match on different display " + mTmpFindTaskResult.r.getDisplayId() + " " + displayId); } } display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; } } if (DEBUG_TASKS && affinityMatch == null) Slog.d(TAG_TASKS, "No task found"); return affinityMatch; if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); return mTmpFindTaskResult.mRecord; } ActivityRecord findActivityLocked(Intent intent, ActivityInfo info, Loading
services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -189,7 +189,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(task.getTopActivity(false /* includeOverlays */), r); assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay); assertNotNull(result.r); assertNotNull(result.mRecord); } @Test Loading