Loading services/core/java/com/android/server/wm/ActivityStarter.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading services/core/java/com/android/server/wm/TaskFragment.java +17 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 {} Loading Loading @@ -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; } Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -432,6 +436,40 @@ public class TaskFragmentTest extends WindowTestsBase { assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode()); } @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. Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading
services/core/java/com/android/server/wm/TaskFragment.java +17 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 {} Loading Loading @@ -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; } Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -432,6 +436,40 @@ public class TaskFragmentTest extends WindowTestsBase { assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode()); } @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. Loading