Loading core/java/android/app/admin/DevicePolicyManagerInternal.java +14 −0 Original line number Diff line number Diff line Loading @@ -101,4 +101,18 @@ public abstract class DevicePolicyManagerInternal { * not enforced by the profile/device owner. */ public abstract Intent createUserRestrictionSupportIntent(int userId, String userRestriction); /** * Returns whether this user/profile is affiliated with the device. * * <p> * By definition, the user that the device owner runs on is always affiliated with the device. * Any other user/profile is considered affiliated with the device if the set specified by its * profile owner via {@link DevicePolicyManager#setAffiliationIds} intersects with the device * owner's. * <p> * Profile owner on the primary user will never be considered as affiliated as there is no * device owner to be affiliated with. */ public abstract boolean isUserAffiliatedWithDevice(int userId); } services/core/java/com/android/server/pm/PackageInstallerService.java +15 −9 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PackageDeleteObserver; import android.app.PackageInstallObserver; import android.app.admin.DevicePolicyManager; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.Intent; import android.content.IntentSender; Loading Loading @@ -704,20 +705,25 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mAppOps.checkPackage(callingUid, callerPackageName); } // Check whether the caller is device owner, in which case we do it silently. DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); boolean isDeviceOwner = (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser( callerPackageName); // Check whether the caller is device owner or affiliated profile owner, in which case we do // it silently. final int callingUserId = UserHandle.getUserId(callingUid); DevicePolicyManagerInternal dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); final boolean isDeviceOwnerOrAffiliatedProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) && dpmi.isUserAffiliatedWithDevice(callingUserId); final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, versionedPackage.getPackageName(), isDeviceOwner, userId); statusReceiver, versionedPackage.getPackageName(), isDeviceOwnerOrAffiliatedProfileOwner, userId); if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) { // Sweet, call straight through! mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags); } else if (isDeviceOwner) { // Allow the DeviceOwner to silently delete packages } else if (isDeviceOwnerOrAffiliatedProfileOwner) { // Allow the device owner and affiliated profile owner to silently delete packages // Need to clear the calling identity to get DELETE_PACKAGES permission long ident = Binder.clearCallingIdentity(); try { Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +15 −12 Original line number Diff line number Diff line Loading @@ -41,7 +41,8 @@ import static com.android.server.pm.PackageInstallerService.prepareStageDir; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.admin.DevicePolicyManager; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.Intent; import android.content.IntentSender; Loading Loading @@ -91,6 +92,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; Loading Loading @@ -311,14 +313,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; /** * @return {@code true} iff the installing is app an device owner? * @return {@code true} iff the installing is app an device owner or affiliated profile owner. */ private boolean isInstallerDeviceOwnerLocked() { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); return (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser( mInstallerPackageName); private boolean isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked() { DevicePolicyManagerInternal dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); return dpmi != null && dpmi.isActiveAdminWithPolicy(mInstallerUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) && dpmi.isUserAffiliatedWithDevice( userId); } /** Loading Loading @@ -347,10 +349,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final boolean forcePermissionPrompt = (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0; // Device owners are allowed to silently install packages, so the permission check is // waived if the installer is the device owner. // Device owners and affiliated profile owners are allowed to silently install packages, so // the permission check is waived if the installer is the device owner. return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot || isInstallerDeviceOwnerLocked()); || isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked()); } public PackageInstallerSession(PackageInstallerService.InternalCallback callback, Loading Loading @@ -705,7 +707,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { assertPreparedAndNotDestroyedLocked("commit"); final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter( mContext, statusReceiver, sessionId, isInstallerDeviceOwnerLocked(), userId); mContext, statusReceiver, sessionId, isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId); mRemoteObserver = adapter.getBinder(); if (forTransfer) { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +22 −4 Original line number Diff line number Diff line Loading @@ -6965,8 +6965,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } final int userId = mInjector.userHandleGetCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } long token = mInjector.binderClearCallingIdentity(); try { mLockPatternUtils.setDeviceOwnerInfo(info != null ? info.toString() : null); Loading Loading @@ -9258,10 +9263,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setKeyguardDisabled(ComponentName who, boolean disabled) { Preconditions.checkNotNull(who, "ComponentName is null"); final int userId = mInjector.userHandleGetCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } } final int userId = UserHandle.getCallingUserId(); long ident = mInjector.binderClearCallingIdentity(); try { Loading @@ -9283,7 +9292,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public boolean setStatusBarDisabled(ComponentName who, boolean disabled) { int userId = UserHandle.getCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } DevicePolicyData policy = getUserData(userId); if (policy.mStatusBarDisabled != disabled) { boolean isLockTaskMode = false; Loading Loading @@ -9548,6 +9561,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } return null; } @Override public boolean isUserAffiliatedWithDevice(int userId) { return DevicePolicyManagerService.this.isUserAffiliatedWithDeviceLocked(userId); } } private Intent createShowAdminSupportIntent(ComponentName admin, int userId) { Loading Loading
core/java/android/app/admin/DevicePolicyManagerInternal.java +14 −0 Original line number Diff line number Diff line Loading @@ -101,4 +101,18 @@ public abstract class DevicePolicyManagerInternal { * not enforced by the profile/device owner. */ public abstract Intent createUserRestrictionSupportIntent(int userId, String userRestriction); /** * Returns whether this user/profile is affiliated with the device. * * <p> * By definition, the user that the device owner runs on is always affiliated with the device. * Any other user/profile is considered affiliated with the device if the set specified by its * profile owner via {@link DevicePolicyManager#setAffiliationIds} intersects with the device * owner's. * <p> * Profile owner on the primary user will never be considered as affiliated as there is no * device owner to be affiliated with. */ public abstract boolean isUserAffiliatedWithDevice(int userId); }
services/core/java/com/android/server/pm/PackageInstallerService.java +15 −9 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PackageDeleteObserver; import android.app.PackageInstallObserver; import android.app.admin.DevicePolicyManager; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.Intent; import android.content.IntentSender; Loading Loading @@ -704,20 +705,25 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mAppOps.checkPackage(callingUid, callerPackageName); } // Check whether the caller is device owner, in which case we do it silently. DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); boolean isDeviceOwner = (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser( callerPackageName); // Check whether the caller is device owner or affiliated profile owner, in which case we do // it silently. final int callingUserId = UserHandle.getUserId(callingUid); DevicePolicyManagerInternal dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); final boolean isDeviceOwnerOrAffiliatedProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) && dpmi.isUserAffiliatedWithDevice(callingUserId); final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, versionedPackage.getPackageName(), isDeviceOwner, userId); statusReceiver, versionedPackage.getPackageName(), isDeviceOwnerOrAffiliatedProfileOwner, userId); if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) { // Sweet, call straight through! mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags); } else if (isDeviceOwner) { // Allow the DeviceOwner to silently delete packages } else if (isDeviceOwnerOrAffiliatedProfileOwner) { // Allow the device owner and affiliated profile owner to silently delete packages // Need to clear the calling identity to get DELETE_PACKAGES permission long ident = Binder.clearCallingIdentity(); try { Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +15 −12 Original line number Diff line number Diff line Loading @@ -41,7 +41,8 @@ import static com.android.server.pm.PackageInstallerService.prepareStageDir; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.admin.DevicePolicyManager; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.Intent; import android.content.IntentSender; Loading Loading @@ -91,6 +92,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; Loading Loading @@ -311,14 +313,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; /** * @return {@code true} iff the installing is app an device owner? * @return {@code true} iff the installing is app an device owner or affiliated profile owner. */ private boolean isInstallerDeviceOwnerLocked() { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); return (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser( mInstallerPackageName); private boolean isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked() { DevicePolicyManagerInternal dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); return dpmi != null && dpmi.isActiveAdminWithPolicy(mInstallerUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) && dpmi.isUserAffiliatedWithDevice( userId); } /** Loading Loading @@ -347,10 +349,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final boolean forcePermissionPrompt = (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0; // Device owners are allowed to silently install packages, so the permission check is // waived if the installer is the device owner. // Device owners and affiliated profile owners are allowed to silently install packages, so // the permission check is waived if the installer is the device owner. return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot || isInstallerDeviceOwnerLocked()); || isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked()); } public PackageInstallerSession(PackageInstallerService.InternalCallback callback, Loading Loading @@ -705,7 +707,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { assertPreparedAndNotDestroyedLocked("commit"); final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter( mContext, statusReceiver, sessionId, isInstallerDeviceOwnerLocked(), userId); mContext, statusReceiver, sessionId, isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId); mRemoteObserver = adapter.getBinder(); if (forTransfer) { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +22 −4 Original line number Diff line number Diff line Loading @@ -6965,8 +6965,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } final int userId = mInjector.userHandleGetCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } long token = mInjector.binderClearCallingIdentity(); try { mLockPatternUtils.setDeviceOwnerInfo(info != null ? info.toString() : null); Loading Loading @@ -9258,10 +9263,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setKeyguardDisabled(ComponentName who, boolean disabled) { Preconditions.checkNotNull(who, "ComponentName is null"); final int userId = mInjector.userHandleGetCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } } final int userId = UserHandle.getCallingUserId(); long ident = mInjector.binderClearCallingIdentity(); try { Loading @@ -9283,7 +9292,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public boolean setStatusBarDisabled(ComponentName who, boolean disabled) { int userId = UserHandle.getCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (!isUserAffiliatedWithDeviceLocked(userId)) { throw new SecurityException("Admin " + who + " is neither the device owner or affiliated user's profile owner."); } DevicePolicyData policy = getUserData(userId); if (policy.mStatusBarDisabled != disabled) { boolean isLockTaskMode = false; Loading Loading @@ -9548,6 +9561,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } return null; } @Override public boolean isUserAffiliatedWithDevice(int userId) { return DevicePolicyManagerService.this.isUserAffiliatedWithDeviceLocked(userId); } } private Intent createShowAdminSupportIntent(ComponentName admin, int userId) { Loading