From 1744f603ed3c15d56508c44474e1c181f126a0b3 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Tue, 27 Jul 2021 16:03:24 +0800 Subject: [PATCH] Allow embedding activities cross apps No longer limiting cross app activities being embedded because the activities can originally be started into the task and therefore no reason to prevent them from also being embedded. Adding enforcement while embedding tasks. Only system or privileged apps with ACTIVITY_EMBEDDING permission can embed tasks of another app. Bug: 189386461 Test: starting activities in embedded task Change-Id: I6a7efe6357118da795b0432cbd9c6cf7d3db4b8f --- .../android/server/wm/ActivityStarter.java | 63 ++++++++++--------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index c881359f7d683..4e73bf3420542 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -24,6 +24,7 @@ import static android.app.ActivityManager.START_CANCELED; import static android.app.ActivityManager.START_CLASS_NOT_FOUND; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED; +import static android.app.ActivityManager.START_PERMISSION_DENIED; import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER; import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; import static android.app.ActivityManager.START_SUCCESS; @@ -744,7 +745,7 @@ class ActivityStarter { Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid=" + mRequest.callingPid + ") when starting: " + mRequest.intent.toString()); SafeActivityOptions.abort(mRequest.activityOptions); - return ActivityManager.START_PERMISSION_DENIED; + return START_PERMISSION_DENIED; } } @@ -858,7 +859,7 @@ class ActivityStarter { } else { Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid + ") when starting: " + intent.toString()); - err = ActivityManager.START_PERMISSION_DENIED; + err = START_PERMISSION_DENIED; } } @@ -1952,9 +1953,40 @@ class ActivityStarter { } } + if (mInTaskFragment != null && mInTaskFragment.getTask() != null) { + final int hostUid = mInTaskFragment.getTask().effectiveUid; + final int embeddingUid = targetTask != null ? targetTask.effectiveUid : r.getUid(); + if (!canTaskBeEmbedded(hostUid, embeddingUid)) { + Slog.e(TAG, "Cannot embed activity to a task owned by " + hostUid + " targetTask= " + + targetTask); + return START_PERMISSION_DENIED; + } + } + return START_SUCCESS; } + /** + * Return {@code true} if the {@param task} can embed another task. + * @param hostUid the uid of the host task + * @param embeddedUid the uid of the task the are going to be embedded + */ + private boolean canTaskBeEmbedded(int hostUid, int embeddedUid) { + // Allowing the embedding if the task is owned by system. + if (hostUid == Process.SYSTEM_UID) { + return true; + } + + // Allowing embedding if the host task is owned by an app that has the ACTIVITY_EMBEDDING + // permission + if (mService.checkPermission(ACTIVITY_EMBEDDING, -1, hostUid) == PERMISSION_GRANTED) { + return true; + } + + // Allowing embedding if it is from the same app that owned the task + return hostUid == embeddedUid; + } + /** * Prepare the target task to be reused for this launch, which including: * - Position the target task on valid root task on preferred display. @@ -2736,31 +2768,6 @@ class ActivityStarter { mIntentDelivered = true; } - /** - * Return {@code true} if the {@param task} has child {@code TaskFragment}s and the - * {@param activity} can be embedded in. Otherwise, return {@code false} - */ - private boolean canActivityBeEmbedded(@NonNull ActivityRecord activity, @NonNull Task task) { - if (task.isLeafTaskFragment()) { - return false; - } - - final int taskUid = task.effectiveUid; - // Allowing the activity be embedded into leaf TaskFragment if the task is owned by system. - if (taskUid == Process.SYSTEM_UID) { - return true; - } - - // Allowing embedding if the task is owned by an app that has the ACTIVITY_EMBEDDING - // permission - if (mService.checkPermission(ACTIVITY_EMBEDDING, -1, taskUid) == PERMISSION_GRANTED) { - return true; - } - - // Allowing embedding if the activity is from the same app that owned the task - return activity.isUid(taskUid); - } - private void addOrReparentStartingActivity(@NonNull Task task, String reason) { TaskFragment newParent = task; if (mInTaskFragment != null) { @@ -2772,7 +2779,7 @@ class ActivityStarter { } else { newParent = mInTaskFragment; } - } else if (canActivityBeEmbedded(mStartActivity, task)) { + } else { // Use the child TaskFragment (if any) as the new parent if the activity can be embedded final ActivityRecord top = task.topRunningActivity(); newParent = top != null ? top.getTaskFragment() : task;