Merge branch 'donut' of ssh://android-git.corp.google.com:29418/platform/frameworks/base into donut

This commit is contained in:
The Android Open Source Project
2009-05-07 16:45:46 -07:00
12 changed files with 502 additions and 21 deletions

View File

@@ -21795,6 +21795,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"

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -116,7 +116,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) \

View File

@@ -155,6 +155,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;
@@ -1125,6 +1126,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),
};
/*

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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());
}
}
}
}
}

View File

@@ -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)

View File

@@ -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>

View File

@@ -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);