Loading cmds/dpm/src/com/android/commands/dpm/Dpm.java +21 −16 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public final class Dpm extends BaseCommand { private IDevicePolicyManager mDevicePolicyManager; private int mUserId = UserHandle.USER_SYSTEM; private String mName = ""; private ComponentName mComponent = null; @Override Loading @@ -52,8 +53,8 @@ public final class Dpm extends BaseCommand { "usage: dpm [subcommand] [options]\n" + "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + // STOPSHIP Finalize it "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] <COMPONENT>\n" + "usage: dpm set-profile-owner [ --user <USER_ID> ] <COMPONENT>\n" + "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] [ --name <NAME> ] <COMPONENT>\n" + "usage: dpm set-profile-owner [ --user <USER_ID> ] [ --name <NAME> ] <COMPONENT>\n" + "\n" + "dpm set-active-admin: Sets the given component as active admin" + " for an existing user.\n" + Loading Loading @@ -90,47 +91,51 @@ public final class Dpm extends BaseCommand { } } private void parseArgs(boolean canHaveUser) { String nextArg = nextArgRequired(); if (canHaveUser && "--user".equals(nextArg)) { private void parseArgs(boolean canHaveUser, boolean canHaveName) { String opt; while ((opt = nextOption()) != null) { if (canHaveUser && "--user".equals(opt)) { mUserId = parseInt(nextArgRequired()); nextArg = nextArgRequired(); } else if (canHaveName && "--name".equals(opt)) { mName = nextArgRequired(); } else { throw new IllegalArgumentException("Unknown option: " + opt); } mComponent = parseComponentName(nextArg); } mComponent = parseComponentName(nextArgRequired()); } private void runSetActiveAdmin() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ false); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); System.out.println("Success: Active admin set to component " + mComponent.toShortString()); } private void runSetDeviceOwner() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); String packageName = mComponent.getPackageName(); try { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/, mUserId)) { if (!mDevicePolicyManager.setDeviceOwner(mComponent, mName, mUserId)) { throw new RuntimeException( "Can't set package " + packageName + " as device owner."); "Can't set package " + mComponent + " as device owner."); } } catch (Exception e) { // Need to remove the admin that we just added. mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM); throw e; } System.out.println("Success: Device owner set to package " + packageName); System.out.println("Success: Device owner set to package " + mComponent); System.out.println("Active admin set to component " + mComponent.toShortString()); } private void runSetProfileOwner() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); try { if (!mDevicePolicyManager.setProfileOwner(mComponent, "" /*ownerName*/, mUserId)) { if (!mDevicePolicyManager.setProfileOwner(mComponent, mName, mUserId)) { throw new RuntimeException("Can't set component " + mComponent.toShortString() + " as profile owner for user " + mUserId); } Loading core/java/android/app/admin/DevicePolicyManager.java +53 −20 Original line number Diff line number Diff line Loading @@ -2573,28 +2573,28 @@ public class DevicePolicyManager { /** * @hide * Sets the given package as the device owner. * Same as {@link #setDeviceOwner(String, String)} but without setting a device owner name. * @param packageName the package name of the application to be registered as the device owner. * Same as {@link #setDeviceOwner(ComponentName, String)} but without setting a device owner name. * @param who the component name to be registered as device owner. * @return whether the package was successfully registered as the device owner. * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName) { return setDeviceOwner(packageName, null); public boolean setDeviceOwner(ComponentName who) { return setDeviceOwner(who, null); } /** * @hide */ public boolean setDeviceOwner(String packageName, int userId) { return setDeviceOwner(packageName, null, userId); public boolean setDeviceOwner(ComponentName who, int userId) { return setDeviceOwner(who, null, userId); } /** * @hide */ public boolean setDeviceOwner(String packageName, String ownerName) { return setDeviceOwner(packageName, ownerName, UserHandle.USER_SYSTEM); public boolean setDeviceOwner(ComponentName who, String ownerName) { return setDeviceOwner(who, ownerName, UserHandle.USER_SYSTEM); } /** Loading @@ -2605,18 +2605,18 @@ public class DevicePolicyManager { * this method. * Calling this after the setup phase of the primary user has completed is allowed only if * the caller is the shell uid, and there are no additional users and no accounts. * @param packageName the package name of the application to be registered as the device owner. * @param who the component name to be registered as device owner. * @param ownerName the human readable name of the institution that owns this device. * @param userId ID of the user on which the device owner runs. * @return whether the package was successfully registered as the device owner. * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName, String ownerName, int userId) public boolean setDeviceOwner(ComponentName who, String ownerName, int userId) throws IllegalArgumentException, IllegalStateException { if (mService != null) { try { return mService.setDeviceOwner(packageName, ownerName, userId); return mService.setDeviceOwner(who, ownerName, userId); } catch (RemoteException re) { Log.w(TAG, "Failed to set device owner"); } Loading @@ -2635,14 +2635,15 @@ public class DevicePolicyManager { * the setup process. * @param packageName the package name of the app, to compare with the registered device owner * app, if any. * @return whether or not the package is registered as the device owner app. * @return whether or not the package is registered as the device owner app. Note this method * does *not* check weather the device owner is actually running on the current user. */ public boolean isDeviceOwnerApp(String packageName) { if (mService != null) { try { return mService.isDeviceOwner(packageName); } catch (RemoteException re) { Log.w(TAG, "Failed to check device owner"); return mService.isDeviceOwnerPackage(packageName); } catch (RemoteException e) { Log.w(TAG, "Failed talking with device policy service", e); } } return false; Loading @@ -2656,6 +2657,17 @@ public class DevicePolicyManager { return isDeviceOwnerApp(packageName); } /** * Check whether a given component is registered as a device owner. * Note this method does *not* check weather the device owner is actually running on the current * user. * * @hide */ public boolean isDeviceOwner(ComponentName who) { return (who != null) && who.equals(getDeviceOwner()); } /** * Clears the current device owner. The caller must be the device owner. * Loading @@ -2675,12 +2687,28 @@ public class DevicePolicyManager { } } /** @hide */ /** * Returns the device owner package name. Note this method will still return the device owner * package name even if it's running on a different user. * * @hide */ @SystemApi public String getDeviceOwner() { final ComponentName componentName = getDeviceOwnerComponent(); return componentName == null ? null : componentName.getPackageName(); } /** * Returns the device owner name. Note this method will still return the device owner * name even if it's running on a different user. * * @hide */ public String getDeviceOwnerName() { if (mService != null) { try { return mService.getDeviceOwner(); return mService.getDeviceOwnerName(); } catch (RemoteException re) { Log.w(TAG, "Failed to get device owner"); } Loading @@ -2688,11 +2716,16 @@ public class DevicePolicyManager { return null; } /** @hide */ public String getDeviceOwnerName() { /** * Returns the device owner component name. Note this method will still return the device owner * component name even if it's running on a different user. * * @hide */ public ComponentName getDeviceOwnerComponent() { if (mService != null) { try { return mService.getDeviceOwnerName(); return mService.getDeviceOwner(); } catch (RemoteException re) { Log.w(TAG, "Failed to get device owner"); } Loading core/java/android/app/admin/IDevicePolicyManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -113,9 +113,9 @@ interface IDevicePolicyManager { void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); boolean setDeviceOwner(String packageName, String ownerName, int userId); boolean isDeviceOwner(String packageName); String getDeviceOwner(); boolean setDeviceOwner(in ComponentName who, String ownerName, int userId); boolean isDeviceOwnerPackage(String packageName); ComponentName getDeviceOwner(); String getDeviceOwnerName(); void clearDeviceOwner(String packageName); Loading services/core/java/com/android/server/pm/PackageManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -12860,9 +12860,11 @@ public class PackageManagerService extends IPackageManager.Stub { ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); try { if (dpm != null) { if (dpm.isDeviceOwner(packageName)) { // Does the package contains the device owner? if (dpm.isDeviceOwnerPackage(packageName)) { return true; } // Does it contain a device admin for any user? int[] users; if (userId == UserHandle.USER_ALL) { users = sUserManager.getUserIds(); services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +93 −29 Original line number Diff line number Diff line Loading @@ -1326,10 +1326,59 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void loadOwners() { synchronized (this) { mOwners.load(); findOwnerComponentIfNecessaryLocked(); // TODO PO may not have a class name either due to b/17652534. Address that too. updateDeviceOwnerLocked(); } } private void findOwnerComponentIfNecessaryLocked() { if (!mOwners.hasDeviceOwner()) { return; } final ComponentName doComponentName = mOwners.getDeviceOwnerComponent(); if (!TextUtils.isEmpty(doComponentName.getClassName())) { return; // Already a full component name. } final ComponentName doComponent = findAdminComponentWithPackageLocked( doComponentName.getPackageName(), mOwners.getDeviceOwnerUserId()); if (doComponent == null) { Slog.e(LOG_TAG, "Device-owner isn't registered as device-admin"); } else { mOwners.setDeviceOwner( doComponent, mOwners.getDeviceOwnerName(), mOwners.getDeviceOwnerUserId()); mOwners.writeDeviceOwner(); } } private ComponentName findAdminComponentWithPackageLocked(String packageName, int userId) { final DevicePolicyData policy = getUserData(userId); final int n = policy.mAdminList.size(); ComponentName found = null; int nFound = 0; for (int i = 0; i < n; i++) { final ActiveAdmin admin = policy.mAdminList.get(i); if (packageName.equals(admin.info.getPackageName())) { // Found! if (nFound == 0) { found = admin.info.getComponent(); } nFound++; } } if (nFound > 0) { Slog.w(LOG_TAG, "Multiple DA found; assume the first one is DO."); } return found; } /** * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration * reminders. Clears alarm if no expirations are configured. Loading Loading @@ -1440,9 +1489,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, @VisibleForTesting boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, int userId) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsDevice = isDeviceOwner(admin.info.getComponent()); boolean ownsProfile = (getProfileOwner(userId) != null && getProfileOwner(userId).getPackageName() .equals(admin.info.getPackageName())); Loading Loading @@ -1880,8 +1930,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void updateDeviceOwnerLocked() { long ident = mInjector.binderClearCallingIdentity(); try { if (getDeviceOwner() != null) { mInjector.getIActivityManager() .updateDeviceOwner(getDeviceOwner()); .updateDeviceOwner(getDeviceOwner().getPackageName()); } } catch (RemoteException e) { // Not gonna happen. } finally { Loading Loading @@ -1945,7 +1997,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public void systemReady(int phase) { @VisibleForTesting void systemReady(int phase) { if (!mHasFeature) { return; } Loading Loading @@ -2284,7 +2337,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (admin.getUid() != mInjector.binderGetCallingUid()) { // Active device owners must remain active admins. if (isDeviceOwner(adminReceiver.getPackageName())) { if (isDeviceOwner(adminReceiver)) { return; } mContext.enforceCallingOrSelfPermission( Loading Loading @@ -3544,7 +3597,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { if ((flags & WIPE_RESET_PROTECTION_DATA) != 0) { if (userHandle != UserHandle.USER_SYSTEM || !isDeviceOwner(admin.info.getPackageName())) { || !isDeviceOwner(admin.info.getComponent())) { throw new SecurityException( "Only device owner admins can set WIPE_RESET_PROTECTION_DATA"); } Loading Loading @@ -4293,13 +4346,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean setDeviceOwner(String packageName, String ownerName, int userId) { public boolean setDeviceOwner(ComponentName admin, String ownerName, int userId) { if (!mHasFeature) { return false; } if (packageName == null || !isPackageInstalledForUser(packageName, userId)) { throw new IllegalArgumentException("Invalid package name " + packageName if (admin == null || !isPackageInstalledForUser(admin.getPackageName(), userId)) { throw new IllegalArgumentException("Invalid component " + admin + " for device owner"); } synchronized (this) { Loading @@ -4315,7 +4368,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mInjector.binderRestoreCallingIdentity(ident); } mOwners.setDeviceOwner(packageName, ownerName, userId); mOwners.setDeviceOwner(admin, ownerName, userId); mOwners.writeDeviceOwner(); updateDeviceOwnerLocked(); Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED); Loading @@ -4331,24 +4384,33 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public boolean isDeviceOwner(ComponentName who) { if (!mHasFeature) { return false; } synchronized (this) { return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerComponent().equals(who); } } @Override public boolean isDeviceOwner(String packageName) { public boolean isDeviceOwnerPackage(String packageName) { if (!mHasFeature) { return false; } synchronized (this) { return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerPackageName().equals(packageName); && mOwners.getDeviceOwnerComponent().getPackageName().equals(packageName); } } @Override public String getDeviceOwner() { public ComponentName getDeviceOwner() { if (!mHasFeature) { return null; } synchronized (this) { return mOwners.getDeviceOwnerPackageName(); return mOwners.getDeviceOwnerComponent(); } } Loading @@ -4373,16 +4435,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Returns the active device owner or null if there is no device owner. @VisibleForTesting ActiveAdmin getDeviceOwnerAdminLocked() { String deviceOwnerPackageName = getDeviceOwner(); if (deviceOwnerPackageName == null) { ComponentName component = getDeviceOwner(); if (component == null) { return null; } DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); DevicePolicyData policy = getUserData(mOwners.getDeviceOwnerUserId()); final int n = policy.mAdminList.size(); for (int i = 0; i < n; i++) { ActiveAdmin admin = policy.mAdminList.get(i); if (deviceOwnerPackageName.equals(admin.info.getPackageName())) { if (component.equals(admin.info.getComponent())) { return admin; } } Loading @@ -4392,15 +4454,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void clearDeviceOwner(String packageName) { Preconditions.checkNotNull(packageName, "packageName is null"); final int callingUid = mInjector.binderGetCallingUid(); try { int uid = mContext.getPackageManager().getPackageUid(packageName, 0); if (uid != mInjector.binderGetCallingUid()) { if (uid != callingUid) { throw new SecurityException("Invalid packageName"); } } catch (NameNotFoundException e) { throw new SecurityException(e); } if (!isDeviceOwner(packageName)) { if (!mOwners.hasDeviceOwner() || !getDeviceOwner().getPackageName().equals(packageName) || (mOwners.getDeviceOwnerUserId() != UserHandle.getUserId(callingUid))) { throw new SecurityException("clearDeviceOwner can only be called by the device owner"); } synchronized (this) { Loading Loading @@ -5443,7 +5507,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName()); boolean isDeviceOwner = isDeviceOwner(who); if (!isDeviceOwner && userHandle != UserHandle.USER_SYSTEM && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) { throw new SecurityException("Profile owners cannot set user restriction " + key); Loading Loading @@ -5976,7 +6040,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Bundle adminExtras = new Bundle(); adminExtras.putString(DeviceAdminReceiver.EXTRA_LOCK_TASK_PACKAGE, pkg); for (ActiveAdmin admin : policy.mAdminList) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsDevice = isDeviceOwner(admin.info.getComponent()); boolean ownsProfile = (getProfileOwner(userHandle) != null && getProfileOwner(userHandle).equals(admin.info.getPackageName())); if (ownsDevice || ownsProfile) { Loading Loading @@ -6034,10 +6098,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final ContentResolver contentResolver = mContext.getContentResolver(); synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (isDeviceOwner(activeAdmin.info.getPackageName())) { if (isDeviceOwner(who)) { if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) { throw new SecurityException(String.format( "Permission denial: Device owners cannot update %1$s", setting)); Loading Loading @@ -6320,7 +6383,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private boolean isCallerDeviceOwner(int callerUid) { String[] pkgs = mContext.getPackageManager().getPackagesForUid(callerUid); for (String pkg : pkgs) { if (isDeviceOwner(pkg)) { if (isDeviceOwnerPackage(pkg)) { return true; } } Loading @@ -6342,7 +6405,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateReceivedTime); synchronized (this) { String deviceOwnerPackage = getDeviceOwner(); final String deviceOwnerPackage = getDeviceOwner() == null ? null : getDeviceOwner().getPackageName(); if (deviceOwnerPackage == null) { return; } Loading Loading
cmds/dpm/src/com/android/commands/dpm/Dpm.java +21 −16 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public final class Dpm extends BaseCommand { private IDevicePolicyManager mDevicePolicyManager; private int mUserId = UserHandle.USER_SYSTEM; private String mName = ""; private ComponentName mComponent = null; @Override Loading @@ -52,8 +53,8 @@ public final class Dpm extends BaseCommand { "usage: dpm [subcommand] [options]\n" + "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + // STOPSHIP Finalize it "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] <COMPONENT>\n" + "usage: dpm set-profile-owner [ --user <USER_ID> ] <COMPONENT>\n" + "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] [ --name <NAME> ] <COMPONENT>\n" + "usage: dpm set-profile-owner [ --user <USER_ID> ] [ --name <NAME> ] <COMPONENT>\n" + "\n" + "dpm set-active-admin: Sets the given component as active admin" + " for an existing user.\n" + Loading Loading @@ -90,47 +91,51 @@ public final class Dpm extends BaseCommand { } } private void parseArgs(boolean canHaveUser) { String nextArg = nextArgRequired(); if (canHaveUser && "--user".equals(nextArg)) { private void parseArgs(boolean canHaveUser, boolean canHaveName) { String opt; while ((opt = nextOption()) != null) { if (canHaveUser && "--user".equals(opt)) { mUserId = parseInt(nextArgRequired()); nextArg = nextArgRequired(); } else if (canHaveName && "--name".equals(opt)) { mName = nextArgRequired(); } else { throw new IllegalArgumentException("Unknown option: " + opt); } mComponent = parseComponentName(nextArg); } mComponent = parseComponentName(nextArgRequired()); } private void runSetActiveAdmin() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ false); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); System.out.println("Success: Active admin set to component " + mComponent.toShortString()); } private void runSetDeviceOwner() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); String packageName = mComponent.getPackageName(); try { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/, mUserId)) { if (!mDevicePolicyManager.setDeviceOwner(mComponent, mName, mUserId)) { throw new RuntimeException( "Can't set package " + packageName + " as device owner."); "Can't set package " + mComponent + " as device owner."); } } catch (Exception e) { // Need to remove the admin that we just added. mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM); throw e; } System.out.println("Success: Device owner set to package " + packageName); System.out.println("Success: Device owner set to package " + mComponent); System.out.println("Active admin set to component " + mComponent.toShortString()); } private void runSetProfileOwner() throws RemoteException { parseArgs(true); parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); try { if (!mDevicePolicyManager.setProfileOwner(mComponent, "" /*ownerName*/, mUserId)) { if (!mDevicePolicyManager.setProfileOwner(mComponent, mName, mUserId)) { throw new RuntimeException("Can't set component " + mComponent.toShortString() + " as profile owner for user " + mUserId); } Loading
core/java/android/app/admin/DevicePolicyManager.java +53 −20 Original line number Diff line number Diff line Loading @@ -2573,28 +2573,28 @@ public class DevicePolicyManager { /** * @hide * Sets the given package as the device owner. * Same as {@link #setDeviceOwner(String, String)} but without setting a device owner name. * @param packageName the package name of the application to be registered as the device owner. * Same as {@link #setDeviceOwner(ComponentName, String)} but without setting a device owner name. * @param who the component name to be registered as device owner. * @return whether the package was successfully registered as the device owner. * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName) { return setDeviceOwner(packageName, null); public boolean setDeviceOwner(ComponentName who) { return setDeviceOwner(who, null); } /** * @hide */ public boolean setDeviceOwner(String packageName, int userId) { return setDeviceOwner(packageName, null, userId); public boolean setDeviceOwner(ComponentName who, int userId) { return setDeviceOwner(who, null, userId); } /** * @hide */ public boolean setDeviceOwner(String packageName, String ownerName) { return setDeviceOwner(packageName, ownerName, UserHandle.USER_SYSTEM); public boolean setDeviceOwner(ComponentName who, String ownerName) { return setDeviceOwner(who, ownerName, UserHandle.USER_SYSTEM); } /** Loading @@ -2605,18 +2605,18 @@ public class DevicePolicyManager { * this method. * Calling this after the setup phase of the primary user has completed is allowed only if * the caller is the shell uid, and there are no additional users and no accounts. * @param packageName the package name of the application to be registered as the device owner. * @param who the component name to be registered as device owner. * @param ownerName the human readable name of the institution that owns this device. * @param userId ID of the user on which the device owner runs. * @return whether the package was successfully registered as the device owner. * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName, String ownerName, int userId) public boolean setDeviceOwner(ComponentName who, String ownerName, int userId) throws IllegalArgumentException, IllegalStateException { if (mService != null) { try { return mService.setDeviceOwner(packageName, ownerName, userId); return mService.setDeviceOwner(who, ownerName, userId); } catch (RemoteException re) { Log.w(TAG, "Failed to set device owner"); } Loading @@ -2635,14 +2635,15 @@ public class DevicePolicyManager { * the setup process. * @param packageName the package name of the app, to compare with the registered device owner * app, if any. * @return whether or not the package is registered as the device owner app. * @return whether or not the package is registered as the device owner app. Note this method * does *not* check weather the device owner is actually running on the current user. */ public boolean isDeviceOwnerApp(String packageName) { if (mService != null) { try { return mService.isDeviceOwner(packageName); } catch (RemoteException re) { Log.w(TAG, "Failed to check device owner"); return mService.isDeviceOwnerPackage(packageName); } catch (RemoteException e) { Log.w(TAG, "Failed talking with device policy service", e); } } return false; Loading @@ -2656,6 +2657,17 @@ public class DevicePolicyManager { return isDeviceOwnerApp(packageName); } /** * Check whether a given component is registered as a device owner. * Note this method does *not* check weather the device owner is actually running on the current * user. * * @hide */ public boolean isDeviceOwner(ComponentName who) { return (who != null) && who.equals(getDeviceOwner()); } /** * Clears the current device owner. The caller must be the device owner. * Loading @@ -2675,12 +2687,28 @@ public class DevicePolicyManager { } } /** @hide */ /** * Returns the device owner package name. Note this method will still return the device owner * package name even if it's running on a different user. * * @hide */ @SystemApi public String getDeviceOwner() { final ComponentName componentName = getDeviceOwnerComponent(); return componentName == null ? null : componentName.getPackageName(); } /** * Returns the device owner name. Note this method will still return the device owner * name even if it's running on a different user. * * @hide */ public String getDeviceOwnerName() { if (mService != null) { try { return mService.getDeviceOwner(); return mService.getDeviceOwnerName(); } catch (RemoteException re) { Log.w(TAG, "Failed to get device owner"); } Loading @@ -2688,11 +2716,16 @@ public class DevicePolicyManager { return null; } /** @hide */ public String getDeviceOwnerName() { /** * Returns the device owner component name. Note this method will still return the device owner * component name even if it's running on a different user. * * @hide */ public ComponentName getDeviceOwnerComponent() { if (mService != null) { try { return mService.getDeviceOwnerName(); return mService.getDeviceOwner(); } catch (RemoteException re) { Log.w(TAG, "Failed to get device owner"); } Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -113,9 +113,9 @@ interface IDevicePolicyManager { void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); boolean setDeviceOwner(String packageName, String ownerName, int userId); boolean isDeviceOwner(String packageName); String getDeviceOwner(); boolean setDeviceOwner(in ComponentName who, String ownerName, int userId); boolean isDeviceOwnerPackage(String packageName); ComponentName getDeviceOwner(); String getDeviceOwnerName(); void clearDeviceOwner(String packageName); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -12860,9 +12860,11 @@ public class PackageManagerService extends IPackageManager.Stub { ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); try { if (dpm != null) { if (dpm.isDeviceOwner(packageName)) { // Does the package contains the device owner? if (dpm.isDeviceOwnerPackage(packageName)) { return true; } // Does it contain a device admin for any user? int[] users; if (userId == UserHandle.USER_ALL) { users = sUserManager.getUserIds();
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +93 −29 Original line number Diff line number Diff line Loading @@ -1326,10 +1326,59 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void loadOwners() { synchronized (this) { mOwners.load(); findOwnerComponentIfNecessaryLocked(); // TODO PO may not have a class name either due to b/17652534. Address that too. updateDeviceOwnerLocked(); } } private void findOwnerComponentIfNecessaryLocked() { if (!mOwners.hasDeviceOwner()) { return; } final ComponentName doComponentName = mOwners.getDeviceOwnerComponent(); if (!TextUtils.isEmpty(doComponentName.getClassName())) { return; // Already a full component name. } final ComponentName doComponent = findAdminComponentWithPackageLocked( doComponentName.getPackageName(), mOwners.getDeviceOwnerUserId()); if (doComponent == null) { Slog.e(LOG_TAG, "Device-owner isn't registered as device-admin"); } else { mOwners.setDeviceOwner( doComponent, mOwners.getDeviceOwnerName(), mOwners.getDeviceOwnerUserId()); mOwners.writeDeviceOwner(); } } private ComponentName findAdminComponentWithPackageLocked(String packageName, int userId) { final DevicePolicyData policy = getUserData(userId); final int n = policy.mAdminList.size(); ComponentName found = null; int nFound = 0; for (int i = 0; i < n; i++) { final ActiveAdmin admin = policy.mAdminList.get(i); if (packageName.equals(admin.info.getPackageName())) { // Found! if (nFound == 0) { found = admin.info.getComponent(); } nFound++; } } if (nFound > 0) { Slog.w(LOG_TAG, "Multiple DA found; assume the first one is DO."); } return found; } /** * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration * reminders. Clears alarm if no expirations are configured. Loading Loading @@ -1440,9 +1489,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, @VisibleForTesting boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, int userId) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsDevice = isDeviceOwner(admin.info.getComponent()); boolean ownsProfile = (getProfileOwner(userId) != null && getProfileOwner(userId).getPackageName() .equals(admin.info.getPackageName())); Loading Loading @@ -1880,8 +1930,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void updateDeviceOwnerLocked() { long ident = mInjector.binderClearCallingIdentity(); try { if (getDeviceOwner() != null) { mInjector.getIActivityManager() .updateDeviceOwner(getDeviceOwner()); .updateDeviceOwner(getDeviceOwner().getPackageName()); } } catch (RemoteException e) { // Not gonna happen. } finally { Loading Loading @@ -1945,7 +1997,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public void systemReady(int phase) { @VisibleForTesting void systemReady(int phase) { if (!mHasFeature) { return; } Loading Loading @@ -2284,7 +2337,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (admin.getUid() != mInjector.binderGetCallingUid()) { // Active device owners must remain active admins. if (isDeviceOwner(adminReceiver.getPackageName())) { if (isDeviceOwner(adminReceiver)) { return; } mContext.enforceCallingOrSelfPermission( Loading Loading @@ -3544,7 +3597,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { if ((flags & WIPE_RESET_PROTECTION_DATA) != 0) { if (userHandle != UserHandle.USER_SYSTEM || !isDeviceOwner(admin.info.getPackageName())) { || !isDeviceOwner(admin.info.getComponent())) { throw new SecurityException( "Only device owner admins can set WIPE_RESET_PROTECTION_DATA"); } Loading Loading @@ -4293,13 +4346,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean setDeviceOwner(String packageName, String ownerName, int userId) { public boolean setDeviceOwner(ComponentName admin, String ownerName, int userId) { if (!mHasFeature) { return false; } if (packageName == null || !isPackageInstalledForUser(packageName, userId)) { throw new IllegalArgumentException("Invalid package name " + packageName if (admin == null || !isPackageInstalledForUser(admin.getPackageName(), userId)) { throw new IllegalArgumentException("Invalid component " + admin + " for device owner"); } synchronized (this) { Loading @@ -4315,7 +4368,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mInjector.binderRestoreCallingIdentity(ident); } mOwners.setDeviceOwner(packageName, ownerName, userId); mOwners.setDeviceOwner(admin, ownerName, userId); mOwners.writeDeviceOwner(); updateDeviceOwnerLocked(); Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED); Loading @@ -4331,24 +4384,33 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public boolean isDeviceOwner(ComponentName who) { if (!mHasFeature) { return false; } synchronized (this) { return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerComponent().equals(who); } } @Override public boolean isDeviceOwner(String packageName) { public boolean isDeviceOwnerPackage(String packageName) { if (!mHasFeature) { return false; } synchronized (this) { return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerPackageName().equals(packageName); && mOwners.getDeviceOwnerComponent().getPackageName().equals(packageName); } } @Override public String getDeviceOwner() { public ComponentName getDeviceOwner() { if (!mHasFeature) { return null; } synchronized (this) { return mOwners.getDeviceOwnerPackageName(); return mOwners.getDeviceOwnerComponent(); } } Loading @@ -4373,16 +4435,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Returns the active device owner or null if there is no device owner. @VisibleForTesting ActiveAdmin getDeviceOwnerAdminLocked() { String deviceOwnerPackageName = getDeviceOwner(); if (deviceOwnerPackageName == null) { ComponentName component = getDeviceOwner(); if (component == null) { return null; } DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); DevicePolicyData policy = getUserData(mOwners.getDeviceOwnerUserId()); final int n = policy.mAdminList.size(); for (int i = 0; i < n; i++) { ActiveAdmin admin = policy.mAdminList.get(i); if (deviceOwnerPackageName.equals(admin.info.getPackageName())) { if (component.equals(admin.info.getComponent())) { return admin; } } Loading @@ -4392,15 +4454,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void clearDeviceOwner(String packageName) { Preconditions.checkNotNull(packageName, "packageName is null"); final int callingUid = mInjector.binderGetCallingUid(); try { int uid = mContext.getPackageManager().getPackageUid(packageName, 0); if (uid != mInjector.binderGetCallingUid()) { if (uid != callingUid) { throw new SecurityException("Invalid packageName"); } } catch (NameNotFoundException e) { throw new SecurityException(e); } if (!isDeviceOwner(packageName)) { if (!mOwners.hasDeviceOwner() || !getDeviceOwner().getPackageName().equals(packageName) || (mOwners.getDeviceOwnerUserId() != UserHandle.getUserId(callingUid))) { throw new SecurityException("clearDeviceOwner can only be called by the device owner"); } synchronized (this) { Loading Loading @@ -5443,7 +5507,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName()); boolean isDeviceOwner = isDeviceOwner(who); if (!isDeviceOwner && userHandle != UserHandle.USER_SYSTEM && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) { throw new SecurityException("Profile owners cannot set user restriction " + key); Loading Loading @@ -5976,7 +6040,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Bundle adminExtras = new Bundle(); adminExtras.putString(DeviceAdminReceiver.EXTRA_LOCK_TASK_PACKAGE, pkg); for (ActiveAdmin admin : policy.mAdminList) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsDevice = isDeviceOwner(admin.info.getComponent()); boolean ownsProfile = (getProfileOwner(userHandle) != null && getProfileOwner(userHandle).equals(admin.info.getPackageName())); if (ownsDevice || ownsProfile) { Loading Loading @@ -6034,10 +6098,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final ContentResolver contentResolver = mContext.getContentResolver(); synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (isDeviceOwner(activeAdmin.info.getPackageName())) { if (isDeviceOwner(who)) { if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) { throw new SecurityException(String.format( "Permission denial: Device owners cannot update %1$s", setting)); Loading Loading @@ -6320,7 +6383,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private boolean isCallerDeviceOwner(int callerUid) { String[] pkgs = mContext.getPackageManager().getPackagesForUid(callerUid); for (String pkg : pkgs) { if (isDeviceOwner(pkg)) { if (isDeviceOwnerPackage(pkg)) { return true; } } Loading @@ -6342,7 +6405,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateReceivedTime); synchronized (this) { String deviceOwnerPackage = getDeviceOwner(); final String deviceOwnerPackage = getDeviceOwner() == null ? null : getDeviceOwner().getPackageName(); if (deviceOwnerPackage == null) { return; } Loading