diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-05-08 07:21:43 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-05-08 07:21:43 -0700 |
commit | 1a36071092c209ac763fdb48dcfe87043a2b2cf6 (patch) | |
tree | 9d053660a58b8f8119d6b0378a22728e1a3869f0 | |
parent | aec09d7ea9eaa842b606d26f8eda3cbd8537e0b3 (diff) | |
parent | 7ec32cc7c33240c50cca31d2fa1b17f6dc2ccead (diff) | |
download | frameworks_base-1a36071092c209ac763fdb48dcfe87043a2b2cf6.zip frameworks_base-1a36071092c209ac763fdb48dcfe87043a2b2cf6.tar.gz frameworks_base-1a36071092c209ac763fdb48dcfe87043a2b2cf6.tar.bz2 |
manual merge of 7ec32cc
Merge commit '7ec32cc'
-rw-r--r-- | api/current.xml | 178 | ||||
-rw-r--r-- | core/java/android/backup/BackupDataOutput.java | 44 | ||||
-rw-r--r-- | core/java/android/backup/FileBackupHelper.java | 68 | ||||
-rw-r--r-- | core/java/android/backup/SharedPreferencesBackupHelper.java | 40 | ||||
-rw-r--r-- | core/jni/Android.mk | 3 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_backup_FileBackupHelper.cpp | 79 | ||||
-rw-r--r-- | core/jni/android_os_ParcelFileDescriptor.cpp | 31 | ||||
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 28 | ||||
-rw-r--r-- | tests/backup/Android.mk | 4 | ||||
-rw-r--r-- | tests/backup/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | tests/backup/src/com/android/backuptest/BackupTestActivity.java | 44 |
12 files changed, 502 insertions, 21 deletions
diff --git a/api/current.xml b/api/current.xml index 4086836..5eb098d 100644 --- a/api/current.xml +++ b/api/current.xml @@ -23815,6 +23815,184 @@ </field> </class> </package> +<package name="android.backup" +> +<class name="BackupDataOutput" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="BackupDataOutput" + type="android.backup.BackupDataOutput" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="context" type="android.content.Context"> +</parameter> +<parameter name="fd" type="java.io.FileDescriptor"> +</parameter> +</constructor> +<method name="close" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="flush" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="write" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="buffer" type="byte[]"> +</parameter> +</method> +<method name="write" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="oneByte" type="int"> +</parameter> +</method> +<method name="write" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="buffer" type="byte[]"> +</parameter> +<parameter name="offset" type="int"> +</parameter> +<parameter name="count" type="int"> +</parameter> +</method> +<method name="writeKey" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="key" type="java.lang.String"> +</parameter> +</method> +</class> +<class name="FileBackupHelper" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="FileBackupHelper" + type="android.backup.FileBackupHelper" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="performBackup" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="context" type="android.content.Context"> +</parameter> +<parameter name="oldSnapshot" type="android.os.ParcelFileDescriptor"> +</parameter> +<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor"> +</parameter> +<parameter name="data" type="android.backup.BackupDataOutput"> +</parameter> +<parameter name="files" type="java.lang.String[]"> +</parameter> +</method> +</class> +<class name="SharedPreferencesBackupHelper" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="SharedPreferencesBackupHelper" + type="android.backup.SharedPreferencesBackupHelper" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="performBackup" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="context" type="android.content.Context"> +</parameter> +<parameter name="oldSnapshot" type="android.os.ParcelFileDescriptor"> +</parameter> +<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor"> +</parameter> +<parameter name="data" type="android.backup.BackupDataOutput"> +</parameter> +<parameter name="prefGroups" type="java.lang.String[]"> +</parameter> +</method> +</class> +</package> <package name="android.content" > <class name="ActivityNotFoundException" diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java new file mode 100644 index 0000000..6c47f7e --- /dev/null +++ b/core/java/android/backup/BackupDataOutput.java @@ -0,0 +1,44 @@ +/* + * 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 java.io.FileDescriptor; + +public class BackupDataOutput { + /* package */ FileDescriptor fd; + + public static final int OP_UPDATE = 1; + public static final int OP_DELETE = 2; + + public BackupDataOutput(Context context, FileDescriptor fd) { + this.fd = fd; + } + + public void close() { + // do we close the fd? + } + public native void flush(); + public native void write(byte[] buffer); + public native void write(int oneByte); + public native void write(byte[] buffer, int offset, int count); + + public native void writeOperation(int op); + public native void writeKey(String key); +} + diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java new file mode 100644 index 0000000..3b2122c --- /dev/null +++ b/core/java/android/backup/FileBackupHelper.java @@ -0,0 +1,68 @@ +/* + * 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.os.ParcelFileDescriptor; + +import java.io.FileDescriptor; + +public class FileBackupHelper { + /** + * Based on oldSnapshot, determine which of the files from the application's data directory + * need to be backed up, write them to the data stream, and fill in newSnapshot with the + * state as it exists now. + */ + public static void performBackup(Context context, + ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot, + BackupDataOutput data, String[] files) { + String basePath = context.getFilesDir().getAbsolutePath(); + performBackup_checked(basePath, oldSnapshot, newSnapshot, data, 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 oldSnapshot, ParcelFileDescriptor newSnapshot, + BackupDataOutput data, String[] files) { + if (newSnapshot == null) { + throw new NullPointerException("newSnapshot==null"); + } + if (data == null) { + throw new NullPointerException("data==null"); + } + if (data.fd == null) { + throw new NullPointerException("data.fd==null"); + } + if (files == null) { + throw new NullPointerException("files==null"); + } + + int err = performBackup_native(basePath, oldSnapshot.getFileDescriptor(), + newSnapshot.getFileDescriptor(), data.fd, files); + + if (err != 0) { + throw new RuntimeException("Backup failed"); // TODO: more here + } + } + + native private static int performBackup_native(String basePath, + FileDescriptor oldSnapshot, FileDescriptor newSnapshot, + FileDescriptor data, String[] files); +} diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java new file mode 100644 index 0000000..e839bb4 --- /dev/null +++ b/core/java/android/backup/SharedPreferencesBackupHelper.java @@ -0,0 +1,40 @@ +/* + * 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.os.ParcelFileDescriptor; + +import java.io.FileDescriptor; + +public class SharedPreferencesBackupHelper { + 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"; + } + + FileBackupHelper.performBackup_checked(basePath, oldSnapshot, newSnapshot, data, files); + } +} + diff --git a/core/jni/Android.mk b/core/jni/Android.mk index de64e84..5ef678e 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -115,7 +115,8 @@ LOCAL_SRC_FILES:= \ android_ddm_DdmHandleNativeHeap.cpp \ android_location_GpsLocationProvider.cpp \ com_android_internal_os_ZygoteInit.cpp \ - com_android_internal_graphics_NativeUtils.cpp + com_android_internal_graphics_NativeUtils.cpp \ + android_backup_FileBackupHelper.cpp LOCAL_C_INCLUDES += \ $(JNI_H_INCLUDE) \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 422020e..d1e87f3 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -154,6 +154,7 @@ extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env); extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env); extern int register_android_util_Base64(JNIEnv* env); extern int register_android_location_GpsLocationProvider(JNIEnv* env); +extern int register_android_backup_FileBackupHelper(JNIEnv *env); static AndroidRuntime* gCurRuntime = NULL; @@ -1168,6 +1169,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_ddm_DdmHandleNativeHeap), REG_JNI(register_android_util_Base64), REG_JNI(register_android_location_GpsLocationProvider), + REG_JNI(register_android_backup_FileBackupHelper), }; /* diff --git a/core/jni/android_backup_FileBackupHelper.cpp b/core/jni/android_backup_FileBackupHelper.cpp new file mode 100644 index 0000000..e8d60a0 --- /dev/null +++ b/core/jni/android_backup_FileBackupHelper.cpp @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#include "JNIHelp.h" +#include <android_runtime/AndroidRuntime.h> + +#include <utils/backup_helpers.h> + +namespace android +{ + +static jfieldID s_descriptorField; + +static int +performBackup_native(JNIEnv* env, jstring basePath, + jobject oldSnapshot, jobject newSnapshot, + jobject data, jobjectArray files) +{ + int err; + + // all parameters have already been checked against null + + int oldSnapshotFD = env->GetIntField(oldSnapshot, s_descriptorField); + int newSnapshotFD = env->GetIntField(newSnapshot, s_descriptorField); + int dataFD = env->GetIntField(data, s_descriptorField); + + char const* basePathUTF = env->GetStringUTFChars(basePath, NULL); + 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(oldSnapshotFD, newSnapshotFD, dataFD, basePathUTF, filesUTF, fileCount); + + for (int i=0; i<fileCount; i++) { + env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(files, i), filesUTF[i]); + } + free(filesUTF); + env->ReleaseStringUTFChars(basePath, basePathUTF); + + return err; +} + +static const JNINativeMethod g_methods[] = { + { "performBackup_native", + "(Ljava/lang/String;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;" + "Ljava/io/FileDescriptor;[Ljava/lang/String;)I", + (void*)performBackup_native }, +}; + +int register_android_backup_FileBackupHelper(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/FileBackupHelper", + g_methods, NELEM(g_methods)); +} + +} diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp index 971f87c..848a57a 100644 --- a/core/jni/android_os_ParcelFileDescriptor.cpp +++ b/core/jni/android_os_ParcelFileDescriptor.cpp @@ -1,19 +1,18 @@ -/* //device/libs/android_runtime/android_os_ParcelFileDescriptor.cpp -** -** Copyright 2008, 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. -*/ +/* + * Copyright (C) 2008 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_NDEBUG 0 diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 63fc871..e582fb1 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -42,7 +42,9 @@ import android.util.SparseArray; import android.backup.IBackupManager; import java.io.File; +import java.io.FileDescriptor; import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.lang.String; import java.util.HashSet; import java.util.List; @@ -51,7 +53,8 @@ class BackupManagerService extends IBackupManager.Stub { private static final String TAG = "BackupManagerService"; private static final boolean DEBUG = true; - private static final long COLLECTION_INTERVAL = 3 * 60 * 1000; + private static final long COLLECTION_INTERVAL = 1000; + //private static final long COLLECTION_INTERVAL = 3 * 60 * 1000; private static final int MSG_RUN_BACKUP = 1; @@ -338,8 +341,11 @@ class BackupManagerService extends IBackupManager.Stub { // Record that we need a backup pass for the caller. Since multiple callers // may share a uid, we need to note all candidates within that uid and schedule // a backup pass for each of them. + + Log.d(TAG, "dataChanged packageName=" + packageName); HashSet<ServiceInfo> targets = mBackupParticipants.get(Binder.getCallingUid()); + Log.d(TAG, "targets=" + targets); if (targets != null) { synchronized (mQueueLock) { // Note that this client has made data changes that need to be backed up @@ -354,6 +360,7 @@ class BackupManagerService extends IBackupManager.Stub { } } + Log.d(TAG, "Scheduling backup for " + mPendingBackups.size() + " participants"); // Schedule a backup pass in a few minutes. As backup-eligible data // keeps changing, continue to defer the backup pass until things // settle down, to avoid extra overhead. @@ -380,4 +387,23 @@ class BackupManagerService extends IBackupManager.Stub { } } } + + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + synchronized (mQueueLock) { + int N = mBackupParticipants.size(); + pw.println("Participants:"); + for (int i=0; i<N; i++) { + int uid = mBackupParticipants.keyAt(i); + pw.print(" uid: "); + pw.println(uid); + HashSet<ServiceInfo> services = mBackupParticipants.valueAt(i); + for (ServiceInfo s: services) { + pw.print(" "); + pw.println(s.toString()); + } + } + } + } } diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk index 35c05df..2e3385f 100644 --- a/tests/backup/Android.mk +++ b/tests/backup/Android.mk @@ -21,7 +21,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ backup_helper_test.cpp -LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_TAGS := user LOCAL_MODULE := backup_helper_test LOCAL_SHARED_LIBRARIES := libutils @@ -31,7 +31,7 @@ include $(BUILD_EXECUTABLE) # ======================================== include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := user LOCAL_SRC_FILES := $(call all-subdir-java-files) diff --git a/tests/backup/AndroidManifest.xml b/tests/backup/AndroidManifest.xml index c26078b..eaeb5b7 100644 --- a/tests/backup/AndroidManifest.xml +++ b/tests/backup/AndroidManifest.xml @@ -10,7 +10,7 @@ </activity> <service android:name="BackupTestService"> <intent-filter> - <action android:name="android.backup.BackupService" /> + <action android:name="android.backup.BackupService.SERVICE" /> </intent-filter> </service> </application> diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java index 31aec39..de68cb7 100644 --- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java +++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java @@ -31,14 +31,58 @@ import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintStream; +import java.text.DateFormat; +import java.util.Date; + public class BackupTestActivity extends ListActivity { static final String TAG = "BackupTestActivity"; static final String PREF_GROUP_SETTINGS = "settings"; static final String PREF_KEY = "pref"; + static final String FILE_NAME = "file.txt"; Test[] mTests = new Test[] { + new Test("Show File") { + void run() { + StringBuffer str = new StringBuffer(); + str.append("Text is:"); + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(openFileInput(FILE_NAME))); + while (reader.ready()) { + str.append("\n"); + str.append(reader.readLine()); + } + } catch (IOException ex) { + str.append("ERROR: "); + str.append(ex.toString()); + } + Log.d(TAG, str.toString()); + Toast.makeText(BackupTestActivity.this, str, Toast.LENGTH_SHORT).show(); + } + }, + new Test("Append to File") { + void run() { + PrintStream output = null; + try { + output = new PrintStream(openFileOutput(FILE_NAME, MODE_APPEND)); + DateFormat formatter = DateFormat.getDateTimeInstance(); + output.println(formatter.format(new Date())); + output.close(); + } catch (IOException ex) { + if (output != null) { + output.close(); + } + } + BackupManager bm = new BackupManager(BackupTestActivity.this); + bm.dataChanged(); + } + }, new Test("Show Shared Pref") { void run() { SharedPreferences prefs = getSharedPreferences(PREF_GROUP_SETTINGS, MODE_PRIVATE); |