Loading cmds/dpm/src/com/android/commands/dpm/Dpm.java +8 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,8 @@ public final class Dpm extends BaseCommand { out.println( "usage: dpm [subcommand] [options]\n" + "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + "usage: dpm set-device-owner <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" + "\n" + "dpm set-active-admin: Sets the given component as active admin" + Loading Loading @@ -106,22 +107,22 @@ public final class Dpm extends BaseCommand { } private void runSetDeviceOwner() throws RemoteException { ComponentName component = parseComponentName(nextArgRequired()); mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_SYSTEM); parseArgs(true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); String packageName = component.getPackageName(); String packageName = mComponent.getPackageName(); try { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/, mUserId)) { throw new RuntimeException( "Can't set package " + packageName + " as device owner."); } } catch (Exception e) { // Need to remove the admin that we just added. mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_SYSTEM); mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM); throw e; } System.out.println("Success: Device owner set to package " + packageName); System.out.println("Active admin set to component " + component.toShortString()); System.out.println("Active admin set to component " + mComponent.toShortString()); } private void runSetProfileOwner() throws RemoteException { Loading core/java/android/app/admin/DevicePolicyManager.java +18 −4 Original line number Diff line number Diff line Loading @@ -2684,11 +2684,24 @@ public class DevicePolicyManager { * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName) throws IllegalArgumentException, IllegalStateException { public boolean setDeviceOwner(String packageName) { return setDeviceOwner(packageName, null); } /** * @hide */ public boolean setDeviceOwner(String packageName, int userId) { return setDeviceOwner(packageName, null, userId); } /** * @hide */ public boolean setDeviceOwner(String packageName, String ownerName) { return setDeviceOwner(packageName, ownerName, UserHandle.USER_SYSTEM); } /** * @hide * Sets the given package as the device owner. The package must already be installed. There Loading @@ -2699,15 +2712,16 @@ public class DevicePolicyManager { * 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 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) public boolean setDeviceOwner(String packageName, String ownerName, int userId) throws IllegalArgumentException, IllegalStateException { if (mService != null) { try { return mService.setDeviceOwner(packageName, ownerName); return mService.setDeviceOwner(packageName, ownerName, userId); } catch (RemoteException re) { Log.w(TAG, "Failed to set device owner"); } Loading core/java/android/app/admin/IDevicePolicyManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ interface IDevicePolicyManager { void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); boolean setDeviceOwner(String packageName, String ownerName); boolean setDeviceOwner(String packageName, String ownerName, int userId); boolean isDeviceOwner(String packageName); String getDeviceOwner(); String getDeviceOwnerName(); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +77 −35 Original line number Diff line number Diff line Loading @@ -303,9 +303,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void onBootPhase(int phase) { if (phase == PHASE_LOCK_SETTINGS_READY) { mService.systemReady(); } mService.systemReady(phase); } } Loading Loading @@ -1776,10 +1774,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public void systemReady() { public void systemReady(int phase) { if (!mHasFeature) { return; } switch (phase) { case SystemService.PHASE_LOCK_SETTINGS_READY: onLockSettingsReady(); break; case SystemService.PHASE_BOOT_COMPLETED: ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this. break; } } private void onLockSettingsReady() { getUserData(UserHandle.USER_OWNER); loadDeviceOwner(); cleanUpOldUsers(); Loading @@ -1798,6 +1807,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private void ensureDeviceOwnerUserStarted() { if (mOwners.hasDeviceOwner()) { final IActivityManager am = ActivityManagerNative.getDefault(); final int userId = mOwners.getDeviceOwnerUserId(); if (VERBOSE_LOG) { Log.v(LOG_TAG, "Starting non-system DO user: " + userId); } if (userId != UserHandle.USER_SYSTEM) { try { am.startUserInBackground(userId); // STOPSHIP Prevent the DO user from being killed. } catch (RemoteException e) { Slog.w(LOG_TAG, "Exception starting user", e); } } } } private void cleanUpOldUsers() { // This is needed in case the broadcast {@link Intent.ACTION_USER_REMOVED} was not handled // before reboot Loading Loading @@ -4110,17 +4139,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean setDeviceOwner(String packageName, String ownerName) { public boolean setDeviceOwner(String packageName, String ownerName, int userId) { if (!mHasFeature) { return false; } if (packageName == null || !Owners.isInstalled(packageName, mContext.getPackageManager())) { || !Owners.isInstalledForUser(packageName, userId)) { throw new IllegalArgumentException("Invalid package name " + packageName + " for device owner"); } synchronized (this) { enforceCanSetDeviceOwner(); enforceCanSetDeviceOwner(userId); // Shutting down backup manager service permanently. long ident = Binder.clearCallingIdentity(); Loading @@ -4134,14 +4163,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Binder.restoreCallingIdentity(ident); } mOwners.setDeviceOwner(packageName, ownerName); mOwners.setDeviceOwner(packageName, ownerName, userId); mOwners.writeDeviceOwner(); updateDeviceOwnerLocked(); Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED); ident = Binder.clearCallingIdentity(); try { mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); // TODO Send to system too? mContext.sendBroadcastAsUser(intent, new UserHandle(userId)); } finally { Binder.restoreCallingIdentity(ident); } Loading Loading @@ -4242,10 +4272,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } if (initializer == null || !Owners.isInstalled( initializer.getPackageName(), mContext.getPackageManager())) { if (initializer == null || !mOwners.hasDeviceOwner() || !Owners.isInstalledForUser(initializer.getPackageName(), mOwners.getDeviceOwnerUserId())) { throw new IllegalArgumentException("Invalid component name " + initializer + " for device initializer"); + " for device initializer or no device owner set"); } boolean isInitializerSystemApp; try { Loading @@ -4268,7 +4300,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mOwners.setDeviceInitializer(initializer); addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER); addDeviceInitializerToLockTaskPackagesLocked(mOwners.getDeviceOwnerUserId()); mOwners.writeDeviceOwner(); return true; } Loading @@ -4278,7 +4310,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (who == null) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); if (hasUserSetupCompleted(UserHandle.USER_OWNER)) { if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { throw new IllegalStateException( "Trying to set device initializer but device is already provisioned."); } Loading Loading @@ -4648,33 +4680,48 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * The device owner can only be set before the setup phase of the primary user has completed, * except for adb if no accounts or additional users are present on the device. */ private void enforceCanSetDeviceOwner() { if (mOwners != null && mOwners.hasDeviceOwner()) { private void enforceCanSetDeviceOwner(int userId) { if (mOwners.hasDeviceOwner()) { throw new IllegalStateException("Trying to set the device owner, but device owner " + "is already set."); } // STOPSHIP Make sure the DO user is running int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) { return; } // STOPSHIP Do proper check in split user mode if (!UserManager.isSplitSystemUser()) { if (mUserManager.getUserCount() > 1) { throw new IllegalStateException("Not allowed to set the device owner because there " throw new IllegalStateException( "Not allowed to set the device owner because there " + "are already several users on the device"); } if (AccountManager.get(mContext).getAccounts().length > 0) { throw new IllegalStateException("Not allowed to set the device owner because there " throw new IllegalStateException( "Not allowed to set the device owner because there " + "are already some accounts on the device"); } } return; } else { // STOPSHIP check the caller UID with userId } if (mUserManager.isUserRunning(new UserHandle(userId))) { throw new IllegalStateException("User not running: " + userId); } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); // STOPSHIP Do proper check in split user mode if (!UserManager.isSplitSystemUser()) { if (hasUserSetupCompleted(UserHandle.USER_OWNER)) { throw new IllegalStateException("Cannot set the device owner if the device is " + "already set-up"); } } } private void enforceCrossUserPermission(int userHandle) { if (userHandle < 0) { Loading @@ -4689,12 +4736,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private void enforceSystemProcess(String message) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException(message); } } private void enforceNotManagedProfile(int userHandle, String message) { if(isManagedProfile(userHandle)) { throw new SecurityException("You can not " + message + " for a managed profile. "); Loading Loading @@ -6318,7 +6359,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mContext.sendBroadcastAsUser( new Intent(DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED), UserHandle.OWNER); UserHandle.SYSTEM); } @Override Loading Loading @@ -6368,6 +6409,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (deviceOwnerPackage == null) { return; } final UserHandle deviceOwnerUser = new UserHandle(mOwners.getDeviceOwnerUserId()); ActivityInfo[] receivers = null; try { Loading @@ -6383,7 +6425,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) { intent.setComponent(new ComponentName(deviceOwnerPackage, receivers[i].name)); mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); mContext.sendBroadcastAsUser(intent, deviceOwnerUser); } } } finally { Loading services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +43 −16 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.os.Environment; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import android.util.AtomicFile; Loading Loading @@ -71,6 +72,8 @@ class Owners { private static final String TAG_DEVICE_OWNER = "device-owner"; private static final String TAG_DEVICE_INITIALIZER = "device-initializer"; private static final String TAG_PROFILE_OWNER = "profile-owner"; // Holds "context" for device-owner, this must not be show up before device-owner. private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context"; private static final String ATTR_NAME = "name"; private static final String ATTR_PACKAGE = "package"; Loading @@ -85,6 +88,8 @@ class Owners { // Internal state for the device owner package. private OwnerInfo mDeviceOwner; private int mDeviceOwnerUserId = UserHandle.USER_NULL; // Internal state for the device initializer package. private OwnerInfo mDeviceInitializer; Loading Loading @@ -140,16 +145,26 @@ class Owners { return mDeviceOwner != null ? mDeviceOwner.packageName : null; } int getDeviceOwnerUserId() { return mDeviceOwnerUserId; } String getDeviceOwnerName() { return mDeviceOwner != null ? mDeviceOwner.name : null; } void setDeviceOwner(String packageName, String ownerName) { void setDeviceOwner(String packageName, String ownerName, int userId) { if (userId < 0) { Slog.e(TAG, "Invalid user id for device owner user: " + userId); return; } mDeviceOwner = new OwnerInfo(ownerName, packageName); mDeviceOwnerUserId = userId; } void clearDeviceOwner() { mDeviceOwner = null; mDeviceOwnerUserId = UserHandle.USER_NULL; } ComponentName getDeviceInitializerComponent() { Loading Loading @@ -215,20 +230,6 @@ class Owners { return mDeviceOwner != null; } static boolean isInstalled(String packageName, PackageManager pm) { try { PackageInfo pi; if ((pi = pm.getPackageInfo(packageName, 0)) != null) { if ((pi.applicationInfo.flags) != 0) { return true; } } } catch (NameNotFoundException nnfe) { Slog.w(TAG, "Device Owner package " + packageName + " not installed."); } return false; } static boolean isInstalledForUser(String packageName, int userHandle) { try { PackageInfo pi = (AppGlobals.getPackageManager()) Loading Loading @@ -263,6 +264,7 @@ class Owners { String name = parser.getAttributeValue(null, ATTR_NAME); String packageName = parser.getAttributeValue(null, ATTR_PACKAGE); mDeviceOwner = new OwnerInfo(name, packageName); mDeviceOwnerUserId = UserHandle.USER_SYSTEM; } else if (tag.equals(TAG_DEVICE_INITIALIZER)) { String packageName = parser.getAttributeValue(null, ATTR_PACKAGE); String initializerComponentStr = Loading Loading @@ -464,7 +466,11 @@ class Owners { void writeInner(XmlSerializer out) throws IOException { if (mDeviceOwner != null) { mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER); out.startTag(null, TAG_DEVICE_OWNER_CONTEXT); out.attribute(null, ATTR_USERID, String.valueOf(mDeviceOwnerUserId)); out.endTag(null, TAG_DEVICE_OWNER_CONTEXT); } if (mDeviceInitializer != null) { mDeviceInitializer.writeToXml(out, TAG_DEVICE_INITIALIZER); } Loading @@ -483,7 +489,18 @@ class Owners { switch (tag) { case TAG_DEVICE_OWNER: mDeviceOwner = OwnerInfo.readFromXml(parser); mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default break; case TAG_DEVICE_OWNER_CONTEXT: { final String userIdString = parser.getAttributeValue(null, ATTR_USERID); try { mDeviceOwnerUserId = Integer.parseInt(userIdString); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing user-id " + userIdString); } break; } case TAG_DEVICE_INITIALIZER: mDeviceInitializer = OwnerInfo.readFromXml(parser); break; Loading Loading @@ -594,7 +611,6 @@ class Owners { pw.println(prefix + "admin=" + admin); pw.println(prefix + "name=" + name); pw.println(prefix + "package=" + packageName); pw.println(); } } Loading @@ -602,6 +618,17 @@ class Owners { if (mDeviceOwner != null) { pw.println(prefix + "Device Owner: "); mDeviceOwner.dump(prefix + " ", pw); pw.println(prefix + " User ID: " + mDeviceOwnerUserId); pw.println(); } if (mDeviceInitializer != null) { pw.println(prefix + "Device Initializer: "); mDeviceInitializer.dump(prefix + " ", pw); pw.println(); } if (mSystemUpdatePolicy != null) { pw.println(prefix + "System Update Policy: " + mSystemUpdatePolicy); pw.println(); } if (mProfileOwners != null) { for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) { Loading Loading
cmds/dpm/src/com/android/commands/dpm/Dpm.java +8 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,8 @@ public final class Dpm extends BaseCommand { out.println( "usage: dpm [subcommand] [options]\n" + "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + "usage: dpm set-device-owner <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" + "\n" + "dpm set-active-admin: Sets the given component as active admin" + Loading Loading @@ -106,22 +107,22 @@ public final class Dpm extends BaseCommand { } private void runSetDeviceOwner() throws RemoteException { ComponentName component = parseComponentName(nextArgRequired()); mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_SYSTEM); parseArgs(true); mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); String packageName = component.getPackageName(); String packageName = mComponent.getPackageName(); try { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) { if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/, mUserId)) { throw new RuntimeException( "Can't set package " + packageName + " as device owner."); } } catch (Exception e) { // Need to remove the admin that we just added. mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_SYSTEM); mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM); throw e; } System.out.println("Success: Device owner set to package " + packageName); System.out.println("Active admin set to component " + component.toShortString()); System.out.println("Active admin set to component " + mComponent.toShortString()); } private void runSetProfileOwner() throws RemoteException { Loading
core/java/android/app/admin/DevicePolicyManager.java +18 −4 Original line number Diff line number Diff line Loading @@ -2684,11 +2684,24 @@ public class DevicePolicyManager { * @throws IllegalArgumentException if the package name is null or invalid * @throws IllegalStateException If the preconditions mentioned are not met. */ public boolean setDeviceOwner(String packageName) throws IllegalArgumentException, IllegalStateException { public boolean setDeviceOwner(String packageName) { return setDeviceOwner(packageName, null); } /** * @hide */ public boolean setDeviceOwner(String packageName, int userId) { return setDeviceOwner(packageName, null, userId); } /** * @hide */ public boolean setDeviceOwner(String packageName, String ownerName) { return setDeviceOwner(packageName, ownerName, UserHandle.USER_SYSTEM); } /** * @hide * Sets the given package as the device owner. The package must already be installed. There Loading @@ -2699,15 +2712,16 @@ public class DevicePolicyManager { * 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 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) public boolean setDeviceOwner(String packageName, String ownerName, int userId) throws IllegalArgumentException, IllegalStateException { if (mService != null) { try { return mService.setDeviceOwner(packageName, ownerName); return mService.setDeviceOwner(packageName, ownerName, userId); } catch (RemoteException re) { Log.w(TAG, "Failed to set device owner"); } Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ interface IDevicePolicyManager { void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); boolean setDeviceOwner(String packageName, String ownerName); boolean setDeviceOwner(String packageName, String ownerName, int userId); boolean isDeviceOwner(String packageName); String getDeviceOwner(); String getDeviceOwnerName(); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +77 −35 Original line number Diff line number Diff line Loading @@ -303,9 +303,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void onBootPhase(int phase) { if (phase == PHASE_LOCK_SETTINGS_READY) { mService.systemReady(); } mService.systemReady(phase); } } Loading Loading @@ -1776,10 +1774,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public void systemReady() { public void systemReady(int phase) { if (!mHasFeature) { return; } switch (phase) { case SystemService.PHASE_LOCK_SETTINGS_READY: onLockSettingsReady(); break; case SystemService.PHASE_BOOT_COMPLETED: ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this. break; } } private void onLockSettingsReady() { getUserData(UserHandle.USER_OWNER); loadDeviceOwner(); cleanUpOldUsers(); Loading @@ -1798,6 +1807,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private void ensureDeviceOwnerUserStarted() { if (mOwners.hasDeviceOwner()) { final IActivityManager am = ActivityManagerNative.getDefault(); final int userId = mOwners.getDeviceOwnerUserId(); if (VERBOSE_LOG) { Log.v(LOG_TAG, "Starting non-system DO user: " + userId); } if (userId != UserHandle.USER_SYSTEM) { try { am.startUserInBackground(userId); // STOPSHIP Prevent the DO user from being killed. } catch (RemoteException e) { Slog.w(LOG_TAG, "Exception starting user", e); } } } } private void cleanUpOldUsers() { // This is needed in case the broadcast {@link Intent.ACTION_USER_REMOVED} was not handled // before reboot Loading Loading @@ -4110,17 +4139,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean setDeviceOwner(String packageName, String ownerName) { public boolean setDeviceOwner(String packageName, String ownerName, int userId) { if (!mHasFeature) { return false; } if (packageName == null || !Owners.isInstalled(packageName, mContext.getPackageManager())) { || !Owners.isInstalledForUser(packageName, userId)) { throw new IllegalArgumentException("Invalid package name " + packageName + " for device owner"); } synchronized (this) { enforceCanSetDeviceOwner(); enforceCanSetDeviceOwner(userId); // Shutting down backup manager service permanently. long ident = Binder.clearCallingIdentity(); Loading @@ -4134,14 +4163,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Binder.restoreCallingIdentity(ident); } mOwners.setDeviceOwner(packageName, ownerName); mOwners.setDeviceOwner(packageName, ownerName, userId); mOwners.writeDeviceOwner(); updateDeviceOwnerLocked(); Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED); ident = Binder.clearCallingIdentity(); try { mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); // TODO Send to system too? mContext.sendBroadcastAsUser(intent, new UserHandle(userId)); } finally { Binder.restoreCallingIdentity(ident); } Loading Loading @@ -4242,10 +4272,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } if (initializer == null || !Owners.isInstalled( initializer.getPackageName(), mContext.getPackageManager())) { if (initializer == null || !mOwners.hasDeviceOwner() || !Owners.isInstalledForUser(initializer.getPackageName(), mOwners.getDeviceOwnerUserId())) { throw new IllegalArgumentException("Invalid component name " + initializer + " for device initializer"); + " for device initializer or no device owner set"); } boolean isInitializerSystemApp; try { Loading @@ -4268,7 +4300,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mOwners.setDeviceInitializer(initializer); addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER); addDeviceInitializerToLockTaskPackagesLocked(mOwners.getDeviceOwnerUserId()); mOwners.writeDeviceOwner(); return true; } Loading @@ -4278,7 +4310,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (who == null) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); if (hasUserSetupCompleted(UserHandle.USER_OWNER)) { if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { throw new IllegalStateException( "Trying to set device initializer but device is already provisioned."); } Loading Loading @@ -4648,33 +4680,48 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * The device owner can only be set before the setup phase of the primary user has completed, * except for adb if no accounts or additional users are present on the device. */ private void enforceCanSetDeviceOwner() { if (mOwners != null && mOwners.hasDeviceOwner()) { private void enforceCanSetDeviceOwner(int userId) { if (mOwners.hasDeviceOwner()) { throw new IllegalStateException("Trying to set the device owner, but device owner " + "is already set."); } // STOPSHIP Make sure the DO user is running int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) { return; } // STOPSHIP Do proper check in split user mode if (!UserManager.isSplitSystemUser()) { if (mUserManager.getUserCount() > 1) { throw new IllegalStateException("Not allowed to set the device owner because there " throw new IllegalStateException( "Not allowed to set the device owner because there " + "are already several users on the device"); } if (AccountManager.get(mContext).getAccounts().length > 0) { throw new IllegalStateException("Not allowed to set the device owner because there " throw new IllegalStateException( "Not allowed to set the device owner because there " + "are already some accounts on the device"); } } return; } else { // STOPSHIP check the caller UID with userId } if (mUserManager.isUserRunning(new UserHandle(userId))) { throw new IllegalStateException("User not running: " + userId); } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); // STOPSHIP Do proper check in split user mode if (!UserManager.isSplitSystemUser()) { if (hasUserSetupCompleted(UserHandle.USER_OWNER)) { throw new IllegalStateException("Cannot set the device owner if the device is " + "already set-up"); } } } private void enforceCrossUserPermission(int userHandle) { if (userHandle < 0) { Loading @@ -4689,12 +4736,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private void enforceSystemProcess(String message) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException(message); } } private void enforceNotManagedProfile(int userHandle, String message) { if(isManagedProfile(userHandle)) { throw new SecurityException("You can not " + message + " for a managed profile. "); Loading Loading @@ -6318,7 +6359,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mContext.sendBroadcastAsUser( new Intent(DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED), UserHandle.OWNER); UserHandle.SYSTEM); } @Override Loading Loading @@ -6368,6 +6409,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (deviceOwnerPackage == null) { return; } final UserHandle deviceOwnerUser = new UserHandle(mOwners.getDeviceOwnerUserId()); ActivityInfo[] receivers = null; try { Loading @@ -6383,7 +6425,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) { intent.setComponent(new ComponentName(deviceOwnerPackage, receivers[i].name)); mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); mContext.sendBroadcastAsUser(intent, deviceOwnerUser); } } } finally { Loading
services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +43 −16 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.os.Environment; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import android.util.AtomicFile; Loading Loading @@ -71,6 +72,8 @@ class Owners { private static final String TAG_DEVICE_OWNER = "device-owner"; private static final String TAG_DEVICE_INITIALIZER = "device-initializer"; private static final String TAG_PROFILE_OWNER = "profile-owner"; // Holds "context" for device-owner, this must not be show up before device-owner. private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context"; private static final String ATTR_NAME = "name"; private static final String ATTR_PACKAGE = "package"; Loading @@ -85,6 +88,8 @@ class Owners { // Internal state for the device owner package. private OwnerInfo mDeviceOwner; private int mDeviceOwnerUserId = UserHandle.USER_NULL; // Internal state for the device initializer package. private OwnerInfo mDeviceInitializer; Loading Loading @@ -140,16 +145,26 @@ class Owners { return mDeviceOwner != null ? mDeviceOwner.packageName : null; } int getDeviceOwnerUserId() { return mDeviceOwnerUserId; } String getDeviceOwnerName() { return mDeviceOwner != null ? mDeviceOwner.name : null; } void setDeviceOwner(String packageName, String ownerName) { void setDeviceOwner(String packageName, String ownerName, int userId) { if (userId < 0) { Slog.e(TAG, "Invalid user id for device owner user: " + userId); return; } mDeviceOwner = new OwnerInfo(ownerName, packageName); mDeviceOwnerUserId = userId; } void clearDeviceOwner() { mDeviceOwner = null; mDeviceOwnerUserId = UserHandle.USER_NULL; } ComponentName getDeviceInitializerComponent() { Loading Loading @@ -215,20 +230,6 @@ class Owners { return mDeviceOwner != null; } static boolean isInstalled(String packageName, PackageManager pm) { try { PackageInfo pi; if ((pi = pm.getPackageInfo(packageName, 0)) != null) { if ((pi.applicationInfo.flags) != 0) { return true; } } } catch (NameNotFoundException nnfe) { Slog.w(TAG, "Device Owner package " + packageName + " not installed."); } return false; } static boolean isInstalledForUser(String packageName, int userHandle) { try { PackageInfo pi = (AppGlobals.getPackageManager()) Loading Loading @@ -263,6 +264,7 @@ class Owners { String name = parser.getAttributeValue(null, ATTR_NAME); String packageName = parser.getAttributeValue(null, ATTR_PACKAGE); mDeviceOwner = new OwnerInfo(name, packageName); mDeviceOwnerUserId = UserHandle.USER_SYSTEM; } else if (tag.equals(TAG_DEVICE_INITIALIZER)) { String packageName = parser.getAttributeValue(null, ATTR_PACKAGE); String initializerComponentStr = Loading Loading @@ -464,7 +466,11 @@ class Owners { void writeInner(XmlSerializer out) throws IOException { if (mDeviceOwner != null) { mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER); out.startTag(null, TAG_DEVICE_OWNER_CONTEXT); out.attribute(null, ATTR_USERID, String.valueOf(mDeviceOwnerUserId)); out.endTag(null, TAG_DEVICE_OWNER_CONTEXT); } if (mDeviceInitializer != null) { mDeviceInitializer.writeToXml(out, TAG_DEVICE_INITIALIZER); } Loading @@ -483,7 +489,18 @@ class Owners { switch (tag) { case TAG_DEVICE_OWNER: mDeviceOwner = OwnerInfo.readFromXml(parser); mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default break; case TAG_DEVICE_OWNER_CONTEXT: { final String userIdString = parser.getAttributeValue(null, ATTR_USERID); try { mDeviceOwnerUserId = Integer.parseInt(userIdString); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing user-id " + userIdString); } break; } case TAG_DEVICE_INITIALIZER: mDeviceInitializer = OwnerInfo.readFromXml(parser); break; Loading Loading @@ -594,7 +611,6 @@ class Owners { pw.println(prefix + "admin=" + admin); pw.println(prefix + "name=" + name); pw.println(prefix + "package=" + packageName); pw.println(); } } Loading @@ -602,6 +618,17 @@ class Owners { if (mDeviceOwner != null) { pw.println(prefix + "Device Owner: "); mDeviceOwner.dump(prefix + " ", pw); pw.println(prefix + " User ID: " + mDeviceOwnerUserId); pw.println(); } if (mDeviceInitializer != null) { pw.println(prefix + "Device Initializer: "); mDeviceInitializer.dump(prefix + " ", pw); pw.println(); } if (mSystemUpdatePolicy != null) { pw.println(prefix + "System Update Policy: " + mSystemUpdatePolicy); pw.println(); } if (mProfileOwners != null) { for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) { Loading