Restore from a previous full backup's tarfile

Usage:  adb restore [tarfilename]

Restores app data [and installs the apps if necessary from the backup
file] captured in a previous invocation of 'adb backup'.  The user
must explicitly acknowledge the action on-device before it is allowed
to proceed; this prevents any "invisible" pushes of content from the
host to the device.

Known issues:

* The settings databases and wallpaper are saved/restored, but lots
  of other system state is not yet captured in the full backup.  This
  means that for practical purposes this is usable for 3rd party
  apps at present but not for full-system cloning/imaging.

Change-Id: I0c748b645845e7c9178e30bf142857861a64efd3
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 85e59b3..955cef2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1980,7 +1980,8 @@
         BackupAgent agent = null;
         String classname = data.appInfo.backupAgentName;
 
-        if (data.backupMode == IApplicationThread.BACKUP_MODE_FULL) {
+        if (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
+                || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
             classname = "android.app.backup.FullBackupAgent";
             if ((data.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                 // system packages can supply their own full-backup agent
@@ -2011,7 +2012,8 @@
                 // If this is during restore, fail silently; otherwise go
                 // ahead and let the user see the crash.
                 Slog.e(TAG, "Agent threw during creation: " + e);
-                if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE) {
+                if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
+                        && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
                     throw e;
                 }
                 // falling through with 'binder' still null
@@ -3658,12 +3660,16 @@
         Application app = data.info.makeApplication(data.restrictedBackupMode, null);
         mInitialApplication = app;
 
-        List<ProviderInfo> providers = data.providers;
-        if (providers != null) {
-            installContentProviders(app, providers);
-            // For process that contains content providers, we want to
-            // ensure that the JIT is enabled "at some point".
-            mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
+        // don't bring up providers in restricted mode; they may depend on the
+        // app's custom Application class
+        if (!data.restrictedBackupMode){ 
+            List<ProviderInfo> providers = data.providers;
+            if (providers != null) {
+                installContentProviders(app, providers);
+                // For process that contains content providers, we want to
+                // ensure that the JIT is enabled "at some point".
+                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
+            }
         }
 
         try {