Merge "Add security check for clearDeviceInitializer in the service."
diff --git a/api/current.txt b/api/current.txt
index b96d241..7a348ea 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5458,7 +5458,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 clearDeviceInitializerApp();
+    method public void clearDeviceInitializerApp(android.content.ComponentName);
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 65df354..4755fe7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5552,7 +5552,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 clearDeviceInitializerApp();
+    method public void clearDeviceInitializerApp(android.content.ComponentName);
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearProfileOwner(android.content.ComponentName);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index add7130..3d587b6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2476,12 +2476,14 @@
     /**
      * Removes the device initializer, so that it will not be invoked on user initialization for any
      * subsequently created users. This method can be called by either the device owner or device
-     * initializer itself.
+     * initializer itself. The caller must be an active administrator.
+     *
+     * @param who Which {@link DeviceAdminReceiver} this request is associated with.
      */
-    public void clearDeviceInitializerApp() {
+    public void clearDeviceInitializerApp(ComponentName who) {
         if (mService != null) {
             try {
-                mService.clearDeviceInitializer(mContext.getPackageName());
+                mService.clearDeviceInitializer(who);
             } catch (RemoteException re) {
                 Log.w(TAG, "Failed to clear device initializer");
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 5e58fe0..5cbab4b 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -202,7 +202,7 @@
 
     boolean setUserEnabled(in ComponentName who);
     boolean isDeviceInitializer(String packageName);
-    void clearDeviceInitializer(String packageName);
+    void clearDeviceInitializer(in ComponentName who);
     boolean setDeviceInitializer(in ComponentName who, in ComponentName initializer, String initializerName);
     String getDeviceInitializer();
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index aa9d8dd..fc9ff76 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3940,15 +3940,21 @@
     }
 
     @Override
-    public void clearDeviceInitializer(String packageName) {
+    public void clearDeviceInitializer(ComponentName who) {
         if (!mHasFeature) {
             return;
         }
-        if (packageName == null) {
-            throw new NullPointerException("packageName is null");
+        Preconditions.checkNotNull(who, "ComponentName is null");
+
+        ActiveAdmin admin = getActiveAdminUncheckedLocked(who, UserHandle.getCallingUserId());
+
+        if (admin.getUid() != Binder.getCallingUid()) {
+            throw new SecurityException("Admin " + who + " is not owned by uid "
+                    + Binder.getCallingUid());
         }
 
-        if (!isDeviceInitializer(packageName) && !isDeviceOwner(packageName)) {
+        if (!isDeviceInitializer(admin.info.getPackageName())
+                && !isDeviceOwner(admin.info.getPackageName())) {
             throw new SecurityException(
                     "clearDeviceInitializer can only be called by the device initializer/owner");
         }