Eliminate deadlock by deferring wipe data call
The call to RecoverySystem.rebootWipeUserData() was made while holding the lock to DevicePolicyManagerService. But it blocks waiting for system_process' main thread to receive the ordered broadcast complete callback. It won't receive that callback because Keyguard is running on the main thread and is concurrently blocked on DevicePolicyManagerService. By moving the call to rebootWipeUserData() out of the synchronized block the deadlock is eliminated. Fixes bug 16870054. Change-Id: I3eb587211e5484859cc9dab7e80e5a1f6c85225d
This commit is contained in:
@@ -2998,10 +2998,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
|
||||
|
||||
synchronized (this) {
|
||||
DevicePolicyData policy = getUserData(userHandle);
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
boolean wipeData = false;
|
||||
int identifier = 0;
|
||||
synchronized (this) {
|
||||
DevicePolicyData policy = getUserData(userHandle);
|
||||
policy.mFailedPasswordAttempts++;
|
||||
saveSettingsLocked(userHandle);
|
||||
if (mHasFeature) {
|
||||
@@ -3013,15 +3015,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
// Wipe the user/profile associated with the policy that was violated. This
|
||||
// is not necessarily calling user: if the policy that fired was from a
|
||||
// managed profile rather than the main user profile, we wipe former only.
|
||||
wipeDeviceOrUserLocked(0, strictestAdmin.getUserHandle().getIdentifier());
|
||||
wipeData = true;
|
||||
identifier = strictestAdmin.getUserHandle().getIdentifier();
|
||||
}
|
||||
sendAdminCommandToSelfAndProfilesLocked(
|
||||
DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
|
||||
DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
if (wipeData) {
|
||||
// Call without holding lock.
|
||||
wipeDeviceOrUserLocked(0, identifier);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user