OSDN Git Service

Do not call RecoverySystem with DPMS lock held
authorMakoto Onuki <omakoto@google.com>
Wed, 4 Jan 2017 22:36:59 +0000 (14:36 -0800)
committerMakoto Onuki <omakoto@google.com>
Fri, 27 Jan 2017 22:08:01 +0000 (14:08 -0800)
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: Ib97a92a6af87a5589d2643b9ae0522395735e1a5

services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java

index 1a5e315..fd3fa82 100644 (file)
@@ -4750,7 +4750,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         }
     }
 
-    private void wipeDataLocked(boolean wipeExtRequested, String reason) {
+    private void wipeDataNoLock(boolean wipeExtRequested, String reason) {
         if (wipeExtRequested) {
             StorageManager sm = (StorageManager) mContext.getSystemService(
                     Context.STORAGE_SERVICE);
@@ -4770,13 +4770,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         }
         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 {
@@ -4791,39 +4792,44 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                         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);
         }
     }
 
@@ -5003,7 +5009,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
             }
             if (wipeData) {
                 // Call without holding lock.
-                wipeDeviceOrUserLocked(false, identifier,
+                wipeDeviceNoLock(false, identifier,
                         "reportFailedPasswordAttempt()");
             }
         } finally {