OSDN Git Service

Fix work profile shortcut launch
authorMakoto Onuki <omakoto@google.com>
Tue, 6 Feb 2018 21:36:34 +0000 (13:36 -0800)
committerMakoto Onuki <omakoto@google.com>
Mon, 12 Feb 2018 23:48:02 +0000 (15:48 -0800)
Shortcuts let the launcher start activities on work profile, so we can't apply
the usual cross-user startActivity check.

LauncherApps already checks the calling user and the target user relationship,
so let's just skip the handleIncomingUser check.

Bug: 72659387
Test: atest CtsShortcutManagerTestCases
Test: atest ${ANDROID_BUILD_TOP}/cts/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java

Change-Id: I3b6179af0c9d5e54ed8fd57c9c830f7a6ecec9da

core/java/android/app/ActivityManagerInternal.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/ActivityStartController.java
services/core/java/com/android/server/am/PendingIntentRecord.java
services/core/java/com/android/server/am/UserController.java

index 4626cb2..b365d52 100644 (file)
@@ -219,6 +219,9 @@ public abstract class ActivityManagerInternal {
     /**
      * Start activity {@code intents} as if {@code packageName} on user {@code userId} did it.
      *
+     * - DO NOT call it with the calling UID cleared.
+     * - All the necessary caller permission checks must be done at callsites.
+     *
      * @return error codes used by {@link IActivityManager#startActivity} and its siblings.
      */
     public abstract int startActivitiesAsPackage(String packageName,
index 99904b5..c958b67 100644 (file)
@@ -25683,9 +25683,11 @@ public class ActivityManagerService extends IActivityManager.Stub
             }
 
             synchronized (ActivityManagerService.this) {
-                return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
+                return mActivityStartController.startActivitiesInPackage(
+                        packageUid, packageName,
                         intents, resolvedTypes, null /* resultTo */,
-                        SafeActivityOptions.fromBundle(bOptions), userId);
+                        SafeActivityOptions.fromBundle(bOptions), userId,
+                        false /* validateIncomingUser */);
             }
         }
 
index 5551914..f24809a 100644 (file)
@@ -245,11 +245,25 @@ public class ActivityStartController {
                 .execute();
     }
 
+    /**
+     * Start intents as a package.
+     *
+     * @param uid make a call as if this UID did.
+     * @param callingPackage make a call as if this package did.
+     * @param intents intents to start.
+     * @param userId start the intents on this user.
+     * @param validateIncomingUser set true to skip checking {@code userId} with the calling UID.
+     */
     final int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
-            String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId) {
+            String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
+            boolean validateIncomingUser) {
         final String reason = "startActivityInPackage";
-        userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
-                Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+        if (validateIncomingUser) {
+            userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
+                    Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+        } else {
+            mService.mUserController.ensureNotSpecialUser(userId);
+        }
         // TODO: Switch to user app stacks here.
         return startActivities(null, uid, callingPackage, intents, resolvedTypes, resultTo, options,
                 userId, reason);
index 8e9d85d..264609f 100644 (file)
@@ -335,7 +335,8 @@ final class PendingIntentRecord extends IIntentSender.Stub {
                                 allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
                                 res = owner.getActivityStartController().startActivitiesInPackage(
                                         uid, key.packageName, allIntents, allResolvedTypes,
-                                        resultTo, mergedOptions, userId);
+                                        resultTo, mergedOptions, userId,
+                                        true /* validateIncomingUser */);
                             } else {
                                 res = owner.getActivityStartController().startActivityInPackage(uid,
                                         callingPid, callingUid, key.packageName, finalIntent,
index d54e264..bfc787e 100644 (file)
@@ -1489,9 +1489,8 @@ class UserController implements Handler.Callback {
                 }
             }
         }
-        if (!allowAll && targetUserId < 0) {
-            throw new IllegalArgumentException(
-                    "Call does not support special user #" + targetUserId);
+        if (!allowAll) {
+            ensureNotSpecialUser(targetUserId);
         }
         // Check shell permission
         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
@@ -1508,6 +1507,13 @@ class UserController implements Handler.Callback {
                 ? getCurrentUserId(): userId;
     }
 
+    void ensureNotSpecialUser(int userId) {
+        if (userId >= 0) {
+            return;
+        }
+        throw new IllegalArgumentException("Call does not support special user #" + userId);
+    }
+
     void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
         Preconditions.checkNotNull(name, "Observer name cannot be null");
         if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)