Fix remote device wipe to not hang.

The DPM seemed to always go through ExternalStorageFormatter to wipe the
device and SD card. For SD cards emulated on a fuse filesystem, this
seems to fail unless the device is wholly encrypted. Bypass
ExternalStorageFormatter in those cases and just wipe as normal.

Bug: 5458396
Change-Id: Iec759ef894c6bd3863cb4e7329f4de4584c60c1a
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index f1b8bae..47644de 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -44,6 +44,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IPowerManager;
@@ -1656,8 +1657,18 @@
         }
     }
 
+    private boolean isExtStorageEncrypted() {
+        String state = SystemProperties.get("vold.decrypt");
+        return !"".equals(state);
+    }
+
     void wipeDataLocked(int flags) {
-        if ((flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0) {
+        // If the SD card is encrypted and non-removable, we have to force a wipe.
+        boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
+        boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
+
+        // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
+        if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
             Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
             intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
             mWakeLock.acquire(10000);