Implement issue #3094621 and #3094609 - wipe sd card

3094621: add "wipe sd card" option to factory data reset
3094609: collapse unmount/format into one command

Also since we have decided that it is important to consider
the Crespo storage as internal storage, DevicePolicyManager
gets a new API to be able to wipe it.  (No big deal, since
all of the work for this is now done in the implementation
of the new UI.)

Change-Id: I32a77c410f710a87dcdcbf6586c09bd2e48a8807
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 21273cc..1538003 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.storage.ExternalStorageFormatter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.XmlUtils;
@@ -41,6 +42,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IPowerManager;
+import android.os.PowerManager;
 import android.os.RecoverySystem;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
@@ -71,6 +73,7 @@
     
     final Context mContext;
     final MyPackageMonitor mMonitor;
+    final PowerManager.WakeLock mWakeLock;
 
     IPowerManager mIPowerManager;
     
@@ -216,6 +219,8 @@
         mContext = context;
         mMonitor = new MyPackageMonitor();
         mMonitor.register(context, true);
+        mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
+                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
     }
 
     private IPowerManager getIPowerManager() {
@@ -862,10 +867,17 @@
     }
     
     void wipeDataLocked(int flags) {
-        try {
-            RecoverySystem.rebootWipeUserData(mContext);
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed requesting data wipe", e);
+        if ((flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0) {
+            Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
+            intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
+            mWakeLock.acquire(10000);
+            mContext.startService(intent);
+        } else {
+            try {
+                RecoverySystem.rebootWipeUserData(mContext);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed requesting data wipe", e);
+            }
         }
     }
     
diff --git a/services/java/com/android/server/MasterClearReceiver.java b/services/java/com/android/server/MasterClearReceiver.java
index 4d04cee..bdb5a24 100644
--- a/services/java/com/android/server/MasterClearReceiver.java
+++ b/services/java/com/android/server/MasterClearReceiver.java
@@ -29,7 +29,7 @@
     private static final String TAG = "MasterClear";
 
     @Override
-    public void onReceive(Context context, Intent intent) {
+    public void onReceive(final Context context, final Intent intent) {
         if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
             if (!"google.com".equals(intent.getStringExtra("from"))) {
                 Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");
@@ -37,16 +37,23 @@
             }
         }
 
-        try {
-            Slog.w(TAG, "!!! FACTORY RESET !!!");
-            if (intent.hasExtra("enableEFS")) {
-                RecoverySystem.rebootToggleEFS(context, intent.getBooleanExtra("enableEFS", false));
-            } else {
-                RecoverySystem.rebootWipeUserData(context);
+        Slog.w(TAG, "!!! FACTORY RESET !!!");
+        // The reboot call is blocking, so we need to do it on another thread.
+        Thread thr = new Thread("Reboot") {
+            @Override
+            public void run() {
+                try {
+                    if (intent.hasExtra("enableEFS")) {
+                        RecoverySystem.rebootToggleEFS(context, intent.getBooleanExtra("enableEFS", false));
+                    } else {
+                        RecoverySystem.rebootWipeUserData(context);
+                    }
+                    Log.wtf(TAG, "Still running after master clear?!");
+                } catch (IOException e) {
+                    Slog.e(TAG, "Can't perform master clear/factory reset", e);
+                }
             }
-            Log.wtf(TAG, "Still running after master clear?!");
-        } catch (IOException e) {
-            Slog.e(TAG, "Can't perform master clear/factory reset", e);
-        }
+        };
+        thr.start();
     }
 }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index de228d9..aa2f784 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7036,6 +7036,9 @@
                     if (mHeavyWeightProcess == app) {
                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
                     }
+                    if (app.persistent) {
+                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
+                    }
                     int adj = app.curAdj;
                     if (adj >= EMPTY_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;