Fix SharedPrefsBackupHelper so it doesn't hard code the paths to the files.

This took quite a bit of refactoring.
diff --git a/api/current.xml b/api/current.xml
index f30c505..cf10857 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -29035,6 +29035,19 @@
 <parameter name="mode" type="int">
 </parameter>
 </method>
+<method name="getSharedPrefsFile"
+ return="java.io.File"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
 <method name="getSystemService"
  return="java.lang.Object"
  abstract="false"
@@ -115907,6 +115920,19 @@
 <parameter name="mode" type="int">
 </parameter>
 </method>
+<method name="getSharedPrefsFile"
+ return="java.io.File"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
 <method name="getSystemService"
  return="java.lang.Object"
  abstract="false"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 98bbf7b..fc3cdcf 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -300,10 +300,14 @@
         return new File(prefsFile.getPath() + ".bak");
     }
 
+    public File getSharedPrefsFile(String name) {
+        return makeFilename(getPreferencesDir(), name + ".xml");
+    }
+
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         SharedPreferencesImpl sp;
-        File f = makeFilename(getPreferencesDir(), name + ".xml");
+        File f = getSharedPrefsFile(name);
         synchronized (sSharedPrefs) {
             sp = sSharedPrefs.get(f);
             if (sp != null && !sp.hasFileChanged()) {
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index ec16eb1..99051bf 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import java.io.File;
 import java.io.FileDescriptor;
 
 /** @hide */
@@ -34,22 +35,34 @@
     public static void performBackup(Context context,
             ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState, String[] files) {
-        String basePath = context.getFilesDir().getAbsolutePath();
-        performBackup_checked(basePath, oldState, data, newState, files);
+        File base = context.getFilesDir();
+        final int N = files.length;
+        String[] fullPaths = new String[N];
+        for (int i=0; i<N; i++) {
+            fullPaths[i] = (new File(base, files[i])).getAbsolutePath();
+        }
+        performBackup_checked(oldState, data, newState, fullPaths, files);
     }
 
     /**
      * Check the parameters so the native code doens't have to throw all the exceptions
      * since it's easier to do that from java.
      */
-    static void performBackup_checked(String basePath,
-            ParcelFileDescriptor oldState, BackupDataOutput data,
-            ParcelFileDescriptor newState, String[] files) {
+    static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data,
+            ParcelFileDescriptor newState, String[] files, String[] keys) {
         if (files.length == 0) {
             return;
         }
-        if (basePath == null) {
-            throw new NullPointerException();
+        // files must be all absolute paths
+        for (String f: files) {
+            if (f.charAt(0) != '/') {
+                throw new RuntimeException("files must have all absolute paths: " + f);
+            }
+        }
+        // the length of files and keys must be the same
+        if (files.length != keys.length) {
+            throw new RuntimeException("files.length=" + files.length
+                    + " keys.length=" + keys.length);
         }
         // oldStateFd can be null
         FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
@@ -58,13 +71,14 @@
             throw new NullPointerException();
         }
 
-        int err = performBackup_native(basePath, oldStateFd, data.mBackupWriter, newStateFd, files);
+        int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys);
 
         if (err != 0) {
-            throw new RuntimeException("Backup failed"); // TODO: more here
+            // TODO: more here
+            throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err));
         }
     }
 
-    native private static int performBackup_native(String basePath, FileDescriptor oldState,
-            int data, FileDescriptor newState, String[] files);
+    native private static int performBackup_native(FileDescriptor oldState,
+            int data, FileDescriptor newState, String[] files, String[] keys);
 }
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index 8627f08..923dc1b 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -26,16 +26,14 @@
     public static void performBackup(Context context,
             ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
             BackupDataOutput data, String[] prefGroups) {
-        String basePath = "/xxx"; //context.getPreferencesDir();
-
         // make filenames for the prefGroups
         final int N = prefGroups.length;
         String[] files = new String[N];
         for (int i=0; i<N; i++) {
-            files[i] = prefGroups[i] + ".xml";
+            files[i] = context.getSharedPrefsFile(prefGroups[i]).toString();
         }
 
-        FileBackupHelper.performBackup_checked(basePath, oldSnapshot, data, newSnapshot, files);
+        FileBackupHelper.performBackup_checked(oldSnapshot, data, newSnapshot, files, prefGroups);
     }
 }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ec847a4..925249e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -254,12 +254,20 @@
      * <p>Note: this is not generally useful for applications, since they should
      * not be directly accessing the file system.
      *
-     *
      * @return String Path to the code and assets.
      */
     public abstract String getPackageCodePath();
 
     /**
+     * {@hide}
+     * Return the full path to the shared prefs file for the given prefs group name.
+     *
+     * <p>Note: this is not generally useful for applications, since they should
+     * not be directly accessing the file system.
+     */
+    public abstract File getSharedPrefsFile(String name);
+
+    /**
      * Retrieve and hold the contents of the preferences file 'name', returning
      * a SharedPreferences through which you can retrieve and modify its
      * values.  Only one instance of the SharedPreferences object is returned
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 36e1c34..262204e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -130,6 +130,11 @@
     }
 
     @Override
+    public File getSharedPrefsFile(String name) {
+        return mBase.getSharedPrefsFile(name);
+    }
+
+    @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         return mBase.getSharedPreferences(name, mode);
     }
diff --git a/core/jni/android_backup_FileBackupHelper.cpp b/core/jni/android_backup_FileBackupHelper.cpp
index a46f37b..2ee064b 100644
--- a/core/jni/android_backup_FileBackupHelper.cpp
+++ b/core/jni/android_backup_FileBackupHelper.cpp
@@ -28,8 +28,8 @@
 static jfieldID s_descriptorField = 0;
 
 static int
-performBackup_native(JNIEnv* env, jobject clazz, jstring basePath, jobject oldState, int data,
-        jobject newState, jobjectArray files)
+performBackup_native(JNIEnv* env, jobject clazz, jobject oldState, int data,
+        jobject newState, jobjectArray files, jobjectArray keys)
 {
     int err;
 
@@ -39,29 +39,37 @@
     int newStateFD = env->GetIntField(newState, s_descriptorField);
     BackupDataWriter* dataStream = (BackupDataWriter*)data;
 
-    char const* basePathUTF = env->GetStringUTFChars(basePath, NULL);
-    LOGD("basePathUTF=\"%s\"\n", basePathUTF);
     const int fileCount = env->GetArrayLength(files);
     char const** filesUTF = (char const**)malloc(sizeof(char*)*fileCount);
     for (int i=0; i<fileCount; i++) {
         filesUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(files, i), NULL);
     }
 
-    err = back_up_files(oldStateFD, dataStream, newStateFD, basePathUTF, filesUTF, fileCount);
+    const int keyCount = env->GetArrayLength(keys);
+    char const** keysUTF = (char const**)malloc(sizeof(char*)*keyCount);
+    for (int i=0; i<keyCount; i++) {
+        keysUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(keys, i), NULL);
+    }
+
+    err = back_up_files(oldStateFD, dataStream, newStateFD, filesUTF, keysUTF, fileCount);
 
     for (int i=0; i<fileCount; i++) {
         env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(files, i), filesUTF[i]);
     }
     free(filesUTF);
-    env->ReleaseStringUTFChars(basePath, basePathUTF);
+
+    for (int i=0; i<keyCount; i++) {
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(keys, i), keysUTF[i]);
+    }
+    free(keysUTF);
 
     return err;
 }
 
 static const JNINativeMethod g_methods[] = {
     { "performBackup_native",
-        "(Ljava/lang/String;Ljava/io/FileDescriptor;ILjava/io/FileDescriptor;[Ljava/lang/String;)I",
-        (void*)performBackup_native },
+       "(Ljava/io/FileDescriptor;ILjava/io/FileDescriptor;[Ljava/lang/String;[Ljava/lang/String;)I",
+       (void*)performBackup_native },
 };
 
 int register_android_backup_FileBackupHelper(JNIEnv* env)
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index 24b6c9e..1d0daa7 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -118,7 +118,7 @@
 };
 
 int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
-        char const* fileBase, char const* const* files, int fileCount);
+        char const* const* files, char const* const *keys, int fileCount);
 
 
 #define TEST_BACKUP_HELPERS 1
@@ -127,6 +127,7 @@
 int backup_helper_test_empty();
 int backup_helper_test_four();
 int backup_helper_test_files();
+int backup_helper_test_null_base();
 int backup_helper_test_data_writer();
 int backup_helper_test_data_reader();
 #endif
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 7f423a8..ffe4dff 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -41,8 +41,8 @@
 #define MAGIC0 0x70616e53 // Snap
 #define MAGIC1 0x656c6946 // File
 
-#if 0 // TEST_BACKUP_HELPERS
-#define LOGP(x...) printf(x)
+#if 1 // TEST_BACKUP_HELPERS
+#define LOGP(f, x...) printf(f "\n", x)
 #else
 #define LOGP(x...) LOGD(x)
 #endif
@@ -62,6 +62,11 @@
     int nameLen;
 };
 
+struct FileRec {
+    char const* file; // this object does not own this string
+    FileState s;
+};
+
 const static int ROUND_UP[4] = { 0, 3, 2, 1 };
 
 static inline int
@@ -92,8 +97,8 @@
         FileState file;
         char filenameBuf[128];
 
-        amt = read(fd, &file, sizeof(file));
-        if (amt != sizeof(file)) {
+        amt = read(fd, &file, sizeof(FileState));
+        if (amt != sizeof(FileState)) {
             LOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
             return 1;
         }
@@ -128,7 +133,7 @@
 }
 
 static int
-write_snapshot_file(int fd, const KeyedVector<String8,FileState>& snapshot)
+write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
 {
     int bytesWritten = sizeof(SnapshotHeader);
     // preflight size
@@ -151,11 +156,11 @@
 
     for (int i=0; i<header.fileCount; i++) {
         const String8& name = snapshot.keyAt(i);
-        FileState file = snapshot.valueAt(i);
-        int nameLen = file.nameLen = name.length();
+        FileRec r = snapshot.valueAt(i);
+        int nameLen = r.s.nameLen = name.length();
 
-        amt = write(fd, &file, sizeof(file));
-        if (amt != sizeof(file)) {
+        amt = write(fd, &r.s, sizeof(FileState));
+        if (amt != sizeof(FileState)) {
             LOGW("write_snapshot_file error writing header %s", strerror(errno));
             return 1;
         }
@@ -190,9 +195,9 @@
 
 static int
 write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
-        const String8& realFilename)
+        char const* realFilename)
 {
-    LOGP("write_update_file %s (%s)\n", realFilename.string(), key.string());
+    LOGP("write_update_file %s (%s)\n", realFilename, key.string());
 
     const int bufsize = 4*1024;
     int err;
@@ -237,8 +242,7 @@
             }
         }
         LOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
-                " You aren't doing proper locking!",
-                realFilename.string(), fileSize, fileSize-bytesLeft);
+                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
     }
 
     free(buf);
@@ -247,10 +251,10 @@
 }
 
 static int
-write_update_file(BackupDataWriter* dataStream, const String8& key, const String8& realFilename)
+write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
 {
     int err;
-    int fd = open(realFilename.string(), O_RDONLY);
+    int fd = open(realFilename, O_RDONLY);
     if (fd == -1) {
         return errno;
     }
@@ -281,12 +285,11 @@
 
 int
 back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
-        char const* fileBase, char const* const* files, int fileCount)
+        char const* const* files, char const* const* keys, int fileCount)
 {
     int err;
-    const String8 base(fileBase);
     KeyedVector<String8,FileState> oldSnapshot;
-    KeyedVector<String8,FileState> newSnapshot;
+    KeyedVector<String8,FileRec> newSnapshot;
 
     if (oldSnapshotFD != -1) {
         err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
@@ -297,26 +300,28 @@
     }
 
     for (int i=0; i<fileCount; i++) {
-        String8 name(files[i]);
-        FileState s;
+        String8 key(keys[i]);
+        FileRec r;
+        char const* file = r.file = files[i];
         struct stat st;
-        String8 realFilename(base);
-        realFilename.appendPath(name);
 
-        err = stat(realFilename.string(), &st);
+        err = stat(file, &st);
         if (err != 0) {
-            LOGW("Error stating file %s", realFilename.string());
+            LOGW("Error stating file %s", file);
             continue;
         }
 
-        s.modTime_sec = st.st_mtime;
-        s.modTime_nsec = 0; // workaround sim breakage
-        //s.modTime_nsec = st.st_mtime_nsec;
-        s.size = st.st_size;
-
+        r.s.modTime_sec = st.st_mtime;
+        r.s.modTime_nsec = 0; // workaround sim breakage
+        //r.s.modTime_nsec = st.st_mtime_nsec;
+        r.s.size = st.st_size;
         // we compute the crc32 later down below, when we already have the file open.
-
-        newSnapshot.add(name, s);
+        
+        if (newSnapshot.indexOfKey(key) >= 0) {
+            LOGP("back_up_files key already in use '%s'", key.string());
+            return -1;
+        }
+        newSnapshot.add(key, r);
     }
 
     int n = 0;
@@ -329,43 +334,39 @@
         int cmp = p.compare(q);
         if (cmp > 0) {
             // file added
-            String8 realFilename(base);
-            realFilename.appendPath(q);
-            LOGP("file added: %s\n", realFilename.string());
-            write_update_file(dataStream, q, realFilename);
+            const FileRec& g = newSnapshot.valueAt(m);
+            LOGP("file added: %s", g.file);
+            write_update_file(dataStream, q, g.file);
             m++;
         }
         else if (cmp < 0) {
             // file removed
-            LOGP("file removed: %s\n", p.string());
+            LOGP("file removed: %s", p.string());
             dataStream->WriteEntityHeader(p, -1);
             n++;
         }
         else {
-
             // both files exist, check them
-            String8 realFilename(base);
-            realFilename.appendPath(q);
             const FileState& f = oldSnapshot.valueAt(n);
-            FileState& g = newSnapshot.editValueAt(m);
+            FileRec& g = newSnapshot.editValueAt(m);
 
-            int fd = open(realFilename.string(), O_RDONLY);
+            int fd = open(g.file, O_RDONLY);
             if (fd < 0) {
                 // We can't open the file.  Don't report it as a delete either.  Let the
                 // server keep the old version.  Maybe they'll be able to deal with it
                 // on restore.
-                LOGP("Unable to open file %s - skipping", realFilename.string());
+                LOGP("Unable to open file %s - skipping", g.file);
             } else {
-                g.crc32 = compute_crc32(fd);
+                g.s.crc32 = compute_crc32(fd);
 
-                LOGP("%s\n", q.string());
-                LOGP("  new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+                LOGP("%s", q.string());
+                LOGP("  new: modTime=%d,%d size=%-3d crc32=0x%08x",
                         f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
-                LOGP("  old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
-                        g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
-                if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
-                        || f.size != g.size || f.crc32 != g.crc32) {
-                    write_update_file(dataStream, fd, p, realFilename);
+                LOGP("  old: modTime=%d,%d size=%-3d crc32=0x%08x",
+                        g.s.modTime_sec, g.s.modTime_nsec, g.s.size, g.s.crc32);
+                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
+                        || f.size != g.s.size || f.crc32 != g.s.crc32) {
+                    write_update_file(dataStream, fd, p, g.file);
                 }
 
                 close(fd);
@@ -384,9 +385,8 @@
     // these were added
     while (m<fileCount) {
         const String8& q = newSnapshot.keyAt(m);
-        String8 realFilename(base);
-        realFilename.appendPath(q);
-        write_update_file(dataStream, q, realFilename);
+        FileRec& g = newSnapshot.editValueAt(m);
+        write_update_file(dataStream, q, g.file);
         m++;
     }
 
@@ -475,7 +475,7 @@
 {
     int err;
     int fd;
-    KeyedVector<String8,FileState> snapshot;
+    KeyedVector<String8,FileRec> snapshot;
     const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
 
     system("rm -r " SCRATCH_DIR);
@@ -534,7 +534,7 @@
 {
     int err;
     int fd;
-    KeyedVector<String8,FileState> snapshot;
+    KeyedVector<String8,FileRec> snapshot;
     const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
 
     system("rm -r " SCRATCH_DIR);
@@ -549,38 +549,44 @@
 
     String8 filenames[4];
     FileState states[4];
+    FileRec r;
+    r.file = NULL;
 
     states[0].modTime_sec = 0xfedcba98;
     states[0].modTime_nsec = 0xdeadbeef;
     states[0].size = 0xababbcbc;
     states[0].crc32 = 0x12345678;
     states[0].nameLen = -12;
+    r.s = states[0];
     filenames[0] = String8("bytes_of_padding");
-    snapshot.add(filenames[0], states[0]);
+    snapshot.add(filenames[0], r);
 
     states[1].modTime_sec = 0x93400031;
     states[1].modTime_nsec = 0xdeadbeef;
     states[1].size = 0x88557766;
     states[1].crc32 = 0x22334422;
     states[1].nameLen = -1;
+    r.s = states[1];
     filenames[1] = String8("bytes_of_padding3");
-    snapshot.add(filenames[1], states[1]);
+    snapshot.add(filenames[1], r);
 
     states[2].modTime_sec = 0x33221144;
     states[2].modTime_nsec = 0xdeadbeef;
     states[2].size = 0x11223344;
     states[2].crc32 = 0x01122334;
     states[2].nameLen = 0;
+    r.s = states[2];
     filenames[2] = String8("bytes_of_padding_2");
-    snapshot.add(filenames[2], states[2]);
+    snapshot.add(filenames[2], r);
 
     states[3].modTime_sec = 0x33221144;
     states[3].modTime_nsec = 0xdeadbeef;
     states[3].size = 0x11223344;
     states[3].crc32 = 0x01122334;
     states[3].nameLen = 0;
+    r.s = states[3];
     filenames[3] = String8("bytes_of_padding__1");
-    snapshot.add(filenames[3], states[3]);
+    snapshot.add(filenames[3], r);
 
     err = write_snapshot_file(fd, snapshot);
 
@@ -982,6 +988,14 @@
     write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
 
     char const* files_before[] = {
+        SCRATCH_DIR "data/b",
+        SCRATCH_DIR "data/c",
+        SCRATCH_DIR "data/d",
+        SCRATCH_DIR "data/e",
+        SCRATCH_DIR "data/f"
+    };
+
+    char const* keys_before[] = {
         "data/b",
         "data/c",
         "data/d",
@@ -1004,7 +1018,7 @@
     {
         BackupDataWriter dataStream(dataStreamFD);
 
-        err = back_up_files(-1, &dataStream, newSnapshotFD, SCRATCH_DIR, files_before, 5);
+        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
         if (err != 0) {
             return err;
         }
@@ -1035,6 +1049,15 @@
     unlink(SCRATCH_DIR "data/f");
 
     char const* files_after[] = {
+        SCRATCH_DIR "data/a", // added
+        SCRATCH_DIR "data/b", // same
+        SCRATCH_DIR "data/c", // different mod time
+        SCRATCH_DIR "data/d", // different size (same mod time)
+        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
+        SCRATCH_DIR "data/g"  // added
+    };
+
+    char const* keys_after[] = {
         "data/a", // added
         "data/b", // same
         "data/c", // different mod time
@@ -1064,8 +1087,7 @@
     {
         BackupDataWriter dataStream(dataStreamFD);
 
-        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, SCRATCH_DIR,
-                files_after, 6);
+        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
         if (err != 0) {
             return err;
         }
@@ -1078,6 +1100,56 @@
     return 0;
 }
 
+int
+backup_helper_test_null_base()
+{
+    int err;
+    int oldSnapshotFD;
+    int dataStreamFD;
+    int newSnapshotFD;
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
+
+    char const* files[] = {
+        SCRATCH_DIR "data/a",
+    };
+
+    char const* keys[] = {
+        "a",
+    };
+
+    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
+    if (dataStreamFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
+    if (newSnapshotFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+
+        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    close(dataStreamFD);
+    close(newSnapshotFD);
+
+    return 0;
+}
+
+
 #endif // TEST_BACKUP_HELPERS
 
 }
diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java
index e733dd1..9e0cf2c 100644
--- a/test-runner/android/test/mock/MockContext.java
+++ b/test-runner/android/test/mock/MockContext.java
@@ -105,6 +105,11 @@
     }
 
     @Override
+    public File getSharedPrefsFile(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public String getPackageCodePath() {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/backup/backup_helper_test.cpp b/tests/backup/backup_helper_test.cpp
index f087941..919df93 100644
--- a/tests/backup/backup_helper_test.cpp
+++ b/tests/backup/backup_helper_test.cpp
@@ -38,6 +38,7 @@
     { "backup_helper_test_empty", backup_helper_test_empty, 0, false },
     { "backup_helper_test_four", backup_helper_test_four, 0, false },
     { "backup_helper_test_files", backup_helper_test_files, 0, false },
+    { "backup_helper_test_null_base", backup_helper_test_null_base, 0, false },
     { "backup_helper_test_data_writer", backup_helper_test_data_writer, 0, false },
     { "backup_helper_test_data_reader", backup_helper_test_data_reader, 0, false },
     { 0, NULL, 0, false}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index baa3d53..d0896b5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -966,6 +966,12 @@
     }
 
     @Override
+    public File getSharedPrefsFile(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
     public SharedPreferences getSharedPreferences(String arg0, int arg1) {
         // TODO Auto-generated method stub
         return null;