Loading services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +59 −18 Original line number Diff line number Diff line Loading @@ -68,7 +68,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { private Context mContext; private Injector mInjector; private AppOpsManager mAppOpsManager; public CrossProfileAppsServiceImpl(Context context) { this(context, new InjectorImpl(context)); Loading Loading @@ -217,19 +216,27 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { mInjector.getActivityTaskManagerInternal().startActivityAsUser(caller, callingPackage, callingFeatureId, launchIntent, /* options= */ null, userId); logStartActivityByIntent(callingPackage); } private void logStartActivityByIntent(String packageName) { DevicePolicyEventLogger .createEvent(DevicePolicyEnums.START_ACTIVITY_BY_INTENT) .setStrings(packageName) .setBoolean(isCallingUserAManagedProfile()) .write(); } @Override public boolean canRequestInteractAcrossProfiles(String callingPackage) { Objects.requireNonNull(callingPackage); verifyCallingPackage(callingPackage); return canRequestInteractAcrossProfilesUnchecked( callingPackage, mInjector.getCallingUserId()); return canRequestInteractAcrossProfilesUnchecked(callingPackage); } private boolean canRequestInteractAcrossProfilesUnchecked( String packageName, @UserIdInt int userId) { List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, userId); private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) { List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, mInjector.getCallingUserId()); if (targetUserProfiles.isEmpty()) { return false; } Loading @@ -256,12 +263,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { Objects.requireNonNull(callingPackage); verifyCallingPackage(callingPackage); final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(callingPackage, mInjector.getCallingUserId()); final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked( callingPackage, mInjector.getCallingUserId()); if (targetUserProfiles.isEmpty()) { return false; } return hasInteractAcrossProfilesPermission(callingPackage); } Loading Loading @@ -363,6 +369,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { }); } /** * See {@link android.content.pm.CrossProfileApps#setInteractAcrossProfilesAppOp(String, int)}. * * <p>Logs metrics. Use {@link #setInteractAcrossProfilesAppOpUnchecked(String, int, boolean)} * to avoid permission checks or to specify not to log metrics. */ @Override public void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) { final int callingUid = mInjector.getCallingUid(); Loading @@ -379,6 +391,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { "MANAGE_APP_OPS_MODES or CONFIGURE_INTERACT_ACROSS_PROFILES is required to set" + " the app-op for interacting across profiles."); } setInteractAcrossProfilesAppOpUnchecked(packageName, newMode, /* logMetrics= */ true); } private void setInteractAcrossProfilesAppOpUnchecked( String packageName, @Mode int newMode, boolean logMetrics) { if (newMode == AppOpsManager.MODE_ALLOWED && !canConfigureInteractAcrossProfiles(packageName)) { // The user should not be prompted for apps that cannot request to interact across Loading @@ -394,7 +411,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (!isPackageInstalled(packageName, profileId)) { continue; } setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId); setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId, logMetrics); } } Loading @@ -413,16 +430,16 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } private void setInteractAcrossProfilesAppOpForUser( String packageName, @Mode int newMode, @UserIdInt int userId) { String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) { try { setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId); setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId, logMetrics); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Missing package " + packageName + " on user ID " + userId, e); } } private void setInteractAcrossProfilesAppOpForUserOrThrow( String packageName, @Mode int newMode, @UserIdInt int userId) String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) throws PackageManager.NameNotFoundException { final int uid = mInjector.getPackageManager() .getPackageUidAsUser(packageName, /* flags= */ 0, userId); Loading @@ -444,6 +461,28 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { .setMode(OP_INTERACT_ACROSS_PROFILES, uid, packageName, newMode); } sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId)); maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid); } private void maybeLogSetInteractAcrossProfilesAppOp( String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics, int uid) { if (!logMetrics) { return; } if (userId != mInjector.getCallingUserId()) { // Only log once per profile group by checking for the calling user ID. return; } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_INTERACT_ACROSS_PROFILES_APP_OP) .setStrings(packageName) .setInt(newMode) .setBoolean(appDeclaresCrossProfileAttribute(uid)) .write(); } /** Loading Loading @@ -541,11 +580,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { permission, uid, /* owningUid= */-1, /* exported= */ true); } private AppOpsManager getAppOpsManager() { if (mAppOpsManager == null) { mAppOpsManager = mContext.getSystemService(AppOpsManager.class); private boolean isCallingUserAManagedProfile() { return isManagedProfile(mInjector.getCallingUserId()); } return mAppOpsManager; private boolean isManagedProfile(@UserIdInt int userId) { return mInjector.withCleanCallingIdentity(() -> mContext.getSystemService(UserManager.class).isManagedProfile(userId)); } private static class InjectorImpl implements Injector { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -15230,15 +15230,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); previousCrossProfilePackages = admin.mCrossProfilePackages; if (packageNames.equals(previousCrossProfilePackages)) { return; } admin.mCrossProfilePackages = packageNames; saveSettingsLocked(mInjector.userHandleGetCallingUserId()); } logSetCrossProfilePackages(who, packageNames); final CrossProfileApps crossProfileApps = mContext.getSystemService(CrossProfileApps.class); mInjector.binderWithCleanCallingIdentity( () -> crossProfileApps.resetInteractAcrossProfilesAppOps( previousCrossProfilePackages, new HashSet<>(packageNames))); } private void logSetCrossProfilePackages(ComponentName who, List<String> packageNames) { DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_CROSS_PROFILE_PACKAGES) .setAdmin(who) .setStrings(packageNames.toArray(new String[packageNames.size()])) .write(); } @Override public List<String> getCrossProfilePackages(ComponentName who) { if (!mHasFeature) { Loading
services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +59 −18 Original line number Diff line number Diff line Loading @@ -68,7 +68,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { private Context mContext; private Injector mInjector; private AppOpsManager mAppOpsManager; public CrossProfileAppsServiceImpl(Context context) { this(context, new InjectorImpl(context)); Loading Loading @@ -217,19 +216,27 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { mInjector.getActivityTaskManagerInternal().startActivityAsUser(caller, callingPackage, callingFeatureId, launchIntent, /* options= */ null, userId); logStartActivityByIntent(callingPackage); } private void logStartActivityByIntent(String packageName) { DevicePolicyEventLogger .createEvent(DevicePolicyEnums.START_ACTIVITY_BY_INTENT) .setStrings(packageName) .setBoolean(isCallingUserAManagedProfile()) .write(); } @Override public boolean canRequestInteractAcrossProfiles(String callingPackage) { Objects.requireNonNull(callingPackage); verifyCallingPackage(callingPackage); return canRequestInteractAcrossProfilesUnchecked( callingPackage, mInjector.getCallingUserId()); return canRequestInteractAcrossProfilesUnchecked(callingPackage); } private boolean canRequestInteractAcrossProfilesUnchecked( String packageName, @UserIdInt int userId) { List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, userId); private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) { List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, mInjector.getCallingUserId()); if (targetUserProfiles.isEmpty()) { return false; } Loading @@ -256,12 +263,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { Objects.requireNonNull(callingPackage); verifyCallingPackage(callingPackage); final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(callingPackage, mInjector.getCallingUserId()); final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked( callingPackage, mInjector.getCallingUserId()); if (targetUserProfiles.isEmpty()) { return false; } return hasInteractAcrossProfilesPermission(callingPackage); } Loading Loading @@ -363,6 +369,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { }); } /** * See {@link android.content.pm.CrossProfileApps#setInteractAcrossProfilesAppOp(String, int)}. * * <p>Logs metrics. Use {@link #setInteractAcrossProfilesAppOpUnchecked(String, int, boolean)} * to avoid permission checks or to specify not to log metrics. */ @Override public void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) { final int callingUid = mInjector.getCallingUid(); Loading @@ -379,6 +391,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { "MANAGE_APP_OPS_MODES or CONFIGURE_INTERACT_ACROSS_PROFILES is required to set" + " the app-op for interacting across profiles."); } setInteractAcrossProfilesAppOpUnchecked(packageName, newMode, /* logMetrics= */ true); } private void setInteractAcrossProfilesAppOpUnchecked( String packageName, @Mode int newMode, boolean logMetrics) { if (newMode == AppOpsManager.MODE_ALLOWED && !canConfigureInteractAcrossProfiles(packageName)) { // The user should not be prompted for apps that cannot request to interact across Loading @@ -394,7 +411,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (!isPackageInstalled(packageName, profileId)) { continue; } setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId); setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId, logMetrics); } } Loading @@ -413,16 +430,16 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } private void setInteractAcrossProfilesAppOpForUser( String packageName, @Mode int newMode, @UserIdInt int userId) { String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) { try { setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId); setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId, logMetrics); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Missing package " + packageName + " on user ID " + userId, e); } } private void setInteractAcrossProfilesAppOpForUserOrThrow( String packageName, @Mode int newMode, @UserIdInt int userId) String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) throws PackageManager.NameNotFoundException { final int uid = mInjector.getPackageManager() .getPackageUidAsUser(packageName, /* flags= */ 0, userId); Loading @@ -444,6 +461,28 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { .setMode(OP_INTERACT_ACROSS_PROFILES, uid, packageName, newMode); } sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId)); maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid); } private void maybeLogSetInteractAcrossProfilesAppOp( String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics, int uid) { if (!logMetrics) { return; } if (userId != mInjector.getCallingUserId()) { // Only log once per profile group by checking for the calling user ID. return; } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_INTERACT_ACROSS_PROFILES_APP_OP) .setStrings(packageName) .setInt(newMode) .setBoolean(appDeclaresCrossProfileAttribute(uid)) .write(); } /** Loading Loading @@ -541,11 +580,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { permission, uid, /* owningUid= */-1, /* exported= */ true); } private AppOpsManager getAppOpsManager() { if (mAppOpsManager == null) { mAppOpsManager = mContext.getSystemService(AppOpsManager.class); private boolean isCallingUserAManagedProfile() { return isManagedProfile(mInjector.getCallingUserId()); } return mAppOpsManager; private boolean isManagedProfile(@UserIdInt int userId) { return mInjector.withCleanCallingIdentity(() -> mContext.getSystemService(UserManager.class).isManagedProfile(userId)); } private static class InjectorImpl implements Injector { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -15230,15 +15230,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); previousCrossProfilePackages = admin.mCrossProfilePackages; if (packageNames.equals(previousCrossProfilePackages)) { return; } admin.mCrossProfilePackages = packageNames; saveSettingsLocked(mInjector.userHandleGetCallingUserId()); } logSetCrossProfilePackages(who, packageNames); final CrossProfileApps crossProfileApps = mContext.getSystemService(CrossProfileApps.class); mInjector.binderWithCleanCallingIdentity( () -> crossProfileApps.resetInteractAcrossProfilesAppOps( previousCrossProfilePackages, new HashSet<>(packageNames))); } private void logSetCrossProfilePackages(ComponentName who, List<String> packageNames) { DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_CROSS_PROFILE_PACKAGES) .setAdmin(who) .setStrings(packageNames.toArray(new String[packageNames.size()])) .write(); } @Override public List<String> getCrossProfilePackages(ComponentName who) { if (!mHasFeature) {