diff options
| -rw-r--r-- | core/java/android/backup/BackupDataInputStream.java | 2 | ||||
| -rw-r--r-- | core/java/android/backup/FileRestoreHelper.java | 41 | ||||
| -rw-r--r-- | core/java/android/backup/RestoreHelper.java | 2 | ||||
| -rw-r--r-- | core/java/android/backup/RestoreHelperBase.java | 85 | ||||
| -rw-r--r-- | core/java/android/backup/RestoreHelperDispatcher.java | 4 | ||||
| -rw-r--r-- | include/utils/BackupHelpers.h | 2 | ||||
| -rw-r--r-- | libs/utils/BackupData.cpp | 8 | ||||
| -rw-r--r-- | tests/backup/src/com/android/backuptest/BackupTestActivity.java | 60 | 
8 files changed, 193 insertions, 11 deletions
| diff --git a/core/java/android/backup/BackupDataInputStream.java b/core/java/android/backup/BackupDataInputStream.java index 52b1675..b705c4c 100644 --- a/core/java/android/backup/BackupDataInputStream.java +++ b/core/java/android/backup/BackupDataInputStream.java @@ -16,6 +16,8 @@  package android.backup; +import android.util.Log; +  import java.io.InputStream;  import java.io.IOException; diff --git a/core/java/android/backup/FileRestoreHelper.java b/core/java/android/backup/FileRestoreHelper.java new file mode 100644 index 0000000..b7e3625 --- /dev/null +++ b/core/java/android/backup/FileRestoreHelper.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.backup; + +import android.content.Context; +import android.util.Log; + +import java.io.File; + +/** @hide */ +public class FileRestoreHelper extends RestoreHelperBase implements RestoreHelper { +    private static final String TAG = "FileRestoreHelper"; + +    File mFilesDir; + +    public FileRestoreHelper(Context context) { +        super(context); +        mFilesDir = context.getFilesDir(); +    } + +    public void restoreEntity(BackupDataInputStream data) { +        Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); // TODO: turn this off before ship +        File f = new File(mFilesDir, data.getKey()); +        writeFile(f, data); +    } +} + diff --git a/core/java/android/backup/RestoreHelper.java b/core/java/android/backup/RestoreHelper.java index ee8bedd..ac7d8ee 100644 --- a/core/java/android/backup/RestoreHelper.java +++ b/core/java/android/backup/RestoreHelper.java @@ -26,6 +26,6 @@ public interface RestoreHelper {       * Do not close the <code>data</code> stream.  Do not read more than       * <code>dataSize</code> bytes from <code>data</code>.       */ -    public void performRestore(BackupDataInputStream data); +    public void restoreEntity(BackupDataInputStream data);  } diff --git a/core/java/android/backup/RestoreHelperBase.java b/core/java/android/backup/RestoreHelperBase.java new file mode 100644 index 0000000..894c9af --- /dev/null +++ b/core/java/android/backup/RestoreHelperBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.backup; + +import android.content.Context; +import android.util.Log; + +import java.io.InputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +class RestoreHelperBase { +    private static final String TAG = "RestoreHelperBase"; +    private static final int BUF_SIZE = 8 * 1024; + +    Context mContext; +    byte[] mBuf = new byte[BUF_SIZE]; +    boolean mExceptionLogged; +     +    RestoreHelperBase(Context context) { +        mContext = context; +    } + +    void writeFile(File f, InputStream in) { +        boolean success = false; +        FileOutputStream out = null; +        try { +            // Create the enclosing directory. +            File parent = f.getParentFile(); +            parent.mkdirs(); + +            // Copy the file. +            int sum = 0; +            out = new FileOutputStream(f); +            byte[] buf = mBuf; +            int amt; +            while ((amt = in.read(buf)) > 0) { +                out.write(buf, 0, amt); +                sum += amt; +            } + +            // TODO: Set the permissions of the file. + +            // We're done +            success = true; +            out = null; +        } catch (IOException ex) { +            // Bail on this entity.  Only log one exception per helper object. +            if (!mExceptionLogged) { +                Log.e(TAG, "Failed restoring file '" + f + "' for app '" +                    + mContext.getPackageName() + '\'', ex); +                mExceptionLogged = true; +            } +        } +        finally { +            if (out != null) { +                try { +                    out.close(); +                } catch (IOException ex) { +                } +            } +            if (!success) { +                // Something didn't work out, delete the file +                f.delete(); +            } +        } +    } +} + + diff --git a/core/java/android/backup/RestoreHelperDispatcher.java b/core/java/android/backup/RestoreHelperDispatcher.java index cbfefdc..8fcade4 100644 --- a/core/java/android/backup/RestoreHelperDispatcher.java +++ b/core/java/android/backup/RestoreHelperDispatcher.java @@ -21,7 +21,7 @@ import java.util.HashMap;  /** @hide */  public class RestoreHelperDispatcher { -    HashMap<String,RestoreHelper> mHelpers; +    HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>();      public void addHelper(String keyPrefix, RestoreHelper helper) {          mHelpers.put(keyPrefix, helper); @@ -38,7 +38,7 @@ public class RestoreHelperDispatcher {                  if (helper != null) {                      stream.dataSize = input.getDataSize();                      stream.key = rawKey.substring(pos+1); -                    helper.performRestore(stream); +                    helper.restoreEntity(stream);                  }              }              input.skipEntityData(); // In case they didn't consume the data. diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h index 3ca8ad2..fa7f8d5 100644 --- a/include/utils/BackupHelpers.h +++ b/include/utils/BackupHelpers.h @@ -78,7 +78,7 @@ public:      bool HasEntities();      status_t ReadEntityHeader(String8* key, size_t* dataSize);      status_t SkipEntityData(); // must be called with the pointer at the begining of the data. -    status_t ReadEntityData(void* data, size_t size); +    ssize_t ReadEntityData(void* data, size_t size);  private:      explicit BackupDataReader(); diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp index 16ff1e5..34b37ed 100644 --- a/libs/utils/BackupData.cpp +++ b/libs/utils/BackupData.cpp @@ -281,16 +281,16 @@ BackupDataReader::SkipEntityData()      }  } -status_t +ssize_t  BackupDataReader::ReadEntityData(void* data, size_t size)  {      if (m_status != NO_ERROR) {          return m_status;      }      int remaining = m_dataEndPos - m_pos; +    //LOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n", +    //        size, m_pos, m_dataEndPos, remaining);      if (size > remaining) { -        printf("size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n", -                size, m_pos, m_dataEndPos, remaining);          size = remaining;      }      if (remaining <= 0) { @@ -299,7 +299,7 @@ BackupDataReader::ReadEntityData(void* data, size_t size)      int amt = read(m_fd, data, size);      CHECK_SIZE(amt, (int)size);      m_pos += size; -    return NO_ERROR; +    return amt;  }  status_t diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java index af7dfd4..aa940ae 100644 --- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java +++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java @@ -17,14 +17,17 @@  package com.android.backuptest;  import android.app.ListActivity; +import android.backup.BackupDataInput; +import android.backup.BackupDataOutput;  import android.backup.BackupManager; +import android.backup.FileBackupHelper; +import android.backup.FileRestoreHelper; +import android.backup.RestoreHelperDispatcher;  import android.content.Intent;  import android.content.SharedPreferences; -import android.net.Uri;  import android.os.Bundle;  import android.os.Handler; -import android.os.PowerManager; -import android.os.SystemClock; +import android.os.ParcelFileDescriptor;  import android.util.Log;  import android.view.View;  import android.widget.ArrayAdapter; @@ -32,6 +35,10 @@ import android.widget.ListView;  import android.widget.Toast;  import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException;  import java.io.InputStreamReader;  import java.io.IOException;  import java.io.PrintStream; @@ -123,6 +130,44 @@ public class BackupTestActivity extends ListActivity                  BackupManager bm = new BackupManager(BackupTestActivity.this);                  bm.dataChanged();              } +        }, +        new Test("Backup Helpers") { +            void run() { +                try { +                    writeFile("a", "a\naa", MODE_PRIVATE); +                    writeFile("empty", "", MODE_PRIVATE); + +                    ParcelFileDescriptor state = ParcelFileDescriptor.open( +                            new File(getFilesDir(), "state"), +                            ParcelFileDescriptor.MODE_READ_WRITE|ParcelFileDescriptor.MODE_CREATE| +                            ParcelFileDescriptor.MODE_TRUNCATE); +                    FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this, +                            "FileBackupHelper"); +                    FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE); +                    BackupDataOutput data = new BackupDataOutput(BackupTestActivity.this, +                            dataFile.getFD()); +                    h.performBackup(null, data, state, new String[] { "a", "empty" }); +                    dataFile.close(); +                    state.close(); +                } catch (IOException ex) { +                    throw new RuntimeException(ex); +                } +            } +        }, +        new Test("Restore Helpers") { +            void run() { +                try { +                    RestoreHelperDispatcher dispatch = new RestoreHelperDispatcher(); +                    dispatch.addHelper("FileBackupHelper", +                            new FileRestoreHelper(BackupTestActivity.this)); +                    FileInputStream dataFile = openFileInput("backup_test"); +                    BackupDataInput data = new BackupDataInput(dataFile.getFD()); +                    dispatch.dispatch(data); +                    dataFile.close(); +                } catch (IOException ex) { +                    throw new RuntimeException(ex); +                } +            }          }      }; @@ -154,5 +199,14 @@ public class BackupTestActivity extends ListActivity          t.run();      } +    void writeFile(String name, String contents, int mode) { +        try { +            PrintStream out = new PrintStream(openFileOutput(name, mode)); +            out.print(contents); +            out.close(); +        } catch (FileNotFoundException ex) { +            throw new RuntimeException(ex); +        } +    }  } | 
