No longer embedding activity if started-for-result across TFs
Instead of sending RESULT_CANCELED to the caller activity, let's
making sure the caller activity can get the result by stop embedding
the result activity in another TaskFragment.
Bug: 236668365
Test: atest TaskFragmentTest
Change-Id: I2a1d3203cc64df6a3b2004529d067990ae17d1d5
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 393c1be..96fe49e 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -83,6 +83,7 @@
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION;
import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK;
+import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT;
import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -3006,6 +3007,11 @@
errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity;
break;
}
+ case EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT: {
+ errMsg = "Cannot embed activity across TaskFragments for result, resultTo: "
+ + mStartActivity.resultTo;
+ break;
+ }
default:
errMsg = "Unhandled embed result:" + result;
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index f8a9d46..128fe54 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -165,6 +165,13 @@
* indicate that an Activity can't be embedded because the Activity is started on a new task.
*/
static final int EMBEDDING_DISALLOWED_NEW_TASK = 3;
+ /**
+ * An embedding check result of
+ * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}:
+ * indicate that an Activity can't be embedded because the Activity is started on a new
+ * TaskFragment, e.g. start an Activity on a new TaskFragment for result.
+ */
+ static final int EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT = 4;
/**
* Embedding check results of {@link #isAllowedToEmbedActivity(ActivityRecord)} or
@@ -175,6 +182,7 @@
EMBEDDING_DISALLOWED_UNTRUSTED_HOST,
EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION,
EMBEDDING_DISALLOWED_NEW_TASK,
+ EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT,
})
@interface EmbeddingCheckResult {}
@@ -567,9 +575,17 @@
if (!isAllowedToEmbedActivityInUntrustedMode(a)
&& !isAllowedToEmbedActivityInTrustedMode(a, uid)) {
return EMBEDDING_DISALLOWED_UNTRUSTED_HOST;
- } else if (smallerThanMinDimension(a)) {
+ }
+
+ if (smallerThanMinDimension(a)) {
return EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION;
}
+
+ // Cannot embed activity across TaskFragments for activity result.
+ if (a.resultTo != null && a.resultTo.getTaskFragment() != this) {
+ return EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT;
+ }
+
return EMBEDDING_ALLOWED;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 5f30963..1096351 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -23,6 +23,7 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.os.Process.FIRST_APPLICATION_UID;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -31,6 +32,9 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
+import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION;
+import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT;
+import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
@@ -433,6 +437,40 @@
}
@Test
+ public void testIsAllowedToEmbedActivity() {
+ final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+ .setCreateParentTask()
+ .createActivityCount(1)
+ .build();
+ final ActivityRecord activity = taskFragment.getTopMostActivity();
+
+ // Not allow embedding activity if not a trusted host.
+ doReturn(false).when(taskFragment).isAllowedToEmbedActivityInUntrustedMode(any());
+ doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt());
+ assertEquals(EMBEDDING_DISALLOWED_UNTRUSTED_HOST,
+ taskFragment.isAllowedToEmbedActivity(activity));
+
+ // Not allow embedding activity if the TaskFragment is smaller than activity min dimension.
+ doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt());
+ doReturn(true).when(taskFragment).smallerThanMinDimension(any());
+ assertEquals(EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION,
+ taskFragment.isAllowedToEmbedActivity(activity));
+
+ // Not allow to start activity across TaskFragments for result.
+ final TaskFragment newTaskFragment = new TaskFragmentBuilder(mAtm)
+ .setParentTask(taskFragment.getTask())
+ .build();
+ final ActivityRecord newActivity = new ActivityBuilder(mAtm)
+ .setUid(FIRST_APPLICATION_UID)
+ .build();
+ doReturn(true).when(newTaskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt());
+ doReturn(false).when(newTaskFragment).smallerThanMinDimension(any());
+ newActivity.resultTo = activity;
+ assertEquals(EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT,
+ newTaskFragment.isAllowedToEmbedActivity(newActivity));
+ }
+
+ @Test
public void testIgnoreRequestedOrientationForActivityEmbeddingSplit() {
// Setup two activities in ActivityEmbedding split.
final Task task = createTask(mDisplayContent);