Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a342743 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Propagate calling UID to AM from LauncherApps

- So that AM can perform all the necessary caller checks, except for the cross-profile/user check.

- Note PixelLauncher is the recent app which gets extra privileges. So I used ShortcutLauncherDemo
and a 3p launcher for manual tests.

Fixes: 78635323
Test: manual test, with a 3p launcher. (nova)
- Launch primary profile app -> launches fine
- Launch work profile app-> launches fine
- Launch suspended work profile app -> "can't open this app" dialog is shown.
- Launch the primary counterpart of the suspended work profile app -> launches fine.
- Launch work profile app in quiet mode, with separate work challenge
  -> "turn on work profile"? dialog is shown
    -> then "cancel" -> nothing happens.
    -> then "turn on" -> "re-enter your pin" is shown -> type pin -> work profile app starts fine.
- Launch work profile app without separate work challenge
  -> "turn on work profile"? dialog is shown
    -> then "cancel" -> nothing happens.
    -> then "turn on" -> work profile starts and the app starts fine.
- "App info" on work profile app -> Setting page opens fine.
- "App info" on primary profile app -> Setting page opens fine.

Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest*.java
Test: atest cts/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherApps*.java

Change-Id: Ie665a8890407d05c1d877f04d9c5c3a1caad18e1
parent 5d8dfe17
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -235,6 +235,17 @@ public abstract class ActivityManagerInternal {
    public abstract int startActivitiesAsPackage(String packageName,
    public abstract int startActivitiesAsPackage(String packageName,
            int userId, Intent[] intents, Bundle bOptions);
            int userId, Intent[] intents, Bundle bOptions);


    /**
     * Start activity {@code intent} without calling user-id check.
     *
     * - DO NOT call it with the calling UID cleared.
     * - The caller must do the calling user ID check.
     *
     * @return error codes used by {@link IActivityManager#startActivity} and its siblings.
     */
    public abstract int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, @Nullable Bundle options, int userId);

    /**
    /**
     * Get the procstate for the UID.  The return value will be between
     * Get the procstate for the UID.  The return value will be between
     * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
     * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
+3 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.content.pm;
package android.content.pm;


import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender;
@@ -42,10 +43,10 @@ interface ILauncherApps {
            String callingPackage, String packageName, in UserHandle user);
            String callingPackage, String packageName, in UserHandle user);
    ActivityInfo resolveActivity(
    ActivityInfo resolveActivity(
            String callingPackage, in ComponentName component, in UserHandle user);
            String callingPackage, in ComponentName component, in UserHandle user);
    void startActivityAsUser(String callingPackage,
    void startActivityAsUser(in IApplicationThread caller, String callingPackage,
            in ComponentName component, in Rect sourceBounds,
            in ComponentName component, in Rect sourceBounds,
            in Bundle opts, in UserHandle user);
            in Bundle opts, in UserHandle user);
    void showAppDetailsAsUser(
    void showAppDetailsAsUser(in IApplicationThread caller,
            String callingPackage, in ComponentName component, in Rect sourceBounds,
            String callingPackage, in ComponentName component, in Rect sourceBounds,
            in Bundle opts, in UserHandle user);
            in Bundle opts, in UserHandle user);
    boolean isPackageEnabled(String callingPackage, String packageName, in UserHandle user);
    boolean isPackageEnabled(String callingPackage, String packageName, in UserHandle user);
+4 −2
Original line number Original line Diff line number Diff line
@@ -548,7 +548,8 @@ public class LauncherApps {
            Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
            Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
        }
        }
        try {
        try {
            mService.startActivityAsUser(mContext.getPackageName(),
            mService.startActivityAsUser(mContext.getIApplicationThread(),
                    mContext.getPackageName(),
                    component, sourceBounds, opts, user);
                    component, sourceBounds, opts, user);
        } catch (RemoteException re) {
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
            throw re.rethrowFromSystemServer();
@@ -568,7 +569,8 @@ public class LauncherApps {
            Rect sourceBounds, Bundle opts) {
            Rect sourceBounds, Bundle opts) {
        logErrorForInvalidProfileAccess(user);
        logErrorForInvalidProfileAccess(user);
        try {
        try {
            mService.showAppDetailsAsUser(mContext.getPackageName(),
            mService.showAppDetailsAsUser(mContext.getIApplicationThread(),
                    mContext.getPackageName(),
                    component, sourceBounds, opts, user);
                    component, sourceBounds, opts, user);
        } catch (RemoteException re) {
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
            throw re.rethrowFromSystemServer();
+23 −2
Original line number Original line Diff line number Diff line
@@ -5049,9 +5049,20 @@ public class ActivityManagerService extends IActivityManager.Stub
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
        // TODO: Switch to user app stacks here.
        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCaller(caller)
@@ -26342,6 +26353,16 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            }
        }
        }
        @Override
        public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
                Intent intent, Bundle options, int userId) {
            return ActivityManagerService.this.startActivityAsUser(
                    caller, callerPacakge, intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
                    false /*validateIncomingUser*/);
        }
        @Override
        @Override
        public int getUidProcessState(int uid) {
        public int getUidProcessState(int uid) {
            return getUidState(uid);
            return getUidState(uid);
+12 −6
Original line number Original line Diff line number Diff line
@@ -1315,10 +1315,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return aInfo;
        return aInfo;
    }
    }


    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
        return resolveIntent(intent, resolvedType, userId, 0, Binder.getCallingUid());
    }

    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
            int filterCallingUid) {
            int filterCallingUid) {
        synchronized (mService) {
        synchronized (mService) {
@@ -1330,9 +1326,19 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                            || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
                            || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
                    modifiedFlags |= PackageManager.MATCH_INSTANT;
                    modifiedFlags |= PackageManager.MATCH_INSTANT;
                }
                }

                // In order to allow cross-profile lookup, we clear the calling identity here.
                // Note the binder identity won't affect the result, but filterCallingUid will.

                // Cross-user/profile call check are done at the entry points
                // (e.g. AMS.startActivityAsUser).
                final long token = Binder.clearCallingIdentity();
                try {
                    return mService.getPackageManagerInternalLocked().resolveIntent(
                    return mService.getPackageManagerInternalLocked().resolveIntent(
                            intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
                            intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);

                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            } finally {
            } finally {
                Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
                Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
            }
            }
Loading