diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index dd1f29e3bf5f7..7fab94cab413c 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -31,6 +31,7 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.os.Process.INVALID_UID; +import static android.os.Process.SYSTEM_UID; import static android.os.UserHandle.USER_NULL; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.TRANSIT_CLOSE; @@ -82,6 +83,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -530,6 +532,11 @@ class TaskFragment extends WindowContainer { * certificate. */ private boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) { + if (UserHandle.getAppId(mTaskFragmentOrganizerUid) == SYSTEM_UID) { + // The system is trusted to embed other apps securely and for all users. + return true; + } + if (mTaskFragmentOrganizerUid == a.getUid()) { // Activities from the same UID can be embedded freely by the host. return true; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index f7f11ae370889..87abc53bfc5a8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -39,6 +39,7 @@ import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; +import static android.os.Process.SYSTEM_UID; import static com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; @@ -1141,6 +1142,34 @@ public class ActivityStarterTests extends WindowTestsBase { assertFalse(taskFragment.hasChild()); } + @Test + public void testStartActivityInner_inTaskFragment_allowedForSystemUid() { + final ActivityStarter starter = prepareStarter(0, false); + final ActivityRecord targetRecord = new ActivityBuilder(mAtm).build(); + final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).setCreateTask(true).build(); + final TaskFragment taskFragment = new TaskFragment(mAtm, sourceRecord.token, + true /* createdByOrganizer */); + sourceRecord.getTask().addChild(taskFragment, POSITION_TOP); + + taskFragment.setTaskFragmentOrganizer(mock(TaskFragmentOrganizerToken.class), SYSTEM_UID, + "system_uid"); + + starter.startActivityInner( + /* r */targetRecord, + /* sourceRecord */ sourceRecord, + /* voiceSession */null, + /* voiceInteractor */ null, + /* startFlags */ 0, + /* doResume */true, + /* options */null, + /* inTask */null, + /* inTaskFragment */ taskFragment, + /* restrictedBgActivity */false, + /* intentGrants */null); + + assertTrue(taskFragment.hasChild()); + } + @Test public void testStartActivityInner_inTaskFragment_allowedForSameUid() { final ActivityStarter starter = prepareStarter(0, false);