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;