summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Louis Chang <louischang@google.com> 2021-01-07 04:43:01 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-01-07 04:43:01 +0000
commitfb8dad4f272cf243169937763d5d1ef56427aade (patch)
treed4b08d93af38d9070cee1377807fc4a4068374ea
parent7b4904bd2d01d9c34ef3f2b06026e70d995b53b6 (diff)
parent4bce80f1f3047003bf375fc1f4408e8396e5f2b4 (diff)
Merge "Provide alternative find-task method without ActivityRecord"
-rw-r--r--data/etc/services.core.protolog.json18
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java11
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java121
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java15
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