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

Commit de3c16c8 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Do not allow work profile to see main other profiles

It won't throw SecurityException, but it'll pretend there's
no apps on the other profile.

- Also log an error about it, in the client side process.

- Also still send WTF() about the reverse access.

Bug: 34650921
Bug: 34340531

Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest3 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest4 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest5 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest6 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest7 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest8 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest9 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest10 -w com.android.frameworks.servicestests

Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsShortcutHostTestCases -t 'android.content.pm.cts.shortcuthost.ShortcutManagerMultiuserTest'
Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsDevicePolicyManagerTestCases -t 'com.android.cts.devicepolicy.LauncherAppsProfileTest'
Change-Id: I6164014685009db3f34a176a3f12c517766b2b49
parent b289ee1e
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -127,9 +127,10 @@ public class LauncherApps {
    public static final String EXTRA_PIN_ITEM_REQUEST =
            "android.content.pm.extra.PIN_ITEM_REQUEST";

    private Context mContext;
    private ILauncherApps mService;
    private PackageManager mPm;
    private final Context mContext;
    private final ILauncherApps mService;
    private final PackageManager mPm;
    private final UserManager mUserManager;

    private List<CallbackMessageHandler> mCallbacks
            = new ArrayList<CallbackMessageHandler>();
@@ -387,6 +388,7 @@ public class LauncherApps {
        mContext = context;
        mService = service;
        mPm = context.getPackageManager();
        mUserManager = context.getSystemService(UserManager.class);
    }

    /** @hide */
@@ -396,6 +398,16 @@ public class LauncherApps {
                ServiceManager.getService(Context.LAUNCHER_APPS_SERVICE)));
    }

    /**
     * Show an error log on logcat, when the calling user is a managed profile, and the target
     * user is different from the calling user, in order to help developers to detect it.
     */
    private void logErrorForInvalidProfileAccess(@NonNull UserHandle target) {
        if (UserHandle.myUserId() != target.getIdentifier() && mUserManager.isManagedProfile()) {
            Log.e(TAG, "Accessing other profiles/users from managed profile is no longer allowed.");
        }
    }

    /**
     * Return a list of profiles that the caller can access via the {@link LauncherApps} APIs.
     *
@@ -403,14 +415,13 @@ public class LauncherApps {
     * Otherwise it'll return the same list as {@link UserManager#getUserProfiles()} would.
     */
    public List<UserHandle> getProfiles() {
        final UserManager um = mContext.getSystemService(UserManager.class);
        if (um.isManagedProfile()) {
        if (mUserManager.isManagedProfile()) {
            // If it's a managed profile, only return the current profile.
            final List result =  new ArrayList(1);
            result.add(android.os.Process.myUserHandle());
            return result;
        } else {
            return um.getUserProfiles();
            return mUserManager.getUserProfiles();
        }
    }

@@ -424,6 +435,7 @@ public class LauncherApps {
     * @return List of launchable activities. Can be an empty list but will not be null.
     */
    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return convertToActivityList(mService.getLauncherActivities(mContext.getPackageName(),
                    packageName, user), user);
@@ -441,6 +453,7 @@ public class LauncherApps {
     * @return An activity info object if there is a match.
     */
    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            ActivityInfo ai = mService.resolveActivity(mContext.getPackageName(),
                    intent.getComponent(), user);
@@ -464,6 +477,7 @@ public class LauncherApps {
     */
    public void startMainActivity(ComponentName component, UserHandle user, Rect sourceBounds,
            Bundle opts) {
        logErrorForInvalidProfileAccess(user);
        if (DEBUG) {
            Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
        }
@@ -486,6 +500,7 @@ public class LauncherApps {
     */
    public void startAppDetailsActivity(ComponentName component, UserHandle user,
            Rect sourceBounds, Bundle opts) {
        logErrorForInvalidProfileAccess(user);
        try {
            mService.showAppDetailsAsUser(mContext.getPackageName(),
                    component, sourceBounds, opts, user);
@@ -507,6 +522,7 @@ public class LauncherApps {
     */
    public List<LauncherActivityInfo> getShortcutConfigActivityList(@Nullable String packageName,
            @NonNull UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return convertToActivityList(mService.getShortcutConfigActivities(
                    mContext.getPackageName(), packageName, user),
@@ -553,6 +569,7 @@ public class LauncherApps {
     * @see Intent#ACTION_CREATE_SHORTCUT
     * @see android.app.Activity#startIntentSenderForResult
     */
    @Nullable
    public IntentSender getShortcutConfigActivityIntent(@NonNull LauncherActivityInfo info) {
        try {
            return mService.getShortcutConfigActivityIntent(
@@ -571,6 +588,7 @@ public class LauncherApps {
     * @return true if the package exists and is enabled.
     */
    public boolean isPackageEnabled(String packageName, UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return mService.isPackageEnabled(mContext.getPackageName(), packageName, user);
        } catch (RemoteException re) {
@@ -591,6 +609,7 @@ public class LauncherApps {
     */
    public ApplicationInfo getApplicationInfo(String packageName, @ApplicationInfoFlags int flags,
            UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return mService.getApplicationInfo(mContext.getPackageName(), packageName, flags, user);
        } catch (RemoteException re) {
@@ -607,6 +626,7 @@ public class LauncherApps {
     * @return true if the activity exists and is enabled.
     */
    public boolean isActivityEnabled(ComponentName component, UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return mService.isActivityEnabled(mContext.getPackageName(), component, user);
        } catch (RemoteException re) {
@@ -656,6 +676,7 @@ public class LauncherApps {
    @Nullable
    public List<ShortcutInfo> getShortcuts(@NonNull ShortcutQuery query,
            @NonNull UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            return mService.getShortcuts(mContext.getPackageName(),
                    query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
@@ -699,6 +720,7 @@ public class LauncherApps {
     */
    public void pinShortcuts(@NonNull String packageName, @NonNull List<String> shortcutIds,
            @NonNull UserHandle user) {
        logErrorForInvalidProfileAccess(user);
        try {
            mService.pinShortcuts(mContext.getPackageName(), packageName, shortcutIds, user);
        } catch (RemoteException e) {
@@ -866,6 +888,8 @@ public class LauncherApps {
    public void startShortcut(@NonNull String packageName, @NonNull String shortcutId,
            @Nullable Rect sourceBounds, @Nullable Bundle startActivityOptions,
            @NonNull UserHandle user) {
        logErrorForInvalidProfileAccess(user);

        startShortcut(packageName, shortcutId, sourceBounds, startActivityOptions,
                user.getIdentifier());
    }
+95 −58
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
@@ -216,29 +217,35 @@ public class LauncherAppsService extends SystemService {
            }
        }

        /**
         * Checks if the caller is in the same group as the userToCheck.
         */
        private void ensureInUserProfiles(
                String callingPackage, UserHandle userToCheck, String message) {
            ensureInUserProfiles(callingPackage, userToCheck.getIdentifier(), message);
        /** See {@link #canAccessProfile(String, int, String)} */
        private boolean canAccessProfile(
                String callingPackage, UserHandle targetUser, String message) {
            return canAccessProfile(callingPackage, targetUser.getIdentifier(), message);
        }

        private void ensureInUserProfiles(String callingPackage, int targetUserId, String message) {
        /**
         * Checks if the calling user is in the same group as {@code targetUser}, and allowed
         * to access it.
         *
         * @return TRUE if the calling user can access {@code targetUserId}.  FALSE if not *but
         * they're still in the same profile group*.
         *
         * @throws SecurityException if the calling user and {@code targetUser} are not in the same
         * group.
         */
        private boolean canAccessProfile(String callingPackage, int targetUserId, String message) {
            final int callingUserId = injectCallingUserId();

            if (targetUserId == callingUserId) return;
            if (targetUserId == callingUserId) return true;

            long ident = injectClearCallingIdentity();
            try {
                UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
                if (callingUserInfo.isManagedProfile()) {
                    // TODO: Make it SecurityException.  See b/34650921
                    // throw new SecurityException(message + " for another profile " + targetUserId);

                    // TODO: Report caller package name.
                    Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile "
                            + targetUserId + " from " + callingUserId);

                    return false;
                }

                UserInfo targetUserInfo = mUm.getUserInfo(targetUserId);
@@ -250,6 +257,7 @@ public class LauncherAppsService extends SystemService {
            } finally {
                injectRestoreCallingIdentity(ident);
            }
            return true;
        }

        @VisibleForTesting // We override it in unit tests
@@ -301,7 +309,9 @@ public class LauncherAppsService extends SystemService {
        public ActivityInfo resolveActivity(
                String callingPackage, ComponentName component, UserHandle user)
                throws RemoteException {
            ensureInUserProfiles(callingPackage, user, "Cannot resolve activity");
            if (!canAccessProfile(callingPackage, user, "Cannot resolve activity")) {
                return null;
            }
            if (!isUserEnabled(user)) {
                return null;
            }
@@ -328,7 +338,9 @@ public class LauncherAppsService extends SystemService {

        private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage,
                Intent intent, UserHandle user) {
            ensureInUserProfiles(callingPackage, user, "Cannot retrieve activities");
            if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) {
                return null;
            }
            if (!isUserEnabled(user)) {
                return null;
            }
@@ -348,7 +360,10 @@ public class LauncherAppsService extends SystemService {
        @Override
        public IntentSender getShortcutConfigActivityIntent(String callingPackage,
                ComponentName component, UserHandle user) throws RemoteException {
            ensureShortcutPermission(callingPackage, user);
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
                return null;
            }
            Preconditions.checkNotNull(component);
            Preconditions.checkArgument(isUserEnabled(user), "User not enabled");

@@ -356,11 +371,11 @@ public class LauncherAppsService extends SystemService {
            Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component);
            final long identity = Binder.clearCallingIdentity();
            try {
                return PendingIntent.getActivityAsUser(
                final PendingIntent pi = PendingIntent.getActivityAsUser(
                        mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
                                | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
                        null, user)
                        .getIntentSender();
                        null, user);
                return pi == null ? null : pi.getIntentSender();
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
@@ -369,7 +384,9 @@ public class LauncherAppsService extends SystemService {
        @Override
        public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
                throws RemoteException {
            ensureInUserProfiles(callingPackage, user, "Cannot check package");
            if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
                return false;
            }
            if (!isUserEnabled(user)) {
                return false;
            }
@@ -391,7 +408,9 @@ public class LauncherAppsService extends SystemService {
        public ApplicationInfo getApplicationInfo(
                String callingPackage, String packageName, int flags, UserHandle user)
                throws RemoteException {
            ensureInUserProfiles(callingPackage, user, "Cannot check package");
            if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
                return null;
            }
            if (!isUserEnabled(user)) {
                return null;
            }
@@ -407,14 +426,8 @@ public class LauncherAppsService extends SystemService {
            }
        }

        private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) {
            ensureShortcutPermission(callingPackage, user.getIdentifier());
        }

        private void ensureShortcutPermission(@NonNull String callingPackage, int userId) {
        private void ensureShortcutPermission(@NonNull String callingPackage) {
            verifyCallingPackage(callingPackage);
            ensureInUserProfiles(callingPackage, userId, "Cannot access shortcuts");

            if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
                    callingPackage)) {
                throw new SecurityException("Caller can't access shortcut information");
@@ -424,10 +437,11 @@ public class LauncherAppsService extends SystemService {
        @Override
        public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
                String packageName, List shortcutIds, ComponentName componentName, int flags,
                UserHandle user) {
            ensureShortcutPermission(callingPackage, user);
            if (!isUserEnabled(user)) {
                return new ParceledListSlice<>(new ArrayList(0));
                UserHandle targetUser) {
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts")
                    || !isUserEnabled(targetUser)) {
                return new ParceledListSlice<>(Collections.EMPTY_LIST);
            }
            if (shortcutIds != null && packageName == null) {
                throw new IllegalArgumentException(
@@ -438,44 +452,53 @@ public class LauncherAppsService extends SystemService {
            return new ParceledListSlice<>((List<ShortcutInfo>)
                    mShortcutServiceInternal.getShortcuts(getCallingUserId(),
                            callingPackage, changedSince, packageName, shortcutIds,
                            componentName, flags, user.getIdentifier()));
                            componentName, flags, targetUser.getIdentifier()));
        }

        @Override
        public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
                UserHandle user) {
            ensureShortcutPermission(callingPackage, user);
            if (!isUserEnabled(user)) {
                UserHandle targetUser) {
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) {
                return;
            }
            if (!isUserEnabled(targetUser)) {
                throw new IllegalStateException("Cannot pin shortcuts for disabled profile "
                        + user);
                        + targetUser);
            }

            mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
                    callingPackage, packageName, ids, user.getIdentifier());
                    callingPackage, packageName, ids, targetUser.getIdentifier());
        }

        @Override
        public int getShortcutIconResId(String callingPackage, String packageName, String id,
                int userId) {
            ensureShortcutPermission(callingPackage, userId);
            if (!isUserEnabled(userId)) {
                int targetUserId) {
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
                return 0;
            }
            if (!isUserEnabled(targetUserId)) {
                return 0;
            }

            return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
                    callingPackage, packageName, id, userId);
                    callingPackage, packageName, id, targetUserId);
        }

        @Override
        public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
                String packageName, String id, int userId) {
            ensureShortcutPermission(callingPackage, userId);
            if (!isUserEnabled(userId)) {
                String packageName, String id, int targetUserId) {
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
                return null;
            }
            if (!isUserEnabled(targetUserId)) {
                return null;
            }

            return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
                    callingPackage, packageName, id, userId);
                    callingPackage, packageName, id, targetUserId);
        }

        @Override
@@ -487,23 +510,27 @@ public class LauncherAppsService extends SystemService {

        @Override
        public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
                Rect sourceBounds, Bundle startActivityOptions, int userId) {
                Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
            verifyCallingPackage(callingPackage);
            ensureInUserProfiles(callingPackage, userId, "Cannot start activity");

            if (!isUserEnabled(userId)) {
            if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) {
                return false;
            }
            if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
                return false;
            }
            if (!isUserEnabled(targetUserId)) {
                throw new IllegalStateException("Cannot start a shortcut for disabled profile "
                        + userId);
                        + targetUserId);
            }

            // Even without the permission, pinned shortcuts are always launchable.
            if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
                    callingPackage, packageName, shortcutId, userId)) {
                ensureShortcutPermission(callingPackage, userId);
                    callingPackage, packageName, shortcutId, targetUserId)) {
                ensureShortcutPermission(callingPackage);
            }

            final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
                    getCallingUserId(), callingPackage, packageName, shortcutId, userId);
                    getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId);
            if (intents == null || intents.length == 0) {
                return false;
            }
@@ -513,7 +540,7 @@ public class LauncherAppsService extends SystemService {
            intents[0].setSourceBounds(sourceBounds);

            return startShortcutIntentsAsPublisher(
                    intents, packageName, startActivityOptions, userId);
                    intents, packageName, startActivityOptions, targetUserId);
        }

        private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
@@ -543,7 +570,9 @@ public class LauncherAppsService extends SystemService {
        public boolean isActivityEnabled(
                String callingPackage, ComponentName component, UserHandle user)
                throws RemoteException {
            ensureInUserProfiles(callingPackage , user, "Cannot check component");
            if (!canAccessProfile(callingPackage , user, "Cannot check component")) {
                return false;
            }
            if (!isUserEnabled(user)) {
                return false;
            }
@@ -565,7 +594,9 @@ public class LauncherAppsService extends SystemService {
        public void startActivityAsUser(String callingPackage,
                ComponentName component, Rect sourceBounds,
                Bundle opts, UserHandle user) throws RemoteException {
            ensureInUserProfiles(callingPackage, user, "Cannot start activity");
            if (!canAccessProfile(callingPackage, user, "Cannot start activity")) {
                return;
            }
            if (!isUserEnabled(user)) {
                throw new IllegalStateException("Cannot start activity for disabled profile "  + user);
            }
@@ -618,7 +649,9 @@ public class LauncherAppsService extends SystemService {
        @Override
        public void showAppDetailsAsUser(String callingPackage, ComponentName component,
                Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
            ensureInUserProfiles(callingPackage, user, "Cannot show app details");
            if (!canAccessProfile(callingPackage, user, "Cannot show app details")) {
                return;
            }
            if (!isUserEnabled(user)) {
                throw new IllegalStateException("Cannot show app details for disabled profile "
                        + user);
@@ -642,9 +675,13 @@ public class LauncherAppsService extends SystemService {
        private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser,
                String debugMsg) {
            if (user.getIdentifier() == listeningUser.getIdentifier()) {
                if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg);
                if (DEBUG) Log.d(TAG, "Delivering msg to same user: " + debugMsg);
                return true;
            }
            if (mUm.isManagedProfile(listeningUser.getIdentifier())) {
                if (DEBUG) Log.d(TAG, "Managed profile can't see other profiles: " + debugMsg);
                return false;
            }
            long ident = injectClearCallingIdentity();
            try {
                UserInfo userInfo = mUm.getUserInfo(user.getIdentifier());
+17 −1
Original line number Diff line number Diff line
@@ -602,12 +602,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected static final int USER_0 = UserHandle.USER_SYSTEM;
    protected static final int USER_10 = 10;
    protected static final int USER_11 = 11;
    protected static final int USER_P0 = 20; // profile of user 0
    protected static final int USER_P0 = 20; // profile of user 0 (MANAGED_PROFILE *not* set)
    protected static final int USER_P1 = 21; // another profile of user 0 (MANAGED_PROFILE set)

    protected static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
    protected static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
    protected static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
    protected static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
    protected static final UserHandle HANDLE_USER_P1 = UserHandle.of(USER_P1);

    protected static final UserInfo USER_INFO_0 = withProfileGroupId(
            new UserInfo(USER_0, "user0",
@@ -630,6 +632,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
            new UserInfo(USER_P0, "userP0", UserInfo.FLAG_INITIALIZED), 0);

    protected static final UserInfo USER_INFO_P1 = withProfileGroupId(
            new UserInfo(USER_P1, "userP1",
                    UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE), 0);

    protected BiPredicate<String, Integer> mDefaultLauncherChecker =
            (callingPackage, userId) ->
            LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage)
@@ -746,6 +752,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        mUserInfos.put(USER_10, USER_INFO_10);
        mUserInfos.put(USER_11, USER_INFO_11);
        mUserInfos.put(USER_P0, USER_INFO_P0);
        mUserInfos.put(USER_P1, USER_INFO_P1);

        // Set up isUserRunning and isUserUnlocked.
        when(mMockUserManager.isUserRunning(anyInt())).thenAnswer(new AnswerWithSystemCheck<>(
@@ -775,6 +782,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
                    assertNotNull(parent);
                    return parent;
                }));
        when(mMockUserManager.isManagedProfile(anyInt()))
                .thenAnswer(new AnswerWithSystemCheck<>(inv -> {
                    final int userId = (Integer) inv.getArguments()[0];
                    final UserInfo ui = mUserInfos.get(userId);
                    assertNotNull(ui);
                    return ui.isManagedProfile();
                }));

        when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
                ActivityManager.PROCESS_STATE_CACHED_EMPTY);
@@ -784,12 +798,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        mRunningUsers.put(USER_10, false);
        mRunningUsers.put(USER_11, false);
        mRunningUsers.put(USER_P0, true);
        mRunningUsers.put(USER_P1, true);

        // Unlock all users by default.
        mUnlockedUsers.put(USER_0, true);
        mUnlockedUsers.put(USER_10, true);
        mUnlockedUsers.put(USER_11, true);
        mUnlockedUsers.put(USER_P0, true);
        mUnlockedUsers.put(USER_P1, true);

        // Set up resources
        setUpAppResources();
+26 −0

File changed.

Preview size limit exceeded, changes collapsed.