Loading data/etc/services.core.protolog.json +12 −6 Original line number Diff line number Diff line Loading @@ -49,12 +49,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-2062338592": { "message": "Looking for task of %s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-2054442123": { "message": "Setting Intent of %s to %s", "level": "VERBOSE", Loading Loading @@ -475,6 +469,12 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "-1559645910": { "message": "Looking for task of type=%s, taskAffinity=%s, intent=%s, info=%s, preferredTDA=%s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-1558137010": { "message": "Config is relaunching invisible activity %s called by %s", "level": "VERBOSE", Loading Loading @@ -1531,6 +1531,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "-373110070": { "message": "Skipping task: (mismatch activity\/task) %s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-354571697": { "message": "Existence Changed in transition %d: %s", "level": "VERBOSE", Loading services/core/java/com/android/server/wm/ConfigurationContainer.java +4 −7 Original line number Diff line number Diff line Loading @@ -547,19 +547,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { return activityType == ACTIVITY_TYPE_STANDARD || activityType == ACTIVITY_TYPE_UNDEFINED; } public boolean hasCompatibleActivityType(ConfigurationContainer other) { /*@WindowConfiguration.ActivityType*/ int thisType = getActivityType(); /*@WindowConfiguration.ActivityType*/ int otherType = other.getActivityType(); if (thisType == otherType) { public static boolean isCompatibleActivityType(int currentType, int otherType) { if (currentType == otherType) { return true; } if (thisType == ACTIVITY_TYPE_ASSISTANT) { if (currentType == ACTIVITY_TYPE_ASSISTANT) { // Assistant activities are only compatible with themselves... return false; } // Otherwise we are compatible if us or other is not currently defined. return thisType == ACTIVITY_TYPE_UNDEFINED || otherType == ACTIVITY_TYPE_UNDEFINED; return currentType == ACTIVITY_TYPE_UNDEFINED || otherType == ACTIVITY_TYPE_UNDEFINED; } /** Loading services/core/java/com/android/server/wm/RootWindowContainer.java +66 −55 Original line number Diff line number Diff line Loading @@ -306,52 +306,54 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); static class FindTaskResult implements Function<Task, Boolean> { ActivityRecord mRecord; boolean mIdealMatch; ActivityRecord mIdealRecord; ActivityRecord mCandidateRecord; private ActivityRecord mTarget; private Intent intent; private ActivityInfo info; private int mActivityType; private String mTaskAffinity; private Intent mIntent; private ActivityInfo mInfo; private ComponentName cls; private int userId; private boolean isDocument; private Uri documentData; void init(int activityType, String taskAffinity, Intent intent, ActivityInfo info) { mActivityType = activityType; mTaskAffinity = taskAffinity; mIntent = intent; mInfo = info; mIdealRecord = null; mCandidateRecord = null; } /** * Returns the top activity in any existing task matching the given Intent in the input * result. Returns null if no such task is found. */ void process(ActivityRecord target, Task parent) { mTarget = target; intent = target.intent; info = target.info; cls = intent.getComponent(); if (info.targetActivity != null) { cls = new ComponentName(info.packageName, info.targetActivity); void process(WindowContainer parent) { cls = mIntent.getComponent(); if (mInfo.targetActivity != null) { cls = new ComponentName(mInfo.packageName, mInfo.targetActivity); } userId = UserHandle.getUserId(info.applicationInfo.uid); isDocument = intent != null & intent.isDocument(); userId = UserHandle.getUserId(mInfo.applicationInfo.uid); isDocument = mIntent != null & mIntent.isDocument(); // If documentData is non-null then it must match the existing task data. documentData = isDocument ? intent.getData() : null; documentData = isDocument ? mIntent.getData() : null; ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", target, ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", mInfo, parent); parent.forAllLeafTasks(this); } void clear() { mRecord = null; mIdealMatch = false; } void setTo(FindTaskResult result) { mRecord = result.mRecord; mIdealMatch = result.mIdealMatch; } @Override public Boolean apply(Task task) { if (!ConfigurationContainer.isCompatibleActivityType(mActivityType, task.getActivityType())) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping task: (mismatch activity/task) %s", task); return false; } if (task.voiceSession != null) { // We never match voice sessions; those always run independently. ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: voice session", task); Loading @@ -370,7 +372,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch root %s", task, r); return false; } if (!r.hasCompatibleActivityType(mTarget)) { if (!ConfigurationContainer.isCompatibleActivityType(r.getActivityType(), mActivityType)) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch activity type", task); return false; } Loading @@ -391,35 +394,33 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s", r.getTask().rootAffinity, intent.getComponent().flattenToShortString(), info.taskAffinity, (task.realActivity != null r.getTask().rootAffinity, mIntent.getComponent().flattenToShortString(), mInfo.taskAffinity, (task.realActivity != null ? task.realActivity.flattenToShortString() : "")); // TODO Refactor to remove duplications. Check if logic can be simplified. if (task.realActivity != null && task.realActivity.compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); //dump(); ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent); mIdealRecord = r; return true; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent); mIdealRecord = r; return true; } else if (!isDocument && !taskIsDocument && mRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(mTarget.taskAffinity)) { && mIdealRecord == null && mCandidateRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(mTaskAffinity)) { ProtoLog.d(WM_DEBUG_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. mRecord = r; mIdealMatch = false; mCandidateRecord = r; } } else { ProtoLog.d(WM_DEBUG_TASKS, "Not a match: %s", task); Loading Loading @@ -2238,38 +2239,48 @@ class RootWindowContainer extends WindowContainer<DisplayContent> @Nullable ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) { ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s", r); mTmpFindTaskResult.clear(); return findTask(r.getActivityType(), r.taskAffinity, r.intent, r.info, preferredTaskDisplayArea); } @Nullable ActivityRecord findTask(int activityType, String taskAffinity, Intent intent, ActivityInfo info, TaskDisplayArea preferredTaskDisplayArea) { ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of type=%s, taskAffinity=%s, intent=%s" + ", info=%s, preferredTDA=%s", activityType, taskAffinity, intent, info, preferredTaskDisplayArea); mTmpFindTaskResult.init(activityType, taskAffinity, intent, info); // Looking up task on preferred display area first ActivityRecord candidateActivity = null; if (preferredTaskDisplayArea != null) { preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; mTmpFindTaskResult.process(preferredTaskDisplayArea); if (mTmpFindTaskResult.mIdealRecord != null) { return mTmpFindTaskResult.mIdealRecord; } else if (mTmpFindTaskResult.mCandidateRecord != null) { candidateActivity = mTmpFindTaskResult.mCandidateRecord; } } final ActivityRecord task = getItemFromTaskDisplayAreas(taskDisplayArea -> { final ActivityRecord idealMatchActivity = getItemFromTaskDisplayAreas(taskDisplayArea -> { if (taskDisplayArea == preferredTaskDisplayArea) { return null; } taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; mTmpFindTaskResult.process(taskDisplayArea); if (mTmpFindTaskResult.mIdealRecord != null) { return mTmpFindTaskResult.mIdealRecord; } return null; }); if (task != null) { return task; if (idealMatchActivity != null) { return idealMatchActivity; } if (WM_DEBUG_TASKS.isEnabled() && mTmpFindTaskResult.mRecord == null) { if (WM_DEBUG_TASKS.isEnabled() && candidateActivity == null) { ProtoLog.d(WM_DEBUG_TASKS, "No task found"); } return mTmpFindTaskResult.mRecord; return candidateActivity; } /** Loading services/core/java/com/android/server/wm/TaskDisplayArea.java +0 −41 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK; import static com.android.server.wm.DisplayContent.alwaysCreateRootTask; import static com.android.server.wm.Task.ActivityState.RESUMED; Loading Loading @@ -128,9 +127,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { */ Task mPreferredTopFocusableRootTask; private final RootWindowContainer.FindTaskResult mTmpFindTaskResult = new RootWindowContainer.FindTaskResult(); /** * If this is the same as {@link #getFocusedRootTask} then the activity on the top of the * focused root task has been resumed. If root tasks are changing position this will hold the Loading Loading @@ -1312,43 +1308,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { return someActivityPaused[0] > 0; } /** * Find task for putting the Activity in. */ void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplayArea, RootWindowContainer.FindTaskResult result) { mTmpFindTaskResult.clear(); for (int i = mChildren.size() - 1; i >= 0; --i) { final Task rootTask = mChildren.get(i).asTask(); if (rootTask == null) { continue; } if (!r.hasCompatibleActivityType(rootTask) && rootTask.isLeafTask()) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping rootTask: (mismatch activity/rootTask) " + "%s", rootTask); continue; } mTmpFindTaskResult.process(r, rootTask); // It is possible to have tasks in multiple root tasks 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 root task. 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 (isPreferredDisplayArea) { // Note: since the traversing through the root tasks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen root tasks result.setTo(mTmpFindTaskResult); } } } } void onSplitScreenModeDismissed() { // The focused task could be a non-resizeable fullscreen root task that is on top of the // other split-screen tasks, therefore had to dismiss split-screen, make sure the current Loading services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +9 −6 Original line number Diff line number Diff line Loading @@ -314,11 +314,12 @@ public class ActivityStackTests extends WindowTestsBase { final RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult(); result.process(r, task); result.init(r.getActivityType(), r.taskAffinity, r.intent, r.info); result.process(task); assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */)); assertEquals(taskOverlay, task.getTopNonFinishingActivity(true /* includeOverlays */)); assertNotNull(result.mRecord); assertNotNull(result.mIdealRecord); } @Test Loading @@ -340,15 +341,17 @@ public class ActivityStackTests extends WindowTestsBase { final ActivityRecord r1 = new ActivityBuilder(mAtm).setComponent( target).setTargetActivity(targetActivity).build(); RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult(); result.process(r1, parentTask); assertThat(result.mRecord).isNotNull(); result.init(r1.getActivityType(), r1.taskAffinity, r1.intent, r1.info); result.process(parentTask); assertThat(result.mIdealRecord).isNotNull(); // Using alias activity to find task. final ActivityRecord r2 = new ActivityBuilder(mAtm).setComponent( alias).setTargetActivity(targetActivity).build(); result = new RootWindowContainer.FindTaskResult(); result.process(r2, parentTask); assertThat(result.mRecord).isNotNull(); result.init(r2.getActivityType(), r2.taskAffinity, r2.intent, r2.info); result.process(parentTask); assertThat(result.mIdealRecord).isNotNull(); } @Test Loading Loading
data/etc/services.core.protolog.json +12 −6 Original line number Diff line number Diff line Loading @@ -49,12 +49,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-2062338592": { "message": "Looking for task of %s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-2054442123": { "message": "Setting Intent of %s to %s", "level": "VERBOSE", Loading Loading @@ -475,6 +469,12 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "-1559645910": { "message": "Looking for task of type=%s, taskAffinity=%s, intent=%s, info=%s, preferredTDA=%s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-1558137010": { "message": "Config is relaunching invisible activity %s called by %s", "level": "VERBOSE", Loading Loading @@ -1531,6 +1531,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "-373110070": { "message": "Skipping task: (mismatch activity\/task) %s", "level": "DEBUG", "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, "-354571697": { "message": "Existence Changed in transition %d: %s", "level": "VERBOSE", Loading
services/core/java/com/android/server/wm/ConfigurationContainer.java +4 −7 Original line number Diff line number Diff line Loading @@ -547,19 +547,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { return activityType == ACTIVITY_TYPE_STANDARD || activityType == ACTIVITY_TYPE_UNDEFINED; } public boolean hasCompatibleActivityType(ConfigurationContainer other) { /*@WindowConfiguration.ActivityType*/ int thisType = getActivityType(); /*@WindowConfiguration.ActivityType*/ int otherType = other.getActivityType(); if (thisType == otherType) { public static boolean isCompatibleActivityType(int currentType, int otherType) { if (currentType == otherType) { return true; } if (thisType == ACTIVITY_TYPE_ASSISTANT) { if (currentType == ACTIVITY_TYPE_ASSISTANT) { // Assistant activities are only compatible with themselves... return false; } // Otherwise we are compatible if us or other is not currently defined. return thisType == ACTIVITY_TYPE_UNDEFINED || otherType == ACTIVITY_TYPE_UNDEFINED; return currentType == ACTIVITY_TYPE_UNDEFINED || otherType == ACTIVITY_TYPE_UNDEFINED; } /** Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +66 −55 Original line number Diff line number Diff line Loading @@ -306,52 +306,54 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); static class FindTaskResult implements Function<Task, Boolean> { ActivityRecord mRecord; boolean mIdealMatch; ActivityRecord mIdealRecord; ActivityRecord mCandidateRecord; private ActivityRecord mTarget; private Intent intent; private ActivityInfo info; private int mActivityType; private String mTaskAffinity; private Intent mIntent; private ActivityInfo mInfo; private ComponentName cls; private int userId; private boolean isDocument; private Uri documentData; void init(int activityType, String taskAffinity, Intent intent, ActivityInfo info) { mActivityType = activityType; mTaskAffinity = taskAffinity; mIntent = intent; mInfo = info; mIdealRecord = null; mCandidateRecord = null; } /** * Returns the top activity in any existing task matching the given Intent in the input * result. Returns null if no such task is found. */ void process(ActivityRecord target, Task parent) { mTarget = target; intent = target.intent; info = target.info; cls = intent.getComponent(); if (info.targetActivity != null) { cls = new ComponentName(info.packageName, info.targetActivity); void process(WindowContainer parent) { cls = mIntent.getComponent(); if (mInfo.targetActivity != null) { cls = new ComponentName(mInfo.packageName, mInfo.targetActivity); } userId = UserHandle.getUserId(info.applicationInfo.uid); isDocument = intent != null & intent.isDocument(); userId = UserHandle.getUserId(mInfo.applicationInfo.uid); isDocument = mIntent != null & mIntent.isDocument(); // If documentData is non-null then it must match the existing task data. documentData = isDocument ? intent.getData() : null; documentData = isDocument ? mIntent.getData() : null; ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", target, ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", mInfo, parent); parent.forAllLeafTasks(this); } void clear() { mRecord = null; mIdealMatch = false; } void setTo(FindTaskResult result) { mRecord = result.mRecord; mIdealMatch = result.mIdealMatch; } @Override public Boolean apply(Task task) { if (!ConfigurationContainer.isCompatibleActivityType(mActivityType, task.getActivityType())) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping task: (mismatch activity/task) %s", task); return false; } if (task.voiceSession != null) { // We never match voice sessions; those always run independently. ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: voice session", task); Loading @@ -370,7 +372,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch root %s", task, r); return false; } if (!r.hasCompatibleActivityType(mTarget)) { if (!ConfigurationContainer.isCompatibleActivityType(r.getActivityType(), mActivityType)) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch activity type", task); return false; } Loading @@ -391,35 +394,33 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s", r.getTask().rootAffinity, intent.getComponent().flattenToShortString(), info.taskAffinity, (task.realActivity != null r.getTask().rootAffinity, mIntent.getComponent().flattenToShortString(), mInfo.taskAffinity, (task.realActivity != null ? task.realActivity.flattenToShortString() : "")); // TODO Refactor to remove duplications. Check if logic can be simplified. if (task.realActivity != null && task.realActivity.compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); //dump(); ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent); mIdealRecord = r; return true; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", mIntent, r.intent); mIdealRecord = r; return true; } else if (!isDocument && !taskIsDocument && mRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(mTarget.taskAffinity)) { && mIdealRecord == null && mCandidateRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(mTaskAffinity)) { ProtoLog.d(WM_DEBUG_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. mRecord = r; mIdealMatch = false; mCandidateRecord = r; } } else { ProtoLog.d(WM_DEBUG_TASKS, "Not a match: %s", task); Loading Loading @@ -2238,38 +2239,48 @@ class RootWindowContainer extends WindowContainer<DisplayContent> @Nullable ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) { ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s", r); mTmpFindTaskResult.clear(); return findTask(r.getActivityType(), r.taskAffinity, r.intent, r.info, preferredTaskDisplayArea); } @Nullable ActivityRecord findTask(int activityType, String taskAffinity, Intent intent, ActivityInfo info, TaskDisplayArea preferredTaskDisplayArea) { ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of type=%s, taskAffinity=%s, intent=%s" + ", info=%s, preferredTDA=%s", activityType, taskAffinity, intent, info, preferredTaskDisplayArea); mTmpFindTaskResult.init(activityType, taskAffinity, intent, info); // Looking up task on preferred display area first ActivityRecord candidateActivity = null; if (preferredTaskDisplayArea != null) { preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; mTmpFindTaskResult.process(preferredTaskDisplayArea); if (mTmpFindTaskResult.mIdealRecord != null) { return mTmpFindTaskResult.mIdealRecord; } else if (mTmpFindTaskResult.mCandidateRecord != null) { candidateActivity = mTmpFindTaskResult.mCandidateRecord; } } final ActivityRecord task = getItemFromTaskDisplayAreas(taskDisplayArea -> { final ActivityRecord idealMatchActivity = getItemFromTaskDisplayAreas(taskDisplayArea -> { if (taskDisplayArea == preferredTaskDisplayArea) { return null; } taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); if (mTmpFindTaskResult.mIdealMatch) { return mTmpFindTaskResult.mRecord; mTmpFindTaskResult.process(taskDisplayArea); if (mTmpFindTaskResult.mIdealRecord != null) { return mTmpFindTaskResult.mIdealRecord; } return null; }); if (task != null) { return task; if (idealMatchActivity != null) { return idealMatchActivity; } if (WM_DEBUG_TASKS.isEnabled() && mTmpFindTaskResult.mRecord == null) { if (WM_DEBUG_TASKS.isEnabled() && candidateActivity == null) { ProtoLog.d(WM_DEBUG_TASKS, "No task found"); } return mTmpFindTaskResult.mRecord; return candidateActivity; } /** Loading
services/core/java/com/android/server/wm/TaskDisplayArea.java +0 −41 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK; import static com.android.server.wm.DisplayContent.alwaysCreateRootTask; import static com.android.server.wm.Task.ActivityState.RESUMED; Loading Loading @@ -128,9 +127,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { */ Task mPreferredTopFocusableRootTask; private final RootWindowContainer.FindTaskResult mTmpFindTaskResult = new RootWindowContainer.FindTaskResult(); /** * If this is the same as {@link #getFocusedRootTask} then the activity on the top of the * focused root task has been resumed. If root tasks are changing position this will hold the Loading Loading @@ -1312,43 +1308,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { return someActivityPaused[0] > 0; } /** * Find task for putting the Activity in. */ void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplayArea, RootWindowContainer.FindTaskResult result) { mTmpFindTaskResult.clear(); for (int i = mChildren.size() - 1; i >= 0; --i) { final Task rootTask = mChildren.get(i).asTask(); if (rootTask == null) { continue; } if (!r.hasCompatibleActivityType(rootTask) && rootTask.isLeafTask()) { ProtoLog.d(WM_DEBUG_TASKS, "Skipping rootTask: (mismatch activity/rootTask) " + "%s", rootTask); continue; } mTmpFindTaskResult.process(r, rootTask); // It is possible to have tasks in multiple root tasks 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 root task. 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 (isPreferredDisplayArea) { // Note: since the traversing through the root tasks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks // in the fullscreen root tasks result.setTo(mTmpFindTaskResult); } } } } void onSplitScreenModeDismissed() { // The focused task could be a non-resizeable fullscreen root task that is on top of the // other split-screen tasks, therefore had to dismiss split-screen, make sure the current Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +9 −6 Original line number Diff line number Diff line Loading @@ -314,11 +314,12 @@ public class ActivityStackTests extends WindowTestsBase { final RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult(); result.process(r, task); result.init(r.getActivityType(), r.taskAffinity, r.intent, r.info); result.process(task); assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */)); assertEquals(taskOverlay, task.getTopNonFinishingActivity(true /* includeOverlays */)); assertNotNull(result.mRecord); assertNotNull(result.mIdealRecord); } @Test Loading @@ -340,15 +341,17 @@ public class ActivityStackTests extends WindowTestsBase { final ActivityRecord r1 = new ActivityBuilder(mAtm).setComponent( target).setTargetActivity(targetActivity).build(); RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult(); result.process(r1, parentTask); assertThat(result.mRecord).isNotNull(); result.init(r1.getActivityType(), r1.taskAffinity, r1.intent, r1.info); result.process(parentTask); assertThat(result.mIdealRecord).isNotNull(); // Using alias activity to find task. final ActivityRecord r2 = new ActivityBuilder(mAtm).setComponent( alias).setTargetActivity(targetActivity).build(); result = new RootWindowContainer.FindTaskResult(); result.process(r2, parentTask); assertThat(result.mRecord).isNotNull(); result.init(r2.getActivityType(), r2.taskAffinity, r2.intent, r2.info); result.process(parentTask); assertThat(result.mIdealRecord).isNotNull(); } @Test Loading