diff options
4 files changed, 59 insertions, 7 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 7f062d9a2bc8..b11c5091854a 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2513,6 +2513,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case UPDATE_DEVICE_OWNER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + String packageName = data.readString(); + updateDeviceOwner(packageName); + reply.writeNoException(); + return true; + } + case GET_PACKAGE_PROCESS_STATE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); @@ -5801,6 +5809,18 @@ class ActivityManagerProxy implements IActivityManager } @Override + public void updateDeviceOwner(String packageName) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(packageName); + mRemote.transact(UPDATE_DEVICE_OWNER_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + @Override public int getPackageProcessState(String packageName) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 7e03faa5a3f6..00558fe15bb2 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -495,6 +495,7 @@ public interface IActivityManager extends IInterface { public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) throws RemoteException; public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException; + public void updateDeviceOwner(String packageName) throws RemoteException; public int getPackageProcessState(String packageName) throws RemoteException; @@ -837,4 +838,5 @@ public interface IActivityManager extends IInterface { int NOTE_ALARM_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+292; int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293; int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294; + int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9d5ae8e7be58..a48a4d903b6a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -437,6 +437,11 @@ public final class ActivityManagerService extends ActivityManagerNative */ SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); + /** + * The package name of the DeviceOwner. This package is not permitted to have its data cleared. + */ + String mDeviceOwnerName; + public class PendingAssistExtras extends Binder implements Runnable { public final ActivityRecord activity; public final Bundle extras; @@ -4831,6 +4836,9 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId) { enforceNotIsolatedCaller("clearApplicationUserData"); + if (packageName != null && packageName.equals(mDeviceOwnerName)) { + throw new SecurityException("Clearing DeviceOwner data is forbidden."); + } int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); userId = handleIncomingUser(pid, uid, @@ -8563,6 +8571,17 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override + public void updateDeviceOwner(String packageName) { + final int callingUid = Binder.getCallingUid(); + if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { + throw new SecurityException("updateDeviceOwner called from non-system process"); + } + synchronized (this) { + mDeviceOwnerName = packageName; + } + } + + @Override public void updateLockTaskPackages(int userId, String[] packages) { final int callingUid = Binder.getCallingUid(); if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 9bb97f705b2d..44b3f69387e3 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1106,6 +1106,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void loadDeviceOwner() { synchronized (this) { mDeviceOwner = DeviceOwner.load(); + updateDeviceOwnerLocked(); } } @@ -1667,6 +1668,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private void updateDeviceOwnerLocked() { + IActivityManager am = ActivityManagerNative.getDefault(); + long ident = Binder.clearCallingIdentity(); + try { + am.updateDeviceOwner(mDeviceOwner.getDeviceOwnerPackageName()); + } catch (RemoteException e) { + // Not gonna happen. + } finally { + Binder.restoreCallingIdentity(ident); + } + } + static void validateQualityConstant(int quality) { switch (quality) { case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: @@ -3990,14 +4003,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mDeviceOwner == null) { // Device owner is not set and does not exist, set it. mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName); - mDeviceOwner.writeOwnerFile(); - return true; } else { // Device owner is not set but a profile owner exists, update Device owner state. mDeviceOwner.setDeviceOwner(packageName, ownerName); - mDeviceOwner.writeOwnerFile(); - return true; } + mDeviceOwner.writeOwnerFile(); + updateDeviceOwnerLocked(); + return true; } } @@ -4079,6 +4091,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mDeviceOwner != null) { mDeviceOwner.clearDeviceOwner(); mDeviceOwner.writeOwnerFile(); + updateDeviceOwnerLocked(); } } finally { Binder.restoreCallingIdentity(ident); @@ -4107,15 +4120,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mDeviceOwner == null) { // Device owner state does not exist, create it. - mDeviceOwner = DeviceOwner.createWithDeviceInitializer( - initializer, ownerName); + mDeviceOwner = DeviceOwner.createWithDeviceInitializer(initializer, ownerName); } else { // Device owner already exists, update it. mDeviceOwner.setDeviceInitializer(initializer, ownerName); } addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER); - mDeviceOwner.writeOwnerFile(); return true; } |