diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/backup/RestoreHelper.java | 3 | ||||
-rw-r--r-- | core/java/android/backup/RestoreHelperBase.java | 71 | ||||
-rw-r--r-- | core/java/android/backup/RestoreHelperDispatcher.java | 16 | ||||
-rw-r--r-- | core/jni/Android.mk | 3 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_backup_RestoreHelperBase.cpp | 94 |
6 files changed, 150 insertions, 39 deletions
diff --git a/core/java/android/backup/RestoreHelper.java b/core/java/android/backup/RestoreHelper.java index ac7d8ee..e47869c 100644 --- a/core/java/android/backup/RestoreHelper.java +++ b/core/java/android/backup/RestoreHelper.java @@ -16,6 +16,8 @@ package android.backup; +import android.os.ParcelFileDescriptor; + import java.io.InputStream; /** @hide */ @@ -27,5 +29,6 @@ public interface RestoreHelper { * <code>dataSize</code> bytes from <code>data</code>. */ public void restoreEntity(BackupDataInputStream data); + public void writeSnapshot(ParcelFileDescriptor fd); } diff --git a/core/java/android/backup/RestoreHelperBase.java b/core/java/android/backup/RestoreHelperBase.java index 894c9af..93a8fef 100644 --- a/core/java/android/backup/RestoreHelperBase.java +++ b/core/java/android/backup/RestoreHelperBase.java @@ -17,69 +17,66 @@ package android.backup; import android.content.Context; +import android.os.ParcelFileDescriptor; import android.util.Log; import java.io.InputStream; import java.io.File; +import java.io.FileDescriptor; import java.io.FileOutputStream; -import java.io.IOException; class RestoreHelperBase { private static final String TAG = "RestoreHelperBase"; - private static final int BUF_SIZE = 8 * 1024; + int mPtr; Context mContext; - byte[] mBuf = new byte[BUF_SIZE]; boolean mExceptionLogged; RestoreHelperBase(Context context) { + mPtr = ctor(); mContext = context; } - void writeFile(File f, InputStream in) { - boolean success = false; - FileOutputStream out = null; + protected void finalize() throws Throwable { try { - // Create the enclosing directory. - File parent = f.getParentFile(); - parent.mkdirs(); + dtor(mPtr); + } finally { + super.finalize(); + } + } - // 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; - } + void writeFile(File f, InputStream in) { + if (!(in instanceof BackupDataInputStream)) { + throw new IllegalStateException("input stream must be a BackupDataInputStream"); + } + int result = -1; - // TODO: Set the permissions of the file. + // Create the enclosing directory. + File parent = f.getParentFile(); + parent.mkdirs(); - // We're done - success = true; - out = null; - } catch (IOException ex) { - // Bail on this entity. Only log one exception per helper object. + result = writeFile_native(mPtr, f.getAbsolutePath(), + ((BackupDataInputStream)in).mData.mBackupReader); + if (result != 0) { + // Bail on this entity. Only log one failure per helper object. if (!mExceptionLogged) { Log.e(TAG, "Failed restoring file '" + f + "' for app '" - + mContext.getPackageName() + '\'', ex); + + mContext.getPackageName() + "\' result=0x" + + Integer.toHexString(result)); mExceptionLogged = true; } } - finally { - if (out != null) { - try { - out.close(); - } catch (IOException ex) { - } - } - if (!success) { - // Something didn't work out, delete the file - f.delete(); - } - } } + + public void writeSnapshot(ParcelFileDescriptor fd) { + int result = writeSnapshot_native(mPtr, fd.getFileDescriptor()); + // TODO: Do something with the error. + } + + private static native int ctor(); + private static native void dtor(int ptr); + private static native int writeFile_native(int ptr, String filename, int backupReader); + private static native int writeSnapshot_native(int ptr, FileDescriptor fd); } diff --git a/core/java/android/backup/RestoreHelperDispatcher.java b/core/java/android/backup/RestoreHelperDispatcher.java index 5928914..4861775 100644 --- a/core/java/android/backup/RestoreHelperDispatcher.java +++ b/core/java/android/backup/RestoreHelperDispatcher.java @@ -16,10 +16,12 @@ package android.backup; +import android.os.ParcelFileDescriptor; import android.util.Log; import java.io.IOException; import java.util.HashMap; +import java.util.Map; /** @hide */ public class RestoreHelperDispatcher { @@ -31,7 +33,7 @@ public class RestoreHelperDispatcher { mHelpers.put(keyPrefix, helper); } - public void dispatch(BackupDataInput input) throws IOException { + public void dispatch(BackupDataInput input, ParcelFileDescriptor newState) throws IOException { boolean alreadyComplained = false; BackupDataInputStream stream = new BackupDataInputStream(input); @@ -60,5 +62,17 @@ public class RestoreHelperDispatcher { } input.skipEntityData(); // In case they didn't consume the data. } + + if (mHelpers.size() > 1) { + throw new RuntimeException("RestoreHelperDispatcher won't get your your" + + " data in the right order yet."); + } + + // Write out the state files + for (RestoreHelper helper: mHelpers.values()) { + // TODO: Write a header for the state + helper.writeSnapshot(newState); + } } } + diff --git a/core/jni/Android.mk b/core/jni/Android.mk index aca6670..a42eef1 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -117,7 +117,8 @@ LOCAL_SRC_FILES:= \ com_android_internal_graphics_NativeUtils.cpp \ android_backup_BackupDataInput.cpp \ android_backup_BackupDataOutput.cpp \ - android_backup_FileBackupHelper.cpp + android_backup_FileBackupHelper.cpp \ + android_backup_RestoreHelperBase.cpp LOCAL_C_INCLUDES += \ $(JNI_H_INCLUDE) \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 4512fef..3d1ce8c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -156,6 +156,7 @@ extern int register_android_location_GpsLocationProvider(JNIEnv* env); extern int register_android_backup_BackupDataInput(JNIEnv *env); extern int register_android_backup_BackupDataOutput(JNIEnv *env); extern int register_android_backup_FileBackupHelper(JNIEnv *env); +extern int register_android_backup_RestoreHelperBase(JNIEnv *env); static AndroidRuntime* gCurRuntime = NULL; @@ -1172,6 +1173,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_backup_BackupDataInput), REG_JNI(register_android_backup_BackupDataOutput), REG_JNI(register_android_backup_FileBackupHelper), + REG_JNI(register_android_backup_RestoreHelperBase), }; /* diff --git a/core/jni/android_backup_RestoreHelperBase.cpp b/core/jni/android_backup_RestoreHelperBase.cpp new file mode 100644 index 0000000..3173420 --- /dev/null +++ b/core/jni/android_backup_RestoreHelperBase.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#define LOG_TAG "FileBackupHelper_native" +#include <utils/Log.h> + +#include "JNIHelp.h" +#include <android_runtime/AndroidRuntime.h> + +#include <utils/BackupHelpers.h> + +namespace android +{ + +// java.io.FileDescriptor +static jfieldID s_descriptorField = 0; + +static int +ctor(JNIEnv* env, jobject clazz) +{ + return (int)new RestoreHelperBase(); +} + +static void +dtor(JNIEnv* env, jobject clazz, jint ptr) +{ + delete (RestoreHelperBase*)ptr; +} + +static int +writeFile_native(JNIEnv* env, jobject clazz, jint ptr, jstring filenameObj, int backupReaderPtr) +{ + int err; + RestoreHelperBase* restore = (RestoreHelperBase*)ptr; + BackupDataReader* reader = (BackupDataReader*)backupReaderPtr; + char const* filename; + + filename = env->GetStringUTFChars(filenameObj, NULL); + + err = restore->WriteFile(String8(filename), reader); + + env->ReleaseStringUTFChars(filenameObj, filename); + + return err; +} + +static int +writeSnapshot_native(JNIEnv* env, jobject clazz, jint ptr, jobject fileDescriptor) +{ + int err; + + RestoreHelperBase* restore = (RestoreHelperBase*)ptr; + int fd = env->GetIntField(fileDescriptor, s_descriptorField); + + err = restore->WriteSnapshot(fd); + + return err; +} + +static const JNINativeMethod g_methods[] = { + { "ctor", "()I", (void*)ctor }, + { "dtor", "(I)V", (void*)dtor }, + { "writeFile_native", "(ILjava/lang/String;I)I", (void*)writeFile_native }, + { "writeSnapshot_native", "(ILjava/io/FileDescriptor;)I", (void*)writeSnapshot_native }, +}; + +int register_android_backup_RestoreHelperBase(JNIEnv* env) +{ + jclass clazz; + + clazz = env->FindClass("java/io/FileDescriptor"); + LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor"); + s_descriptorField = env->GetFieldID(clazz, "descriptor", "I"); + LOG_FATAL_IF(s_descriptorField == NULL, + "Unable to find descriptor field in java.io.FileDescriptor"); + + return AndroidRuntime::registerNativeMethods(env, "android/backup/RestoreHelperBase", + g_methods, NELEM(g_methods)); +} + +} |