Merge "Move towards a formal public API for backup and restore"
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.backup;
|
||||
|
||||
import android.backup.RestoreSession;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -115,19 +116,21 @@ public class BackupManager {
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public IRestoreSession beginRestoreSession(String transport) {
|
||||
public RestoreSession beginRestoreSession() {
|
||||
if (!EVEN_THINK_ABOUT_DOING_RESTORE) {
|
||||
return null;
|
||||
}
|
||||
IRestoreSession binder = null;
|
||||
RestoreSession session = null;
|
||||
checkServiceBinder();
|
||||
if (sService != null) {
|
||||
try {
|
||||
binder = sService.beginRestoreSession(transport);
|
||||
String transport = sService.getCurrentTransport();
|
||||
IRestoreSession binder = sService.beginRestoreSession(transport);
|
||||
session = new RestoreSession(mContext, binder);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "beginRestoreSession() couldn't connect");
|
||||
}
|
||||
}
|
||||
return binder;
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
53
core/java/android/backup/RestoreObserver.java
Normal file
53
core/java/android/backup/RestoreObserver.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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;
|
||||
|
||||
/**
|
||||
* Callback class for receiving progress reports during a restore operation. These
|
||||
* methods will all be called on your application's main thread.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class RestoreObserver {
|
||||
/**
|
||||
* The restore operation has begun.
|
||||
*
|
||||
* @param numPackages The total number of packages being processed in
|
||||
* this restore operation.
|
||||
*/
|
||||
void restoreStarting(int numPackages) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An indication of which package is being restored currently, out of the
|
||||
* total number provided in the restoreStarting() callback. This method
|
||||
* is not guaranteed to be called.
|
||||
*
|
||||
* @param nowBeingRestored The index, between 1 and the numPackages parameter
|
||||
* to the restoreStarting() callback, of the package now being restored.
|
||||
*/
|
||||
void onUpdate(int nowBeingRestored) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The restore operation has completed.
|
||||
*
|
||||
* @param error Zero on success; a nonzero error code if the restore operation
|
||||
* as a whole failed.
|
||||
*/
|
||||
void restoreFinished(int error) {
|
||||
}
|
||||
}
|
||||
178
core/java/android/backup/RestoreSession.java
Normal file
178
core/java/android/backup/RestoreSession.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.backup.IRestoreSession;
|
||||
import android.backup.RestoreObserver;
|
||||
import android.backup.RestoreSet;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Interface for applications to use when managing a restore session.
|
||||
* @hide
|
||||
*/
|
||||
public class RestoreSession {
|
||||
static final String TAG = "RestoreSession";
|
||||
|
||||
final Context mContext;
|
||||
IRestoreSession mBinder;
|
||||
RestoreObserverWrapper mObserver = null;
|
||||
|
||||
/**
|
||||
* Ask the current transport what the available restore sets are.
|
||||
*
|
||||
* @return A bundle containing two elements: an int array under the key
|
||||
* "tokens" whose entries are a transport-private identifier for each backup set;
|
||||
* and a String array under the key "names" whose entries are the user-meaningful
|
||||
* text corresponding to the backup sets at each index in the tokens array.
|
||||
* On error, returns null.
|
||||
*/
|
||||
public RestoreSet[] getAvailableRestoreSets() {
|
||||
try {
|
||||
return mBinder.getAvailableRestoreSets();
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Can't contact server to get available sets");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the given set onto the device, replacing the current data of any app
|
||||
* contained in the restore set with the data previously backed up.
|
||||
*
|
||||
* @return Zero on success; nonzero on error. The observer will only receive
|
||||
* progress callbacks if this method returned zero.
|
||||
* @param token The token from {@link #getAvailableRestoreSets()} corresponding to
|
||||
* the restore set that should be used.
|
||||
* @param observer If non-null, this argument points to an object that will receive
|
||||
* progress callbacks during the restore operation. These callbacks will occur
|
||||
* on the main thread of the application.
|
||||
*/
|
||||
public int performRestore(long token, RestoreObserver observer) {
|
||||
int err = -1;
|
||||
if (mObserver != null) {
|
||||
Log.d(TAG, "performRestore() called during active restore");
|
||||
return -1;
|
||||
}
|
||||
mObserver = new RestoreObserverWrapper(mContext, observer);
|
||||
try {
|
||||
err = mBinder.performRestore(token, mObserver);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Can't contact server to perform restore");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* End this restore session. After this method is called, the RestoreSession
|
||||
* object is no longer valid.
|
||||
*
|
||||
* <p><b>Note:</b> The caller <i>must</i> invoke this method to end the restore session,
|
||||
* even if {@link #getAvailableRestoreSets()} or
|
||||
* {@link #performRestore(long, RestoreObserver)} failed.
|
||||
*/
|
||||
public void endRestoreSession() {
|
||||
try {
|
||||
mBinder.endRestoreSession();
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Can't contact server to get available sets");
|
||||
} finally {
|
||||
mBinder = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Nonpublic implementation here
|
||||
*/
|
||||
|
||||
RestoreSession(Context context, IRestoreSession binder) {
|
||||
mContext = context;
|
||||
mBinder = binder;
|
||||
}
|
||||
|
||||
/*
|
||||
* We wrap incoming binder calls with a private class implementation that
|
||||
* redirects them into main-thread actions. This accomplishes two things:
|
||||
* first, it ensures that the app's code is run on their own main thread,
|
||||
* never with system Binder identity; and second, it serializes the restore
|
||||
* progress callbacks nicely within the usual main-thread lifecycle pattern.
|
||||
*/
|
||||
private class RestoreObserverWrapper extends IRestoreObserver.Stub {
|
||||
final Handler mHandler;
|
||||
final RestoreObserver mAppObserver;
|
||||
|
||||
RestoreObserverWrapper(Context context, RestoreObserver appObserver) {
|
||||
mHandler = new Handler(context.getMainLooper());
|
||||
mAppObserver = appObserver;
|
||||
}
|
||||
|
||||
// Wrap the IRestoreObserver -> RestoreObserver callthrough in Runnables
|
||||
// posted to the app's main thread looper.
|
||||
class RestoreStartingRunnable implements Runnable {
|
||||
int mNumPackages;
|
||||
|
||||
RestoreStartingRunnable(int numPackages) {
|
||||
mNumPackages = numPackages;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mAppObserver.restoreStarting(mNumPackages);
|
||||
}
|
||||
}
|
||||
|
||||
class OnUpdateRunnable implements Runnable {
|
||||
int mNowRestoring;
|
||||
|
||||
OnUpdateRunnable(int nowRestoring) {
|
||||
mNowRestoring = nowRestoring;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mAppObserver.onUpdate(mNowRestoring);
|
||||
}
|
||||
}
|
||||
|
||||
class RestoreFinishedRunnable implements Runnable {
|
||||
int mError;
|
||||
|
||||
RestoreFinishedRunnable(int error) {
|
||||
mError = error;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mAppObserver.restoreFinished(mError);
|
||||
}
|
||||
}
|
||||
|
||||
// The actual redirection code is quite simple using just the
|
||||
// above Runnable subclasses
|
||||
public void restoreStarting(int numPackages) {
|
||||
mHandler.post(new RestoreStartingRunnable(numPackages));
|
||||
}
|
||||
|
||||
public void onUpdate(int nowBeingRestored) {
|
||||
mHandler.post(new OnUpdateRunnable(nowBeingRestored));
|
||||
}
|
||||
|
||||
public void restoreFinished(int error) {
|
||||
mHandler.post(new RestoreFinishedRunnable(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
= new HashMap<String,IBackupTransport>();
|
||||
String mCurrentTransport;
|
||||
IBackupTransport mLocalTransport, mGoogleTransport;
|
||||
RestoreSession mActiveRestoreSession;
|
||||
ActiveRestoreSession mActiveRestoreSession;
|
||||
|
||||
class RestoreParams {
|
||||
public IBackupTransport transport;
|
||||
@@ -2068,20 +2068,20 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
Log.d(TAG, "Restore session requested but one already active");
|
||||
return null;
|
||||
}
|
||||
mActiveRestoreSession = new RestoreSession(transport);
|
||||
mActiveRestoreSession = new ActiveRestoreSession(transport);
|
||||
}
|
||||
return mActiveRestoreSession;
|
||||
}
|
||||
|
||||
// ----- Restore session -----
|
||||
|
||||
class RestoreSession extends IRestoreSession.Stub {
|
||||
class ActiveRestoreSession extends IRestoreSession.Stub {
|
||||
private static final String TAG = "RestoreSession";
|
||||
|
||||
private IBackupTransport mRestoreTransport = null;
|
||||
RestoreSet[] mRestoreSets = null;
|
||||
|
||||
RestoreSession(String transport) {
|
||||
ActiveRestoreSession(String transport) {
|
||||
mRestoreTransport = getTransport(transport);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user