Do not look for in-process activities if contains other process activities
The #findActivityBelow looks for the in-process activities first to
get the activity behind the given activity. However, it may not be
correct if the container contains activities of another process.
Bug: 271769839
Test: SplitControllerTest
Change-Id: I8794c55a56712113dc318aa4a0f440c90589378d
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index caefb2e..404429a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -1000,7 +1000,10 @@
Activity findActivityBelow(@NonNull Activity activity) {
Activity activityBelow = null;
final TaskFragmentContainer container = getContainerWithActivity(activity);
- if (container != null) {
+ // Looking for the activity below from the information we already have if the container
+ // only embeds activities of the same process because activities of other processes are not
+ // available in this embedding host process for security concern.
+ if (container != null && !container.hasCrossProcessActivities()) {
final List<Activity> containerActivities = container.collectNonFinishingActivities();
final int index = containerActivities.indexOf(activity);
if (index > 0) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 6c553a8..60be9d1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -153,6 +153,11 @@
Runnable mAppearEmptyTimeout;
/**
+ * Whether this TaskFragment contains activities of another process/package.
+ */
+ private boolean mHasCrossProcessActivities;
+
+ /**
* Creates a container with an existing activity that will be re-parented to it in a window
* container transaction.
* @param pairedPrimaryContainer when it is set, the new container will be add right above it
@@ -418,10 +423,18 @@
mAppearEmptyTimeout = null;
}
+ mHasCrossProcessActivities = false;
mInfo = info;
if (mInfo == null || mInfo.isEmpty()) {
return;
}
+
+ // Contains activities of another process if the activities size is not matched to the
+ // running activity count
+ if (mInfo.getRunningActivityCount() != mInfo.getActivities().size()) {
+ mHasCrossProcessActivities = true;
+ }
+
// Only track the pending Intent when the container is empty.
mPendingAppearedIntent = null;
if (mPendingAppearedActivities.isEmpty()) {
@@ -751,6 +764,11 @@
return mPendingAppearedInRequestedTaskFragmentActivities.contains(activityToken);
}
+ /** Whether contains activities of another process */
+ boolean hasCrossProcessActivities() {
+ return mHasCrossProcessActivities;
+ }
+
/** Gets the parent leaf Task id. */
int getTaskId() {
return mTaskContainer.getTaskId();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 3d0e1c8..cbdc262 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -1014,6 +1014,25 @@
}
@Test
+ public void testFindActivityBelow() {
+ // Create a container with two activities
+ final TaskFragmentContainer container = createMockTaskFragmentContainer(mActivity);
+ final Activity pendingAppearedActivity = createMockActivity();
+ container.addPendingAppearedActivity(pendingAppearedActivity);
+
+ // Ensure the activity below matches
+ assertEquals(mActivity,
+ mSplitController.findActivityBelow(pendingAppearedActivity));
+
+ // Ensure that the activity look up won't search for the in-process activities and should
+ // IPC to WM core to get the activity below. It should be `null` for this mock test.
+ spyOn(container);
+ doReturn(true).when(container).hasCrossProcessActivities();
+ assertNotEquals(mActivity,
+ mSplitController.findActivityBelow(pendingAppearedActivity));
+ }
+
+ @Test
public void testResolveActivityToContainer_inUnknownTaskFragment() {
doReturn(new Binder()).when(mSplitController)
.getTaskFragmentTokenFromActivityClientRecord(mActivity);