Loading services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +35 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.stats.devicepolicy.DevicePolicyEnums; import android.text.TextUtils; import android.util.Slog; Loading Loading @@ -458,6 +459,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { + packageName + " on user ID " + userId); return; } final boolean hadPermission = hasInteractAcrossProfilesPermission( packageName, uid, PermissionChecker.PID_UNKNOWN); final int callingUid = mInjector.getCallingUid(); if (isPermissionGranted( Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) { Loading @@ -472,6 +477,22 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId)); maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid); maybeKillUid(packageName, uid, hadPermission); } /** * Kills the process represented by the given UID if it has lost the permission to * interact across profiles. */ private void maybeKillUid( String packageName, int uid, boolean hadPermission) { if (!hadPermission) { return; } if (hasInteractAcrossProfilesPermission(packageName, uid, PermissionChecker.PID_UNKNOWN)) { return; } mInjector.killUid(packageName, uid); } private void maybeLogSetInteractAcrossProfilesAppOp( Loading Loading @@ -774,6 +795,18 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @Override public void killUid(String packageName, int uid) { try { ActivityManager.getService().killApplication( packageName, UserHandle.getAppId(uid), UserHandle.getUserId(uid), PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED); } catch (RemoteException ignored) { } } } @VisibleForTesting Loading Loading @@ -813,6 +846,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { void sendBroadcastAsUser(Intent intent, UserHandle user); int checkComponentPermission(String permission, int uid, int owningUid, boolean exported); void killUid(String packageName, int uid); } class LocalService extends CrossProfileAppsInternal { Loading services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.os.Process; import android.os.UserHandle; Loading Loading @@ -106,6 +107,7 @@ public class CrossProfileAppsServiceImplRoboTest { new CrossProfileAppsServiceImpl(mContext, mInjector); private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>(); private final Map<Integer, List<ApplicationInfo>> installedApplications = new HashMap<>(); private final Set<Integer> mKilledUids = new HashSet<>(); @Mock private PackageManagerInternal mPackageManagerInternal; @Mock private IPackageManager mIPackageManager; Loading Loading @@ -388,6 +390,33 @@ public class CrossProfileAppsServiceImplRoboTest { assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isTrue(); } @Test public void setInteractAcrossProfilesAppOp_toAllowed_doesNotKillApp() { mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED); assertThat(mKilledUids).isEmpty(); } @Test public void setInteractAcrossProfilesAppOp_toDisallowed_killsAppsInBothProfiles() { shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo()); mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED); mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_DEFAULT); assertThat(mKilledUids).contains(WORK_PROFILE_UID); assertThat(mKilledUids).contains(PERSONAL_PROFILE_UID); } private PermissionInfo createCrossProfilesPermissionInfo() { PermissionInfo permissionInfo = new PermissionInfo(); permissionInfo.name = Manifest.permission.INTERACT_ACROSS_PROFILES; permissionInfo.protectionLevel = PermissionInfo.PROTECTION_FLAG_APPOP; return permissionInfo; } @Test public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() { mockUninstallCrossProfileAppFromWorkProfile(); Loading Loading @@ -678,5 +707,10 @@ public class CrossProfileAppsServiceImplRoboTest { // ShadowActivityThread with Robolectric. This method is currently not supported there. return mContext.checkPermission(permission, Process.myPid(), uid); } @Override public void killUid(String packageName, int uid) { mKilledUids.add(uid); } } } services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java +14 −0 Original line number Diff line number Diff line Loading @@ -32,8 +32,10 @@ import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; Loading Loading @@ -692,5 +694,17 @@ public class CrossProfileAppsServiceImplTest { String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @Override public void killUid(String packageName, int uid) { try { ActivityManager.getService().killApplication( packageName, UserHandle.getAppId(uid), UserHandle.getUserId(uid), PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED); } catch (RemoteException ignored) { } } } } Loading
services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +35 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.stats.devicepolicy.DevicePolicyEnums; import android.text.TextUtils; import android.util.Slog; Loading Loading @@ -458,6 +459,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { + packageName + " on user ID " + userId); return; } final boolean hadPermission = hasInteractAcrossProfilesPermission( packageName, uid, PermissionChecker.PID_UNKNOWN); final int callingUid = mInjector.getCallingUid(); if (isPermissionGranted( Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) { Loading @@ -472,6 +477,22 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId)); maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid); maybeKillUid(packageName, uid, hadPermission); } /** * Kills the process represented by the given UID if it has lost the permission to * interact across profiles. */ private void maybeKillUid( String packageName, int uid, boolean hadPermission) { if (!hadPermission) { return; } if (hasInteractAcrossProfilesPermission(packageName, uid, PermissionChecker.PID_UNKNOWN)) { return; } mInjector.killUid(packageName, uid); } private void maybeLogSetInteractAcrossProfilesAppOp( Loading Loading @@ -774,6 +795,18 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @Override public void killUid(String packageName, int uid) { try { ActivityManager.getService().killApplication( packageName, UserHandle.getAppId(uid), UserHandle.getUserId(uid), PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED); } catch (RemoteException ignored) { } } } @VisibleForTesting Loading Loading @@ -813,6 +846,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { void sendBroadcastAsUser(Intent intent, UserHandle user); int checkComponentPermission(String permission, int uid, int owningUid, boolean exported); void killUid(String packageName, int uid); } class LocalService extends CrossProfileAppsInternal { Loading
services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.os.Process; import android.os.UserHandle; Loading Loading @@ -106,6 +107,7 @@ public class CrossProfileAppsServiceImplRoboTest { new CrossProfileAppsServiceImpl(mContext, mInjector); private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>(); private final Map<Integer, List<ApplicationInfo>> installedApplications = new HashMap<>(); private final Set<Integer> mKilledUids = new HashSet<>(); @Mock private PackageManagerInternal mPackageManagerInternal; @Mock private IPackageManager mIPackageManager; Loading Loading @@ -388,6 +390,33 @@ public class CrossProfileAppsServiceImplRoboTest { assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isTrue(); } @Test public void setInteractAcrossProfilesAppOp_toAllowed_doesNotKillApp() { mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED); assertThat(mKilledUids).isEmpty(); } @Test public void setInteractAcrossProfilesAppOp_toDisallowed_killsAppsInBothProfiles() { shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo()); mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED); mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp( CROSS_PROFILE_APP_PACKAGE_NAME, MODE_DEFAULT); assertThat(mKilledUids).contains(WORK_PROFILE_UID); assertThat(mKilledUids).contains(PERSONAL_PROFILE_UID); } private PermissionInfo createCrossProfilesPermissionInfo() { PermissionInfo permissionInfo = new PermissionInfo(); permissionInfo.name = Manifest.permission.INTERACT_ACROSS_PROFILES; permissionInfo.protectionLevel = PermissionInfo.PROTECTION_FLAG_APPOP; return permissionInfo; } @Test public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() { mockUninstallCrossProfileAppFromWorkProfile(); Loading Loading @@ -678,5 +707,10 @@ public class CrossProfileAppsServiceImplRoboTest { // ShadowActivityThread with Robolectric. This method is currently not supported there. return mContext.checkPermission(permission, Process.myPid(), uid); } @Override public void killUid(String packageName, int uid) { mKilledUids.add(uid); } } }
services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java +14 −0 Original line number Diff line number Diff line Loading @@ -32,8 +32,10 @@ import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; Loading Loading @@ -692,5 +694,17 @@ public class CrossProfileAppsServiceImplTest { String permission, int uid, int owningUid, boolean exported) { return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @Override public void killUid(String packageName, int uid) { try { ActivityManager.getService().killApplication( packageName, UserHandle.getAppId(uid), UserHandle.getUserId(uid), PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED); } catch (RemoteException ignored) { } } } }