backup fixes:

- BackupTestAgent calls the DispatchHelper
- Make BackupAgent.onRestore take a BackupDataInput, not just a
  generic ParcelFileDescriptor.
diff --git a/core/java/android/app/BackupAgent.java b/core/java/android/app/BackupAgent.java
index 997bfdc..85c001c 100644
--- a/core/java/android/app/BackupAgent.java
+++ b/core/java/android/app/BackupAgent.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.app.IBackupAgent;
+import android.backup.BackupDataInput;
 import android.backup.BackupDataOutput;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -25,6 +26,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.io.IOException;
+
 /**
  * This is the central interface between an application and Android's
  * settings backup mechanism.
@@ -32,6 +35,8 @@
  * @hide pending API solidification
  */
 public abstract class BackupAgent extends ContextWrapper {
+    private static final String TAG = "BackupAgent";
+
     public BackupAgent() {
         super(null);
     }
@@ -77,8 +82,8 @@
      *                 file.  The application should record the final backup state
      *                 here after restoring its data from dataFd.
      */
-    public abstract void onRestore(ParcelFileDescriptor /* TODO: BackupDataInput */ data,
-            ParcelFileDescriptor newState);
+    public abstract void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
+            throws IOException;
 
 
     // ----- Core implementation -----
@@ -107,13 +112,11 @@
                 ParcelFileDescriptor newState) throws RemoteException {
             // !!! TODO - real implementation; for now just invoke the callbacks directly
             Log.v(TAG, "doBackup() invoked");
-            BackupDataOutput output = new BackupDataOutput(BackupAgent.this,
-                    data.getFileDescriptor());
+            BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor());
             try {
                 BackupAgent.this.onBackup(oldState, output, newState);
             } catch (RuntimeException ex) {
-                Log.d("BackupAgent", "onBackup ("
-                        + BackupAgent.this.getClass().getName() + ") threw", ex);
+                Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
                 throw ex;
             }
         }
@@ -122,7 +125,16 @@
                 ParcelFileDescriptor newState) throws RemoteException {
             // !!! TODO - real implementation; for now just invoke the callbacks directly
             Log.v(TAG, "doRestore() invoked");
-            BackupAgent.this.onRestore(data, newState);
+            BackupDataInput input = new BackupDataInput(data.getFileDescriptor());
+            try {
+                BackupAgent.this.onRestore(input, newState);
+            } catch (IOException ex) {
+                Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
+                throw new RuntimeException(ex);
+            } catch (RuntimeException ex) {
+                Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
+                throw ex;
+            }
         }
     }
 }
diff --git a/core/java/android/app/FullBackupAgent.java b/core/java/android/app/FullBackupAgent.java
index bf5cb5d..89becf4 100644
--- a/core/java/android/app/FullBackupAgent.java
+++ b/core/java/android/app/FullBackupAgent.java
@@ -1,5 +1,6 @@
 package android.app;
 
+import android.backup.BackupDataInput;
 import android.backup.BackupDataOutput;
 import android.backup.FileBackupHelper;
 import android.os.ParcelFileDescriptor;
@@ -52,6 +53,6 @@
     }
 
     @Override
-    public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) {
+    public void onRestore(BackupDataInput data, ParcelFileDescriptor newState) {
     }
 }
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index 1348d81..a6d5bec 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -24,13 +24,11 @@
 /** @hide */
 public class BackupDataOutput {
     int mBackupWriter;
-    private Context mContext;
 
     public static final int OP_UPDATE = 1;
     public static final int OP_DELETE = 2;
 
-    public BackupDataOutput(Context context, FileDescriptor fd) {
-        mContext = context;
+    public BackupDataOutput(FileDescriptor fd) {
         if (fd == null) throw new NullPointerException();
         mBackupWriter = ctor(fd);
         if (mBackupWriter == 0) {
diff --git a/core/java/android/backup/RestoreHelperDispatcher.java b/core/java/android/backup/RestoreHelperDispatcher.java
index 8fcade4..5928914 100644
--- a/core/java/android/backup/RestoreHelperDispatcher.java
+++ b/core/java/android/backup/RestoreHelperDispatcher.java
@@ -16,11 +16,15 @@
 
 package android.backup;
 
+import android.util.Log;
+
 import java.io.IOException;
 import java.util.HashMap;
 
 /** @hide */
 public class RestoreHelperDispatcher {
+    private static final String TAG = "RestoreHelperDispatcher";
+
     HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>();
 
     public void addHelper(String keyPrefix, RestoreHelper helper) {
@@ -28,8 +32,11 @@
     }
 
     public void dispatch(BackupDataInput input) throws IOException {
+        boolean alreadyComplained = false;
+
         BackupDataInputStream stream = new BackupDataInputStream(input);
         while (input.readNextHeader()) {
+
             String rawKey = input.getKey();
             int pos = rawKey.indexOf(':');
             if (pos > 0) {
@@ -39,6 +46,16 @@
                     stream.dataSize = input.getDataSize();
                     stream.key = rawKey.substring(pos+1);
                     helper.restoreEntity(stream);
+                } else {
+                    if (!alreadyComplained) {
+                        Log.w(TAG, "Couldn't find helper for: '" + rawKey + "'");
+                        alreadyComplained = true;
+                    }
+                }
+            } else {
+                if (!alreadyComplained) {
+                    Log.w(TAG, "Entity with no prefix: '" + rawKey + "'");
+                    alreadyComplained = true;
                 }
             }
             input.skipEntityData(); // In case they didn't consume the data.
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 123c072..577ecb4 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -160,7 +160,7 @@
         File[] blobs = packageDir.listFiles();
         int err = 0;
         if (blobs != null && blobs.length > 0) {
-            BackupDataOutput out = new BackupDataOutput(mContext, outFd.getFileDescriptor());
+            BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
             try {
                 for (File f : blobs) {
                     FileInputStream in = new FileInputStream(f);
diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
index aa940ae..d87e85c 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
@@ -144,8 +144,7 @@
                     FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this,
                             "FileBackupHelper");
                     FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE);
-                    BackupDataOutput data = new BackupDataOutput(BackupTestActivity.this,
-                            dataFile.getFD());
+                    BackupDataOutput data = new BackupDataOutput(dataFile.getFD());
                     h.performBackup(null, data, state, new String[] { "a", "empty" });
                     dataFile.close();
                     state.close();
diff --git a/tests/backup/src/com/android/backuptest/BackupTestAgent.java b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
index a370d69..e3566ec 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestAgent.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
@@ -17,28 +17,45 @@
 package com.android.backuptest;
 
 import android.app.BackupAgent;
+import android.backup.BackupDataInput;
 import android.backup.BackupDataOutput;
 import android.backup.FileBackupHelper;
+import android.backup.FileRestoreHelper;
+import android.backup.RestoreHelperDispatcher;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import java.io.IOException;
+
 public class BackupTestAgent extends BackupAgent
 {
     static final String TAG = "BackupTestAgent";
 
+    static final String SHARED_PREFS = "shared_prefs";
+    static final String DATA_FILES = "data_files";
+    static final String[] FILES = new String[] {
+                    BackupTestActivity.FILE_NAME
+                };
+
     @Override
     public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
              ParcelFileDescriptor newState) {
         Log.d(TAG, "onBackup");
-        FileBackupHelper helper = new FileBackupHelper(this);
-        helper.performBackup(oldState, data, newState, new String[] {
-                    BackupTestActivity.FILE_NAME
-                });
+
+        (new FileBackupHelper(this, DATA_FILES)).performBackup(oldState, data, newState, FILES);
     }
 
     @Override
-    public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) {
+    public void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
+            throws IOException {
         Log.d(TAG, "onRestore");
+
+        RestoreHelperDispatcher dispatch = new RestoreHelperDispatcher();
+
+        // dispatch.addHelper(SHARED_PREFS, new SharedPrefsRestoreHelper(this));
+        dispatch.addHelper(DATA_FILES, new FileRestoreHelper(this));
+
+        dispatch.dispatch(data);
     }
 }