DO NOT MERGE Do not call RecoverySystem with DPMS lock held

Note DPM.wipeData() on a secondary user is now blocking, just like
it's been always blocking on the primary user.

Test: Manually tested wipeData() with ApiDemos, both on 1) the primary user,
2) a secondary user and 3) work profile.

Test: adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest -w com.android.frameworks.servicestests

Bug 30681079

Change-Id: Ia832bed0f22396998d6307ab46e262dae9463838
Merged-in: Ia832bed0f22396998d6307ab46e262dae9463838
(cherry picked from commit efdec8f5688ce6b0a287eddb6d5dad93ffa0e1ee)
(cherry picked from commit 2317451acc84174cbe30d1899428d1b2953a4363)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4316866..6c31e67 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4677,7 +4677,7 @@
         }
     }
 
-    private void wipeDataLocked(boolean wipeExtRequested, String reason) {
+    private void wipeDataNoLock(boolean wipeExtRequested, String reason) {
         if (wipeExtRequested) {
             StorageManager sm = (StorageManager) mContext.getSystemService(
                     Context.STORAGE_SERVICE);
@@ -4697,13 +4697,14 @@
         }
         final int userHandle = mInjector.userHandleGetCallingUserId();
         enforceFullCrossUsersPermission(userHandle);
+
+        final String source;
         synchronized (this) {
             // This API can only be called by an active device admin,
             // so try to retrieve it to check that the caller is one.
             final ActiveAdmin admin = getActiveAdminForCallerLocked(null,
                     DeviceAdminInfo.USES_POLICY_WIPE_DATA);
-
-            final String source = admin.info.getComponent().flattenToShortString();
+            source = admin.info.getComponent().flattenToShortString();
 
             long ident = mInjector.binderClearCallingIdentity();
             try {
@@ -4718,39 +4719,44 @@
                         manager.wipe();
                     }
                 }
-                boolean wipeExtRequested = (flags & WIPE_EXTERNAL_STORAGE) != 0;
-                wipeDeviceOrUserLocked(wipeExtRequested, userHandle,
-                        "DevicePolicyManager.wipeData() from " + source);
             } finally {
                 mInjector.binderRestoreCallingIdentity(ident);
             }
         }
+        final boolean wipeExtRequested = (flags & WIPE_EXTERNAL_STORAGE) != 0;
+        wipeDeviceNoLock(wipeExtRequested, userHandle,
+                "DevicePolicyManager.wipeData() from " + source);
     }
 
-    private void wipeDeviceOrUserLocked(boolean wipeExtRequested, final int userHandle, String reason) {
-        if (userHandle == UserHandle.USER_SYSTEM) {
-            wipeDataLocked(wipeExtRequested, reason);
-        } else {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        IActivityManager am = mInjector.getIActivityManager();
-                        if (am.getCurrentUser().id == userHandle) {
-                            am.switchUser(UserHandle.USER_SYSTEM);
-                        }
+    private void wipeDeviceNoLock(boolean wipeExtRequested, final int userHandle, String reason) {
+        final long ident = mInjector.binderClearCallingIdentity();
+        try {
+            if (userHandle == UserHandle.USER_SYSTEM) {
+                wipeDataNoLock(wipeExtRequested, reason);
+            } else {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            IActivityManager am = mInjector.getIActivityManager();
+                            if (am.getCurrentUser().id == userHandle) {
+                                am.switchUser(UserHandle.USER_SYSTEM);
+                            }
 
-                        boolean isManagedProfile = isManagedProfile(userHandle);
-                        if (!mUserManager.removeUser(userHandle)) {
-                            Slog.w(LOG_TAG, "Couldn't remove user " + userHandle);
-                        } else if (isManagedProfile) {
-                            sendWipeProfileNotification();
+                            boolean isManagedProfile = isManagedProfile(userHandle);
+                            if (!mUserManager.removeUser(userHandle)) {
+                                Slog.w(LOG_TAG, "Couldn't remove user " + userHandle);
+                            } else if (isManagedProfile) {
+                                sendWipeProfileNotification();
+                            }
+                        } catch (RemoteException re) {
+                            // Shouldn't happen
                         }
-                    } catch (RemoteException re) {
-                        // Shouldn't happen
                     }
-                }
-            });
+                });
+            }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -4930,7 +4936,7 @@
             }
             if (wipeData) {
                 // Call without holding lock.
-                wipeDeviceOrUserLocked(false, identifier,
+                wipeDeviceNoLock(false, identifier,
                         "reportFailedPasswordAttempt()");
             }
         } finally {