diff options
3 files changed, 61 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 550d21acc53f..fe3f37dd4a27 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.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; 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; @@ -3010,6 +3011,11 @@ class ActivityStarter { 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 68884247df97..d91e2c8d4922 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 @@ class TaskFragment extends WindowContainer<WindowContainer> { * 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 @@ class TaskFragment extends WindowContainer<WindowContainer> { EMBEDDING_DISALLOWED_UNTRUSTED_HOST, EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, EMBEDDING_DISALLOWED_NEW_TASK, + EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT, }) @interface EmbeddingCheckResult {} @@ -567,9 +575,17 @@ class TaskFragment extends WindowContainer<WindowContainer> { 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 5f3096356bc5..1096351524d7 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.app.WindowConfiguration.WINDOWING_MODE_PINNED; 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.never; 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 @@ public class TaskFragmentTest extends WindowTestsBase { } @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); |