Loading core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,8 +45,19 @@ public abstract class ActivityManagerInternal { // Access modes for handleIncomingUser. public static final int ALLOW_NON_FULL = 0; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} * if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ public static final int ALLOW_NON_FULL_IN_PROFILE = 1; public static final int ALLOW_FULL_ONLY = 2; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} * or {@link android.Manifest.permission#INTERACT_ACROSS_USERS} if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ public static final int ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE = 3; /** * Verify that calling app has access to the given provider. Loading services/core/java/com/android/server/am/ActiveServices.java +1 −1 Original line number Diff line number Diff line Loading @@ -2068,7 +2068,7 @@ public final class ActiveServices { + " type=" + resolvedType + " callingUid=" + callingUid); userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE, "service", callingPackage); ServiceMap smap = getServiceMapLocked(userId); Loading services/core/java/com/android/server/am/UserController.java +28 −3 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server.am; import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM; import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP; import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; Loading Loading @@ -1641,9 +1643,10 @@ class UserController implements Handler.Callback { if (callingUid != 0 && callingUid != SYSTEM_UID) { final boolean allow; final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, targetUserId); if (mInjector.isCallerRecents(callingUid) && callingUserId == getCurrentUserId() && isSameProfileGroup(callingUserId, targetUserId)) { && isSameProfileGroup) { // If the caller is Recents and it is running in the current user, we then allow it // to access its profiles. allow = true; Loading @@ -1654,6 +1657,9 @@ class UserController implements Handler.Callback { } else if (allowMode == ALLOW_FULL_ONLY) { // We require full access, sucks to be you. allow = false; } else if (canInteractWithAcrossProfilesPermission( allowMode, isSameProfileGroup, callingPid, callingUid)) { allow = true; } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { // If the caller does not have either permission, they are always doomed. Loading @@ -1661,10 +1667,11 @@ class UserController implements Handler.Callback { } else if (allowMode == ALLOW_NON_FULL) { // We are blanket allowing non-full access, you lucky caller! allow = true; } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE || allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { // We may or may not allow this depending on whether the two users are // in the same profile. allow = isSameProfileGroup(callingUserId, targetUserId); allow = isSameProfileGroup; } else { throw new IllegalArgumentException("Unknown mode: " + allowMode); } Loading @@ -1690,6 +1697,11 @@ class UserController implements Handler.Callback { if (allowMode != ALLOW_FULL_ONLY) { builder.append(" or "); builder.append(INTERACT_ACROSS_USERS); if (isSameProfileGroup && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { builder.append(" or "); builder.append(INTERACT_ACROSS_PROFILES); } } String msg = builder.toString(); Slog.w(TAG, msg); Loading @@ -1710,6 +1722,19 @@ class UserController implements Handler.Callback { return targetUserId; } private boolean canInteractWithAcrossProfilesPermission( int allowMode, boolean isSameProfileGroup, int callingPid, int callingUid) { if (allowMode != ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { return false; } if (!isSameProfileGroup) { return false; } return mInjector.checkComponentPermission( INTERACT_ACROSS_PROFILES, callingPid, callingUid, /*owningUid= */-1, /*exported= */true) == PackageManager.PERMISSION_GRANTED; } int unsafeConvertIncomingUser(@UserIdInt int userId) { return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) ? getCurrentUserId(): userId; Loading services/core/java/com/android/server/pm/PackageManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -5344,8 +5344,9 @@ public class PackageManagerService extends IPackageManager.Stub if (!mUserManager.exists(userId)) return null; final int callingUid = Binder.getCallingUid(); flags = updateFlagsForComponent(flags, userId); mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get service info"); mPermissionManager.enforceCrossUserOrProfilePermission( callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get service info"); synchronized (mLock) { ParsedService s = mComponentResolver.getService(component); if (DEBUG_PACKAGE_INFO) Log.v( Loading Loading @@ -7795,8 +7796,10 @@ public class PackageManagerService extends IPackageManager.Stub String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps) { if (!mUserManager.exists(userId)) return Collections.emptyList(); mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, mPermissionManager.enforceCrossUserOrProfilePermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, "query intent receivers"); final String instantAppPkgName = getInstantAppPackageName(callingUid); flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps); services/core/java/com/android/server/pm/permission/PermissionManagerService.java +132 −14 Original line number Diff line number Diff line Loading @@ -4005,21 +4005,128 @@ public class PermissionManagerService extends IPermissionManager.Stub { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return; if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission( callingUid, callingUserId, userId, requireFullPermission, requirePermissionWhenSameUser)) { return; } String errorMessage = buildInvalidCrossUserPermissionMessage( message, requireFullPermission); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group * as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ private void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, /*requirePermissionWhenSameUser= */ false)) { return; } final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); if (isSameProfileGroup && hasPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES)) { return; } String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( message, requireFullPermission, isSameProfileGroup); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } private boolean hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { if (!requirePermissionWhenSameUser && userId == callingUserId) { return true; } if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { return true; } if (requireFullPermission) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); } else { return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); } return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); } private boolean hasPermission(String permission) { return mContext.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { final long identity = Binder.clearCallingIdentity(); try { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); } catch (SecurityException se) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, message); return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId); } finally { Binder.restoreCallingIdentity(identity); } } private static String buildInvalidCrossUserPermissionMessage( String message, boolean requireFullPermission) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("Requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (requireFullPermission) { builder.append("."); return builder.toString(); } builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); builder.append("."); return builder.toString(); } private static String buildInvalidCrossUserOrProfilePermissionMessage( String message, boolean requireFullPermission, boolean isSameProfileGroup) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("Requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (requireFullPermission) { builder.append("."); return builder.toString(); } builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); if (isSameProfileGroup) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES); } builder.append("."); return builder.toString(); } @GuardedBy({"mSettings.mLock", "mLock"}) Loading Loading @@ -4215,6 +4322,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, requirePermissionWhenSameUser, message); } @Override public void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserOrProfilePermission(callingUid, userId, requireFullPermission, checkShell, message); } @Override public void enforceGrantRevokeRuntimePermissionPermissions(String message) { PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message); Loading Loading
core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,8 +45,19 @@ public abstract class ActivityManagerInternal { // Access modes for handleIncomingUser. public static final int ALLOW_NON_FULL = 0; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} * if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ public static final int ALLOW_NON_FULL_IN_PROFILE = 1; public static final int ALLOW_FULL_ONLY = 2; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} * or {@link android.Manifest.permission#INTERACT_ACROSS_USERS} if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ public static final int ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE = 3; /** * Verify that calling app has access to the given provider. Loading
services/core/java/com/android/server/am/ActiveServices.java +1 −1 Original line number Diff line number Diff line Loading @@ -2068,7 +2068,7 @@ public final class ActiveServices { + " type=" + resolvedType + " callingUid=" + callingUid); userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE, "service", callingPackage); ServiceMap smap = getServiceMapLocked(userId); Loading
services/core/java/com/android/server/am/UserController.java +28 −3 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server.am; import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM; import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP; import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; Loading Loading @@ -1641,9 +1643,10 @@ class UserController implements Handler.Callback { if (callingUid != 0 && callingUid != SYSTEM_UID) { final boolean allow; final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, targetUserId); if (mInjector.isCallerRecents(callingUid) && callingUserId == getCurrentUserId() && isSameProfileGroup(callingUserId, targetUserId)) { && isSameProfileGroup) { // If the caller is Recents and it is running in the current user, we then allow it // to access its profiles. allow = true; Loading @@ -1654,6 +1657,9 @@ class UserController implements Handler.Callback { } else if (allowMode == ALLOW_FULL_ONLY) { // We require full access, sucks to be you. allow = false; } else if (canInteractWithAcrossProfilesPermission( allowMode, isSameProfileGroup, callingPid, callingUid)) { allow = true; } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { // If the caller does not have either permission, they are always doomed. Loading @@ -1661,10 +1667,11 @@ class UserController implements Handler.Callback { } else if (allowMode == ALLOW_NON_FULL) { // We are blanket allowing non-full access, you lucky caller! allow = true; } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE || allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { // We may or may not allow this depending on whether the two users are // in the same profile. allow = isSameProfileGroup(callingUserId, targetUserId); allow = isSameProfileGroup; } else { throw new IllegalArgumentException("Unknown mode: " + allowMode); } Loading @@ -1690,6 +1697,11 @@ class UserController implements Handler.Callback { if (allowMode != ALLOW_FULL_ONLY) { builder.append(" or "); builder.append(INTERACT_ACROSS_USERS); if (isSameProfileGroup && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { builder.append(" or "); builder.append(INTERACT_ACROSS_PROFILES); } } String msg = builder.toString(); Slog.w(TAG, msg); Loading @@ -1710,6 +1722,19 @@ class UserController implements Handler.Callback { return targetUserId; } private boolean canInteractWithAcrossProfilesPermission( int allowMode, boolean isSameProfileGroup, int callingPid, int callingUid) { if (allowMode != ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { return false; } if (!isSameProfileGroup) { return false; } return mInjector.checkComponentPermission( INTERACT_ACROSS_PROFILES, callingPid, callingUid, /*owningUid= */-1, /*exported= */true) == PackageManager.PERMISSION_GRANTED; } int unsafeConvertIncomingUser(@UserIdInt int userId) { return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) ? getCurrentUserId(): userId; Loading
services/core/java/com/android/server/pm/PackageManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -5344,8 +5344,9 @@ public class PackageManagerService extends IPackageManager.Stub if (!mUserManager.exists(userId)) return null; final int callingUid = Binder.getCallingUid(); flags = updateFlagsForComponent(flags, userId); mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get service info"); mPermissionManager.enforceCrossUserOrProfilePermission( callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get service info"); synchronized (mLock) { ParsedService s = mComponentResolver.getService(component); if (DEBUG_PACKAGE_INFO) Log.v( Loading Loading @@ -7795,8 +7796,10 @@ public class PackageManagerService extends IPackageManager.Stub String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps) { if (!mUserManager.exists(userId)) return Collections.emptyList(); mPermissionManager.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, mPermissionManager.enforceCrossUserOrProfilePermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, "query intent receivers"); final String instantAppPkgName = getInstantAppPackageName(callingUid); flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps);
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +132 −14 Original line number Diff line number Diff line Loading @@ -4005,21 +4005,128 @@ public class PermissionManagerService extends IPermissionManager.Stub { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return; if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission( callingUid, callingUserId, userId, requireFullPermission, requirePermissionWhenSameUser)) { return; } String errorMessage = buildInvalidCrossUserPermissionMessage( message, requireFullPermission); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group * as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ private void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, /*requirePermissionWhenSameUser= */ false)) { return; } final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); if (isSameProfileGroup && hasPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES)) { return; } String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( message, requireFullPermission, isSameProfileGroup); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } private boolean hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { if (!requirePermissionWhenSameUser && userId == callingUserId) { return true; } if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { return true; } if (requireFullPermission) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); } else { return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); } return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); } private boolean hasPermission(String permission) { return mContext.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { final long identity = Binder.clearCallingIdentity(); try { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); } catch (SecurityException se) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, message); return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId); } finally { Binder.restoreCallingIdentity(identity); } } private static String buildInvalidCrossUserPermissionMessage( String message, boolean requireFullPermission) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("Requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (requireFullPermission) { builder.append("."); return builder.toString(); } builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); builder.append("."); return builder.toString(); } private static String buildInvalidCrossUserOrProfilePermissionMessage( String message, boolean requireFullPermission, boolean isSameProfileGroup) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("Requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (requireFullPermission) { builder.append("."); return builder.toString(); } builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); if (isSameProfileGroup) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES); } builder.append("."); return builder.toString(); } @GuardedBy({"mSettings.mLock", "mLock"}) Loading Loading @@ -4215,6 +4322,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, requirePermissionWhenSameUser, message); } @Override public void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserOrProfilePermission(callingUid, userId, requireFullPermission, checkShell, message); } @Override public void enforceGrantRevokeRuntimePermissionPermissions(String message) { PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message); Loading