Loading core/java/android/os/UserManagerInternal.java +20 −0 Original line number Diff line number Diff line Loading @@ -186,4 +186,24 @@ public abstract class UserManagerInternal { * @return the array of user ids. */ public abstract int[] getUserIds(); /** * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group * and that the {@code callingUserId} is not a managed profile and * {@code targetUserId} is enabled. * * @return TRUE if the {@code callingUserId} can access {@code targetUserId}. FALSE * otherwise * * @throws SecurityException if the calling user and {@code targetUser} are not in the same * group and {@code throwSecurityException} is true, otherwise if will simply return false. */ public abstract boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException); /** * If {@code userId} is of a managed profile, return the parent user ID. Otherwise return * itself. */ public abstract int getProfileParentId(int userId); } services/core/java/com/android/server/pm/LauncherAppsService.java +31 −142 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; import android.content.pm.UserInfo; import android.graphics.Rect; import android.net.Uri; import android.os.Binder; Loading @@ -50,7 +49,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.provider.Settings; import android.util.Log; import android.util.Slog; Loading Loading @@ -102,7 +101,7 @@ public class LauncherAppsService extends SystemService { private static final boolean DEBUG = false; private static final String TAG = "LauncherAppsService"; private final Context mContext; private final UserManager mUm; private final UserManagerInternal mUserManagerInternal; private final ActivityManagerInternal mActivityManagerInternal; private final ShortcutServiceInternal mShortcutServiceInternal; private final PackageCallbackList<IOnAppsChangedListener> mListeners Loading @@ -114,7 +113,8 @@ public class LauncherAppsService extends SystemService { public LauncherAppsImpl(Context context) { mContext = context; mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mUserManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UserManagerInternal.class)); mActivityManagerInternal = Preconditions.checkNotNull( LocalServices.getService(ActivityManagerInternal.class)); mShortcutServiceInternal = Preconditions.checkNotNull( Loading Loading @@ -222,12 +222,6 @@ public class LauncherAppsService extends SystemService { } } /** See {@link #canAccessProfile(String, int, String)} */ private boolean canAccessProfile( String callingPackage, UserHandle targetUser, String message) { return canAccessProfile(callingPackage, targetUser.getIdentifier(), message); } /** * Checks if the calling user is in the same group as {@code targetUser}, and allowed * to access it. Loading @@ -238,30 +232,9 @@ public class LauncherAppsService extends SystemService { * @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 true; long ident = injectClearCallingIdentity(); try { UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); if (callingUserInfo.isManagedProfile()) { Slog.w(TAG, message + " by " + callingPackage + " for another profile " + targetUserId + " from " + callingUserId); return false; } UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); if (targetUserInfo == null || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { throw new SecurityException(message + " for unrelated profile " + targetUserId); } } finally { injectRestoreCallingIdentity(ident); } return true; private boolean canAccessProfile(int targetUserId, String message) { return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId, message, true); } @VisibleForTesting // We override it in unit tests Loading @@ -283,23 +256,6 @@ public class LauncherAppsService extends SystemService { } } /** * Checks if the user is enabled. */ private boolean isUserEnabled(UserHandle user) { return isUserEnabled(user.getIdentifier()); } private boolean isUserEnabled(int userId) { long ident = injectClearCallingIdentity(); try { UserInfo targetUserInfo = mUm.getUserInfo(userId); return targetUserInfo != null && targetUserInfo.isEnabled(); } finally { injectRestoreCallingIdentity(ident); } } @Override public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage, String packageName, UserHandle user) Loading @@ -315,10 +271,7 @@ public class LauncherAppsService extends SystemService { public ActivityInfo resolveActivity( String callingPackage, ComponentName component, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot resolve activity")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) { return null; } Loading Loading @@ -346,10 +299,7 @@ public class LauncherAppsService extends SystemService { private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, Intent intent, UserHandle user) { if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) { return null; } Loading @@ -372,11 +322,10 @@ public class LauncherAppsService extends SystemService { public IntentSender getShortcutConfigActivityIntent(String callingPackage, ComponentName component, UserHandle user) throws RemoteException { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, user, "Cannot check package")) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return null; } Preconditions.checkNotNull(component); Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); // All right, create the sender. Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); Loading @@ -395,10 +344,7 @@ public class LauncherAppsService extends SystemService { @Override public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot check package")) { return false; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return false; } Loading @@ -421,10 +367,7 @@ public class LauncherAppsService extends SystemService { public ApplicationInfo getApplicationInfo( String callingPackage, String packageName, int flags, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot check package")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return null; } Loading Loading @@ -454,8 +397,7 @@ public class LauncherAppsService extends SystemService { String packageName, List shortcutIds, ComponentName componentName, int flags, UserHandle targetUser) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts") || !isUserEnabled(targetUser)) { if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) { return new ParceledListSlice<>(Collections.EMPTY_LIST); } if (shortcutIds != null && packageName == null) { Loading @@ -475,13 +417,9 @@ public class LauncherAppsService extends SystemService { public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle targetUser) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) { if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) { return; } if (!isUserEnabled(targetUser)) { throw new IllegalStateException("Cannot pin shortcuts for disabled profile " + targetUser); } mShortcutServiceInternal.pinShortcuts(getCallingUserId(), callingPackage, packageName, ids, targetUser.getIdentifier()); Loading @@ -491,10 +429,7 @@ public class LauncherAppsService extends SystemService { public int getShortcutIconResId(String callingPackage, String packageName, String id, int targetUserId) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { return 0; } if (!isUserEnabled(targetUserId)) { if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) { return 0; } Loading @@ -506,10 +441,7 @@ public class LauncherAppsService extends SystemService { public ParcelFileDescriptor getShortcutIconFd(String callingPackage, String packageName, String id, int targetUserId) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { return null; } if (!isUserEnabled(targetUserId)) { if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) { return null; } Loading @@ -528,13 +460,9 @@ public class LauncherAppsService extends SystemService { public boolean startShortcut(String callingPackage, String packageName, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) { if (!canAccessProfile(targetUserId, "Cannot start activity")) { return false; } if (!isUserEnabled(targetUserId)) { throw new IllegalStateException("Cannot start a shortcut for disabled profile " + targetUserId); } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), Loading Loading @@ -581,10 +509,7 @@ public class LauncherAppsService extends SystemService { public boolean isActivityEnabled( String callingPackage, ComponentName component, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage , user, "Cannot check component")) { return false; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) { return false; } Loading @@ -607,12 +532,9 @@ public class LauncherAppsService extends SystemService { public void startActivityAsUser(String callingPackage, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot start activity")) { if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) { return; } if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot start activity for disabled profile " + user); } Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); Loading Loading @@ -665,13 +587,9 @@ public class LauncherAppsService extends SystemService { @Override public void showAppDetailsAsUser(String callingPackage, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot show app details")) { if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) { return; } if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot show app details for disabled profile " + user); } long ident = Binder.clearCallingIdentity(); try { Loading @@ -688,39 +606,10 @@ public class LauncherAppsService extends SystemService { /** Checks if user is a profile of or same as listeningUser. * and the user is enabled. */ private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user, String debugMsg) { if (user.getIdentifier() == listeningUser.getIdentifier()) { 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()); UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); if (userInfo == null || listeningUserInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || userInfo.profileGroupId != listeningUserInfo.profileGroupId || !userInfo.isEnabled()) { if (DEBUG) { Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" + debugMsg); } return false; } else { if (DEBUG) { Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" + debugMsg); } return true; } } finally { injectRestoreCallingIdentity(ident); } return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(), user.getIdentifier(), debugMsg, false); } @VisibleForTesting Loading @@ -740,7 +629,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue; try { listener.onPackageAdded(user, packageName); } catch (RemoteException re) { Loading @@ -762,7 +651,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue; try { listener.onPackageRemoved(user, packageName); } catch (RemoteException re) { Loading @@ -784,7 +673,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue; try { listener.onPackageChanged(user, packageName); } catch (RemoteException re) { Loading @@ -806,7 +695,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue; try { listener.onPackagesAvailable(user, packages, isReplacing()); } catch (RemoteException re) { Loading @@ -828,7 +717,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue; try { listener.onPackagesUnavailable(user, packages, isReplacing()); } catch (RemoteException re) { Loading @@ -850,7 +739,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue; try { listener.onPackagesSuspended(user, packages); } catch (RemoteException re) { Loading @@ -872,7 +761,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue; try { listener.onPackagesUnsuspended(user, packages); } catch (RemoteException re) { Loading Loading @@ -901,7 +790,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue; final int launcherUserId = cookie.user.getIdentifier(); Loading services/core/java/com/android/server/pm/ShortcutService.java +6 −16 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.text.TextUtils; import android.text.format.Time; import android.util.ArraySet; Loading Loading @@ -315,7 +315,7 @@ public class ShortcutService extends IShortcutService.Stub { private final IPackageManager mIPackageManager; private final PackageManagerInternal mPackageManagerInternal; private final UserManager mUserManager; private final UserManagerInternal mUserManagerInternal; private final UsageStatsManagerInternal mUsageStatsManagerInternal; private final ActivityManagerInternal mActivityManagerInternal; Loading Loading @@ -430,7 +430,8 @@ public class ShortcutService extends IShortcutService.Stub { mIPackageManager = AppGlobals.getPackageManager(); mPackageManagerInternal = Preconditions.checkNotNull( LocalServices.getService(PackageManagerInternal.class)); mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class)); mUserManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UserManagerInternal.class)); mUsageStatsManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UsageStatsManagerInternal.class)); mActivityManagerInternal = Preconditions.checkNotNull( Loading Loading @@ -1176,12 +1177,7 @@ public class ShortcutService extends IShortcutService.Stub { // the user might just have been unlocked. // Note we just don't use isUserUnlockingOrUnlocked() here, because it'll return false // when the user is STOPPING, which we still want to consider as "unlocked". final long token = injectClearCallingIdentity(); try { return mUserManager.isUserUnlockingOrUnlocked(userId); } finally { injectRestoreCallingIdentity(token); } return mUserManagerInternal.isUserUnlockingOrUnlocked(userId); } // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L". Loading Loading @@ -3493,13 +3489,7 @@ public class ShortcutService extends IShortcutService.Stub { * itself. */ int getParentOrSelfUserId(int userId) { final long token = injectClearCallingIdentity(); try { final UserInfo parent = mUserManager.getProfileParent(userId); return (parent != null) ? parent.id : userId; } finally { injectRestoreCallingIdentity(token); } return mUserManagerInternal.getProfileParentId(userId); } void injectSendIntentSender(IntentSender intentSender, Intent extras) { Loading services/core/java/com/android/server/pm/UserManagerService.java +51 −8 Original line number Diff line number Diff line Loading @@ -781,14 +781,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public int getProfileParentId(int userHandle) { checkManageUsersPermission("get the profile parent"); synchronized (mUsersLock) { UserInfo profileParent = getProfileParentLU(userHandle); if (profileParent == null) { return userHandle; } return profileParent.id; } return mLocalService.getProfileParentId(userHandle); } private UserInfo getProfileParentLU(int userHandle) { Loading Loading @@ -3928,6 +3921,56 @@ public class UserManagerService extends IUserManager.Stub { public boolean exists(int userId) { return getUserInfoNoChecks(userId) != null; } @Override public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException) { if (targetUserId == callingUserId) { return true; } synchronized (mUsersLock) { UserInfo callingUserInfo = getUserInfoLU(callingUserId); if (callingUserInfo == null || callingUserInfo.isManagedProfile()) { if (throwSecurityException) { throw new SecurityException( debugMsg + " for another profile " + targetUserId + " from " + callingUserId); } } UserInfo targetUserInfo = getUserInfoLU(targetUserId); if (targetUserInfo == null || !targetUserInfo.isEnabled()) { // Do not throw any exception here as this could happen due to race conditions // between the system updating its state and the client getting notified. if (throwSecurityException) { Slog.w(LOG_TAG, debugMsg + " for disabled profile " + targetUserId + " from " + callingUserId); } return false; } if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { if (throwSecurityException) { throw new SecurityException( debugMsg + " for unrelated profile " + targetUserId); } return false; } } return true; } @Override public int getProfileParentId(int userId) { synchronized (mUsersLock) { UserInfo profileParent = getProfileParentLU(userId); if (profileParent == null) { return userId; } return profileParent.id; } } } /* Remove all the users except of the system one. */ Loading Loading
core/java/android/os/UserManagerInternal.java +20 −0 Original line number Diff line number Diff line Loading @@ -186,4 +186,24 @@ public abstract class UserManagerInternal { * @return the array of user ids. */ public abstract int[] getUserIds(); /** * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group * and that the {@code callingUserId} is not a managed profile and * {@code targetUserId} is enabled. * * @return TRUE if the {@code callingUserId} can access {@code targetUserId}. FALSE * otherwise * * @throws SecurityException if the calling user and {@code targetUser} are not in the same * group and {@code throwSecurityException} is true, otherwise if will simply return false. */ public abstract boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException); /** * If {@code userId} is of a managed profile, return the parent user ID. Otherwise return * itself. */ public abstract int getProfileParentId(int userId); }
services/core/java/com/android/server/pm/LauncherAppsService.java +31 −142 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; import android.content.pm.UserInfo; import android.graphics.Rect; import android.net.Uri; import android.os.Binder; Loading @@ -50,7 +49,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.provider.Settings; import android.util.Log; import android.util.Slog; Loading Loading @@ -102,7 +101,7 @@ public class LauncherAppsService extends SystemService { private static final boolean DEBUG = false; private static final String TAG = "LauncherAppsService"; private final Context mContext; private final UserManager mUm; private final UserManagerInternal mUserManagerInternal; private final ActivityManagerInternal mActivityManagerInternal; private final ShortcutServiceInternal mShortcutServiceInternal; private final PackageCallbackList<IOnAppsChangedListener> mListeners Loading @@ -114,7 +113,8 @@ public class LauncherAppsService extends SystemService { public LauncherAppsImpl(Context context) { mContext = context; mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mUserManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UserManagerInternal.class)); mActivityManagerInternal = Preconditions.checkNotNull( LocalServices.getService(ActivityManagerInternal.class)); mShortcutServiceInternal = Preconditions.checkNotNull( Loading Loading @@ -222,12 +222,6 @@ public class LauncherAppsService extends SystemService { } } /** See {@link #canAccessProfile(String, int, String)} */ private boolean canAccessProfile( String callingPackage, UserHandle targetUser, String message) { return canAccessProfile(callingPackage, targetUser.getIdentifier(), message); } /** * Checks if the calling user is in the same group as {@code targetUser}, and allowed * to access it. Loading @@ -238,30 +232,9 @@ public class LauncherAppsService extends SystemService { * @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 true; long ident = injectClearCallingIdentity(); try { UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); if (callingUserInfo.isManagedProfile()) { Slog.w(TAG, message + " by " + callingPackage + " for another profile " + targetUserId + " from " + callingUserId); return false; } UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); if (targetUserInfo == null || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { throw new SecurityException(message + " for unrelated profile " + targetUserId); } } finally { injectRestoreCallingIdentity(ident); } return true; private boolean canAccessProfile(int targetUserId, String message) { return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId, message, true); } @VisibleForTesting // We override it in unit tests Loading @@ -283,23 +256,6 @@ public class LauncherAppsService extends SystemService { } } /** * Checks if the user is enabled. */ private boolean isUserEnabled(UserHandle user) { return isUserEnabled(user.getIdentifier()); } private boolean isUserEnabled(int userId) { long ident = injectClearCallingIdentity(); try { UserInfo targetUserInfo = mUm.getUserInfo(userId); return targetUserInfo != null && targetUserInfo.isEnabled(); } finally { injectRestoreCallingIdentity(ident); } } @Override public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage, String packageName, UserHandle user) Loading @@ -315,10 +271,7 @@ public class LauncherAppsService extends SystemService { public ActivityInfo resolveActivity( String callingPackage, ComponentName component, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot resolve activity")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) { return null; } Loading Loading @@ -346,10 +299,7 @@ public class LauncherAppsService extends SystemService { private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, Intent intent, UserHandle user) { if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) { return null; } Loading @@ -372,11 +322,10 @@ public class LauncherAppsService extends SystemService { public IntentSender getShortcutConfigActivityIntent(String callingPackage, ComponentName component, UserHandle user) throws RemoteException { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, user, "Cannot check package")) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return null; } Preconditions.checkNotNull(component); Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); // All right, create the sender. Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); Loading @@ -395,10 +344,7 @@ public class LauncherAppsService extends SystemService { @Override public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot check package")) { return false; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return false; } Loading @@ -421,10 +367,7 @@ public class LauncherAppsService extends SystemService { public ApplicationInfo getApplicationInfo( String callingPackage, String packageName, int flags, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot check package")) { return null; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) { return null; } Loading Loading @@ -454,8 +397,7 @@ public class LauncherAppsService extends SystemService { String packageName, List shortcutIds, ComponentName componentName, int flags, UserHandle targetUser) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts") || !isUserEnabled(targetUser)) { if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) { return new ParceledListSlice<>(Collections.EMPTY_LIST); } if (shortcutIds != null && packageName == null) { Loading @@ -475,13 +417,9 @@ public class LauncherAppsService extends SystemService { public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle targetUser) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) { if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) { return; } if (!isUserEnabled(targetUser)) { throw new IllegalStateException("Cannot pin shortcuts for disabled profile " + targetUser); } mShortcutServiceInternal.pinShortcuts(getCallingUserId(), callingPackage, packageName, ids, targetUser.getIdentifier()); Loading @@ -491,10 +429,7 @@ public class LauncherAppsService extends SystemService { public int getShortcutIconResId(String callingPackage, String packageName, String id, int targetUserId) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { return 0; } if (!isUserEnabled(targetUserId)) { if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) { return 0; } Loading @@ -506,10 +441,7 @@ public class LauncherAppsService extends SystemService { public ParcelFileDescriptor getShortcutIconFd(String callingPackage, String packageName, String id, int targetUserId) { ensureShortcutPermission(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { return null; } if (!isUserEnabled(targetUserId)) { if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) { return null; } Loading @@ -528,13 +460,9 @@ public class LauncherAppsService extends SystemService { public boolean startShortcut(String callingPackage, String packageName, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage); if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) { if (!canAccessProfile(targetUserId, "Cannot start activity")) { return false; } if (!isUserEnabled(targetUserId)) { throw new IllegalStateException("Cannot start a shortcut for disabled profile " + targetUserId); } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), Loading Loading @@ -581,10 +509,7 @@ public class LauncherAppsService extends SystemService { public boolean isActivityEnabled( String callingPackage, ComponentName component, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage , user, "Cannot check component")) { return false; } if (!isUserEnabled(user)) { if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) { return false; } Loading @@ -607,12 +532,9 @@ public class LauncherAppsService extends SystemService { public void startActivityAsUser(String callingPackage, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot start activity")) { if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) { return; } if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot start activity for disabled profile " + user); } Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); Loading Loading @@ -665,13 +587,9 @@ public class LauncherAppsService extends SystemService { @Override public void showAppDetailsAsUser(String callingPackage, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { if (!canAccessProfile(callingPackage, user, "Cannot show app details")) { if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) { return; } if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot show app details for disabled profile " + user); } long ident = Binder.clearCallingIdentity(); try { Loading @@ -688,39 +606,10 @@ public class LauncherAppsService extends SystemService { /** Checks if user is a profile of or same as listeningUser. * and the user is enabled. */ private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user, String debugMsg) { if (user.getIdentifier() == listeningUser.getIdentifier()) { 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()); UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); if (userInfo == null || listeningUserInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || userInfo.profileGroupId != listeningUserInfo.profileGroupId || !userInfo.isEnabled()) { if (DEBUG) { Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" + debugMsg); } return false; } else { if (DEBUG) { Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" + debugMsg); } return true; } } finally { injectRestoreCallingIdentity(ident); } return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(), user.getIdentifier(), debugMsg, false); } @VisibleForTesting Loading @@ -740,7 +629,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue; try { listener.onPackageAdded(user, packageName); } catch (RemoteException re) { Loading @@ -762,7 +651,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue; try { listener.onPackageRemoved(user, packageName); } catch (RemoteException re) { Loading @@ -784,7 +673,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue; try { listener.onPackageChanged(user, packageName); } catch (RemoteException re) { Loading @@ -806,7 +695,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue; try { listener.onPackagesAvailable(user, packages, isReplacing()); } catch (RemoteException re) { Loading @@ -828,7 +717,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue; try { listener.onPackagesUnavailable(user, packages, isReplacing()); } catch (RemoteException re) { Loading @@ -850,7 +739,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue; try { listener.onPackagesSuspended(user, packages); } catch (RemoteException re) { Loading @@ -872,7 +761,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue; try { listener.onPackagesUnsuspended(user, packages); } catch (RemoteException re) { Loading Loading @@ -901,7 +790,7 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < n; i++) { IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue; final int launcherUserId = cookie.user.getIdentifier(); Loading
services/core/java/com/android/server/pm/ShortcutService.java +6 −16 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.text.TextUtils; import android.text.format.Time; import android.util.ArraySet; Loading Loading @@ -315,7 +315,7 @@ public class ShortcutService extends IShortcutService.Stub { private final IPackageManager mIPackageManager; private final PackageManagerInternal mPackageManagerInternal; private final UserManager mUserManager; private final UserManagerInternal mUserManagerInternal; private final UsageStatsManagerInternal mUsageStatsManagerInternal; private final ActivityManagerInternal mActivityManagerInternal; Loading Loading @@ -430,7 +430,8 @@ public class ShortcutService extends IShortcutService.Stub { mIPackageManager = AppGlobals.getPackageManager(); mPackageManagerInternal = Preconditions.checkNotNull( LocalServices.getService(PackageManagerInternal.class)); mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class)); mUserManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UserManagerInternal.class)); mUsageStatsManagerInternal = Preconditions.checkNotNull( LocalServices.getService(UsageStatsManagerInternal.class)); mActivityManagerInternal = Preconditions.checkNotNull( Loading Loading @@ -1176,12 +1177,7 @@ public class ShortcutService extends IShortcutService.Stub { // the user might just have been unlocked. // Note we just don't use isUserUnlockingOrUnlocked() here, because it'll return false // when the user is STOPPING, which we still want to consider as "unlocked". final long token = injectClearCallingIdentity(); try { return mUserManager.isUserUnlockingOrUnlocked(userId); } finally { injectRestoreCallingIdentity(token); } return mUserManagerInternal.isUserUnlockingOrUnlocked(userId); } // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L". Loading Loading @@ -3493,13 +3489,7 @@ public class ShortcutService extends IShortcutService.Stub { * itself. */ int getParentOrSelfUserId(int userId) { final long token = injectClearCallingIdentity(); try { final UserInfo parent = mUserManager.getProfileParent(userId); return (parent != null) ? parent.id : userId; } finally { injectRestoreCallingIdentity(token); } return mUserManagerInternal.getProfileParentId(userId); } void injectSendIntentSender(IntentSender intentSender, Intent extras) { Loading
services/core/java/com/android/server/pm/UserManagerService.java +51 −8 Original line number Diff line number Diff line Loading @@ -781,14 +781,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public int getProfileParentId(int userHandle) { checkManageUsersPermission("get the profile parent"); synchronized (mUsersLock) { UserInfo profileParent = getProfileParentLU(userHandle); if (profileParent == null) { return userHandle; } return profileParent.id; } return mLocalService.getProfileParentId(userHandle); } private UserInfo getProfileParentLU(int userHandle) { Loading Loading @@ -3928,6 +3921,56 @@ public class UserManagerService extends IUserManager.Stub { public boolean exists(int userId) { return getUserInfoNoChecks(userId) != null; } @Override public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException) { if (targetUserId == callingUserId) { return true; } synchronized (mUsersLock) { UserInfo callingUserInfo = getUserInfoLU(callingUserId); if (callingUserInfo == null || callingUserInfo.isManagedProfile()) { if (throwSecurityException) { throw new SecurityException( debugMsg + " for another profile " + targetUserId + " from " + callingUserId); } } UserInfo targetUserInfo = getUserInfoLU(targetUserId); if (targetUserInfo == null || !targetUserInfo.isEnabled()) { // Do not throw any exception here as this could happen due to race conditions // between the system updating its state and the client getting notified. if (throwSecurityException) { Slog.w(LOG_TAG, debugMsg + " for disabled profile " + targetUserId + " from " + callingUserId); } return false; } if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { if (throwSecurityException) { throw new SecurityException( debugMsg + " for unrelated profile " + targetUserId); } return false; } } return true; } @Override public int getProfileParentId(int userId) { synchronized (mUsersLock) { UserInfo profileParent = getProfileParentLU(userId); if (profileParent == null) { return userId; } return profileParent.id; } } } /* Remove all the users except of the system one. */ Loading