Loading core/java/android/content/pm/CrossProfileAppsInternal.java +10 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package android.content.pm; import android.annotation.UserIdInt; import android.os.UserHandle; import java.util.List; /** * Exposes internal methods from {@link com.android.server.pm.CrossProfileAppsServiceImpl} to other Loading Loading @@ -52,4 +55,11 @@ public abstract class CrossProfileAppsInternal { */ public abstract boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid); /** * Returns the list of target user profiles for the given package on the given user. See {@link * CrossProfileApps#getTargetUserProfiles()}. */ public abstract List<UserHandle> getTargetUserProfiles( String packageName, @UserIdInt int userId); } services/core/java/com/android/server/pm/CrossProfileAppsService.java +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.CrossProfileAppsInternal; import com.android.server.SystemService; Loading @@ -30,5 +31,6 @@ public class CrossProfileAppsService extends SystemService { @Override public void onStart() { publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl); publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService()); } } services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +35 −26 Original line number Diff line number Diff line Loading @@ -67,6 +67,8 @@ import java.util.Objects; public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { private static final String TAG = "CrossProfileAppsService"; private final LocalService mLocalService = new LocalService(); private Context mContext; private Injector mInjector; Loading @@ -78,8 +80,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { CrossProfileAppsServiceImpl(Context context, Injector injector) { mContext = context; mInjector = injector; LocalServices.addService(CrossProfileAppsInternal.class, new LocalService()); } @Override Loading Loading @@ -209,7 +209,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } if (callerUserId != userId) { if (!hasInteractAcrossProfilesPermission(callingPackage)) { if (!hasCallerGotInteractAcrossProfilesPermission(callingPackage)) { throw new SecurityException("Attempt to launch activity without required " + android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission" + " or target user is not in the same profile group."); Loading Loading @@ -280,20 +280,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (targetUserProfiles.isEmpty()) { return false; } return hasInteractAcrossProfilesPermission(callingPackage); return hasCallerGotInteractAcrossProfilesPermission(callingPackage); } private boolean hasInteractAcrossProfilesPermission(String callingPackage) { final int callingUid = mInjector.getCallingUid(); final int callingPid = mInjector.getCallingPid(); return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid) || PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, callingPid, callingUid, callingPackage) == PermissionChecker.PERMISSION_GRANTED; private boolean hasCallerGotInteractAcrossProfilesPermission(String callingPackage) { return hasInteractAcrossProfilesPermission( callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid()); } private boolean isCrossProfilePackageWhitelisted(String packageName) { Loading Loading @@ -575,6 +567,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op)); } CrossProfileAppsInternal getLocalService() { return mLocalService; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { return mInjector.withCleanCallingIdentity(() -> mInjector.getUserManager().isSameProfileGroup(callerUserId, userId)); Loading @@ -601,6 +597,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { -> mContext.getSystemService(UserManager.class).isManagedProfile(userId)); } private boolean hasInteractAcrossProfilesPermission(String packageName, int uid, int pid) { if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)) { return true; } return PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, pid, uid, packageName); } private static class InjectorImpl implements Injector { private Context mContext; Loading Loading @@ -740,9 +750,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } class LocalService extends CrossProfileAppsInternal { @Override public boolean verifyPackageHasInteractAcrossProfilePermission(String packageName, @UserIdInt int userId) throws PackageManager.NameNotFoundException { public boolean verifyPackageHasInteractAcrossProfilePermission( String packageName, @UserIdInt int userId) throws PackageManager.NameNotFoundException { final int uid = Objects.requireNonNull( mInjector.getPackageManager().getApplicationInfoAsUser( Objects.requireNonNull(packageName), /* flags= */ 0, userId)).uid; Loading @@ -752,16 +764,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { @Override public boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid) { Objects.requireNonNull(packageName); return hasInteractAcrossProfilesPermission( packageName, uid, PermissionChecker.PID_UNKNOWN); } return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid) || PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED; @Override public List<UserHandle> getTargetUserProfiles(String packageName, int userId) { return getTargetUserProfilesUnchecked(packageName, userId); } } } Loading
core/java/android/content/pm/CrossProfileAppsInternal.java +10 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package android.content.pm; import android.annotation.UserIdInt; import android.os.UserHandle; import java.util.List; /** * Exposes internal methods from {@link com.android.server.pm.CrossProfileAppsServiceImpl} to other Loading Loading @@ -52,4 +55,11 @@ public abstract class CrossProfileAppsInternal { */ public abstract boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid); /** * Returns the list of target user profiles for the given package on the given user. See {@link * CrossProfileApps#getTargetUserProfiles()}. */ public abstract List<UserHandle> getTargetUserProfiles( String packageName, @UserIdInt int userId); }
services/core/java/com/android/server/pm/CrossProfileAppsService.java +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.CrossProfileAppsInternal; import com.android.server.SystemService; Loading @@ -30,5 +31,6 @@ public class CrossProfileAppsService extends SystemService { @Override public void onStart() { publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl); publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService()); } }
services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +35 −26 Original line number Diff line number Diff line Loading @@ -67,6 +67,8 @@ import java.util.Objects; public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { private static final String TAG = "CrossProfileAppsService"; private final LocalService mLocalService = new LocalService(); private Context mContext; private Injector mInjector; Loading @@ -78,8 +80,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { CrossProfileAppsServiceImpl(Context context, Injector injector) { mContext = context; mInjector = injector; LocalServices.addService(CrossProfileAppsInternal.class, new LocalService()); } @Override Loading Loading @@ -209,7 +209,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } if (callerUserId != userId) { if (!hasInteractAcrossProfilesPermission(callingPackage)) { if (!hasCallerGotInteractAcrossProfilesPermission(callingPackage)) { throw new SecurityException("Attempt to launch activity without required " + android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission" + " or target user is not in the same profile group."); Loading Loading @@ -280,20 +280,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (targetUserProfiles.isEmpty()) { return false; } return hasInteractAcrossProfilesPermission(callingPackage); return hasCallerGotInteractAcrossProfilesPermission(callingPackage); } private boolean hasInteractAcrossProfilesPermission(String callingPackage) { final int callingUid = mInjector.getCallingUid(); final int callingPid = mInjector.getCallingPid(); return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid) || PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, callingPid, callingUid, callingPackage) == PermissionChecker.PERMISSION_GRANTED; private boolean hasCallerGotInteractAcrossProfilesPermission(String callingPackage) { return hasInteractAcrossProfilesPermission( callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid()); } private boolean isCrossProfilePackageWhitelisted(String packageName) { Loading Loading @@ -575,6 +567,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op)); } CrossProfileAppsInternal getLocalService() { return mLocalService; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { return mInjector.withCleanCallingIdentity(() -> mInjector.getUserManager().isSameProfileGroup(callerUserId, userId)); Loading @@ -601,6 +597,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { -> mContext.getSystemService(UserManager.class).isManagedProfile(userId)); } private boolean hasInteractAcrossProfilesPermission(String packageName, int uid, int pid) { if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)) { return true; } return PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, pid, uid, packageName); } private static class InjectorImpl implements Injector { private Context mContext; Loading Loading @@ -740,9 +750,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } class LocalService extends CrossProfileAppsInternal { @Override public boolean verifyPackageHasInteractAcrossProfilePermission(String packageName, @UserIdInt int userId) throws PackageManager.NameNotFoundException { public boolean verifyPackageHasInteractAcrossProfilePermission( String packageName, @UserIdInt int userId) throws PackageManager.NameNotFoundException { final int uid = Objects.requireNonNull( mInjector.getPackageManager().getApplicationInfoAsUser( Objects.requireNonNull(packageName), /* flags= */ 0, userId)).uid; Loading @@ -752,16 +764,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { @Override public boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid) { Objects.requireNonNull(packageName); return hasInteractAcrossProfilesPermission( packageName, uid, PermissionChecker.PID_UNKNOWN); } return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid) || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid) || PermissionChecker.checkPermissionForPreflight( mContext, Manifest.permission.INTERACT_ACROSS_PROFILES, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED; @Override public List<UserHandle> getTargetUserProfiles(String packageName, int userId) { return getTargetUserProfilesUnchecked(packageName, userId); } } }