Add an API to clear the device owner.
Only the device owner will be able to clear itself.
Change-Id: Ie3231467d92e8c5d22ec51256177793f34110432
diff --git a/api/current.txt b/api/current.txt
index fc662a6..5e27406 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5172,6 +5172,7 @@
method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
method public void addUserRestriction(android.content.ComponentName, java.lang.String);
method public void clearCrossProfileIntentFilters(android.content.ComponentName);
+ method public void clearDeviceOwnerApp();
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 785987f..34fa609 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1821,6 +1821,23 @@
return isDeviceOwnerApp(packageName);
}
+ /**
+ * Clears the current device owner. The caller must be the device owner.
+ *
+ * This function should be used cautiously as once it is called it cannot
+ * be undone. The device owner can only be set as a part of device setup
+ * before setup completes.
+ */
+ public void clearDeviceOwnerApp() {
+ if (mService != null) {
+ try {
+ mService.clearDeviceOwner(mContext.getPackageName());
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed to clear device owner");
+ }
+ }
+ }
+
/** @hide */
public String getDeviceOwner() {
if (mService != null) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 3d80869..4935ddc 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -108,6 +108,7 @@
boolean isDeviceOwner(String packageName);
String getDeviceOwner();
String getDeviceOwnerName();
+ void clearDeviceOwner(String packageName);
boolean setProfileOwner(String packageName, String ownerName, int userHandle);
String getProfileOwner(int userHandle);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 674c6f4..f1284d8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -120,6 +120,10 @@
mDeviceOwner = new OwnerInfo(ownerName, packageName);
}
+ void clearDeviceOwner() {
+ mDeviceOwner = null;
+ }
+
void setProfileOwner(String packageName, String ownerName, int userId) {
mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName));
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8ca437f..14f14f4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -52,6 +52,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ProxyInfo;
import android.os.Binder;
import android.os.Bundle;
@@ -3098,6 +3099,37 @@
}
@Override
+ public void clearDeviceOwner(String packageName) {
+ if (packageName == null) {
+ throw new NullPointerException("packageName is null");
+ }
+ try {
+ int uid = mContext.getPackageManager().getPackageUid(packageName, 0);
+ if (uid != Binder.getCallingUid()) {
+ throw new SecurityException("Invalid packageName");
+ }
+ } catch (NameNotFoundException e) {
+ throw new SecurityException(e);
+ }
+ if (!isDeviceOwner(packageName)) {
+ throw new SecurityException("clearDeviceOwner can only be called by the device owner");
+ }
+ synchronized (this) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mUserManager.setUserRestrictions(new Bundle(),
+ new UserHandle(UserHandle.USER_OWNER));
+ if (mDeviceOwner != null) {
+ mDeviceOwner.clearDeviceOwner();
+ mDeviceOwner.writeOwnerFile();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
public boolean setProfileOwner(String packageName, String ownerName, int userHandle) {
if (!mHasFeature) {
return false;