Merge "Disallow data clearing of DeviceOwner."
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 7f062d9..b11c509 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2513,6 +2513,14 @@
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 @@
}
@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 7e03faa..00558fe 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -495,6 +495,7 @@
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 @@
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 9d5ae8e..a48a4d9 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 @@
*/
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 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 @@
}
@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 9bb97f7..44b3f69 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 @@
void loadDeviceOwner() {
synchronized (this) {
mDeviceOwner = DeviceOwner.load();
+ updateDeviceOwnerLocked();
}
}
@@ -1667,6 +1668,18 @@
}
}
+ 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 @@
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 @@
if (mDeviceOwner != null) {
mDeviceOwner.clearDeviceOwner();
mDeviceOwner.writeOwnerFile();
+ updateDeviceOwnerLocked();
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4107,15 +4120,13 @@
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;
}