diff options
author | 2021-01-07 04:43:01 +0000 | |
---|---|---|
committer | 2021-01-07 04:43:01 +0000 | |
commit | fb8dad4f272cf243169937763d5d1ef56427aade (patch) | |
tree | d4b08d93af38d9070cee1377807fc4a4068374ea | |
parent | 7b4904bd2d01d9c34ef3f2b06026e70d995b53b6 (diff) | |
parent | 4bce80f1f3047003bf375fc1f4408e8396e5f2b4 (diff) |
Merge "Provide alternative find-task method without ActivityRecord"
5 files changed, 91 insertions, 115 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index faf49733050a..145ad1368108 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -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", @@ -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", @@ -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", diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java index 36a1ef9f49b4..0fc4cdb6a928 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -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; } /** diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 3f34478a4088..54996a66ecd7 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -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); @@ -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; } @@ -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); @@ -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; } /** diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index da67abbaa5c1..3f4150b21178 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -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; @@ -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 @@ -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 diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 8b8617d8bf3a..21aa6bf8750a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -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 @@ -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 |