396 lines
17 KiB
Java
396 lines
17 KiB
Java
![]() |
/*
|
||
|
* 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.app.backup;
|
||
|
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.Nullable;
|
||
|
import android.annotation.SystemApi;
|
||
|
import android.content.Context;
|
||
|
import android.os.Handler;
|
||
|
import android.os.Message;
|
||
|
import android.os.RemoteException;
|
||
|
import android.util.Log;
|
||
|
|
||
|
import java.util.Arrays;
|
||
|
import java.util.HashSet;
|
||
|
import java.util.Set;
|
||
|
|
||
|
/**
|
||
|
* Interface for managing a restore session.
|
||
|
* @hide
|
||
|
*/
|
||
|
@SystemApi
|
||
|
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.
|
||
|
*
|
||
|
* @param observer a RestoreObserver object whose restoreSetsAvailable() method will
|
||
|
* be called on the application's main thread in order to supply the results of
|
||
|
* the restore set lookup by the backup transport. This parameter must not be
|
||
|
* null.
|
||
|
* @param monitor a BackupManagerMonitor object will supply data about important events.
|
||
|
* @return Zero on success, nonzero on error. The observer's restoreSetsAvailable()
|
||
|
* method will only be called if this method returned zero.
|
||
|
*/
|
||
|
public int getAvailableRestoreSets(RestoreObserver observer, BackupManagerMonitor monitor) {
|
||
|
int err = -1;
|
||
|
RestoreObserverWrapper obsWrapper = new RestoreObserverWrapper(mContext, observer);
|
||
|
BackupManagerMonitorWrapper monitorWrapper = monitor == null
|
||
|
? null
|
||
|
: new BackupManagerMonitorWrapper(monitor);
|
||
|
try {
|
||
|
err = mBinder.getAvailableRestoreSets(obsWrapper, monitorWrapper);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.d(TAG, "Can't contact server to get available sets");
|
||
|
}
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Ask the current transport what the available restore sets are.
|
||
|
*
|
||
|
* @param observer a RestoreObserver object whose restoreSetsAvailable() method will
|
||
|
* be called on the application's main thread in order to supply the results of
|
||
|
* the restore set lookup by the backup transport. This parameter must not be
|
||
|
* null.
|
||
|
* @return Zero on success, nonzero on error. The observer's restoreSetsAvailable()
|
||
|
* method will only be called if this method returned zero.
|
||
|
*/
|
||
|
public int getAvailableRestoreSets(RestoreObserver observer) {
|
||
|
return getAvailableRestoreSets(observer, 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.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param monitor If non-null, this binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
*/
|
||
|
public int restoreAll(long token, RestoreObserver observer, BackupManagerMonitor monitor) {
|
||
|
int err = -1;
|
||
|
if (mObserver != null) {
|
||
|
Log.d(TAG, "restoreAll() called during active restore");
|
||
|
return -1;
|
||
|
}
|
||
|
mObserver = new RestoreObserverWrapper(mContext, observer);
|
||
|
BackupManagerMonitorWrapper monitorWrapper = monitor == null
|
||
|
? null
|
||
|
: new BackupManagerMonitorWrapper(monitor);
|
||
|
try {
|
||
|
err = mBinder.restoreAll(token, mObserver, monitorWrapper);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.d(TAG, "Can't contact server to restore");
|
||
|
}
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
*/
|
||
|
public int restoreAll(long token, RestoreObserver observer) {
|
||
|
return restoreAll(token, observer, null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore select packages from the given set onto the device, replacing the
|
||
|
* current data of any app contained in the set with the data previously
|
||
|
* backed up.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param packages The set of packages for which to attempt a restore. Regardless of
|
||
|
* the contents of the actual back-end dataset named by {@code token}, only
|
||
|
* applications mentioned in this list will have their data restored.
|
||
|
* @param monitor If non-null, this binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation containing detailed information on any
|
||
|
* failures or important decisions made by {@link BackupManager}.
|
||
|
*/
|
||
|
public int restorePackages(long token, @Nullable RestoreObserver observer,
|
||
|
@NonNull Set<String> packages, @Nullable BackupManagerMonitor monitor) {
|
||
|
int err = -1;
|
||
|
if (mObserver != null) {
|
||
|
Log.d(TAG, "restoreAll() called during active restore");
|
||
|
return -1;
|
||
|
}
|
||
|
mObserver = new RestoreObserverWrapper(mContext, observer);
|
||
|
BackupManagerMonitorWrapper monitorWrapper = monitor == null
|
||
|
? null
|
||
|
: new BackupManagerMonitorWrapper(monitor);
|
||
|
try {
|
||
|
err = mBinder.restorePackages(token, mObserver, packages.toArray(new String[] {}),
|
||
|
monitorWrapper);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.d(TAG, "Can't contact server to restore packages");
|
||
|
}
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore select packages from the given set onto the device, replacing the
|
||
|
* current data of any app contained in the set with the data previously
|
||
|
* backed up.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param packages The set of packages for which to attempt a restore. Regardless of
|
||
|
* the contents of the actual back-end dataset named by {@code token}, only
|
||
|
* applications mentioned in this list will have their data restored.
|
||
|
*/
|
||
|
public int restorePackages(long token, @Nullable RestoreObserver observer,
|
||
|
@NonNull Set<String> packages) {
|
||
|
return restorePackages(token, observer, packages, null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore select packages from the given set onto the device, replacing the
|
||
|
* current data of any app contained in the set with the data previously
|
||
|
* backed up.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param monitor If non-null, this binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param packages The set of packages for which to attempt a restore. Regardless of
|
||
|
* the contents of the actual back-end dataset named by {@code token}, only
|
||
|
* applications mentioned in this list will have their data restored.
|
||
|
*
|
||
|
* @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver,
|
||
|
* BackupManagerMonitor, Set)} instead.
|
||
|
* @removed
|
||
|
*/
|
||
|
@Deprecated
|
||
|
public int restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor,
|
||
|
String[] packages) {
|
||
|
return restorePackages(token, observer, new HashSet<>(Arrays.asList(packages)), monitor);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore select packages from the given set onto the device, replacing the
|
||
|
* current data of any app contained in the set with the data previously
|
||
|
* backed up.
|
||
|
*
|
||
|
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
|
||
|
*
|
||
|
* @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 binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
* @param packages The set of packages for which to attempt a restore. Regardless of
|
||
|
* the contents of the actual back-end dataset named by {@code token}, only
|
||
|
* applications mentioned in this list will have their data restored.
|
||
|
*
|
||
|
* @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver, Set)}
|
||
|
* instead.
|
||
|
* @removed
|
||
|
*/
|
||
|
@Deprecated
|
||
|
public int restoreSome(long token, RestoreObserver observer, String[] packages) {
|
||
|
return restoreSome(token, observer, null, packages);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore a single application from backup. The data will be restored from the
|
||
|
* current backup dataset if the given package has stored data there, or from
|
||
|
* the dataset used during the last full device setup operation if the current
|
||
|
* backup dataset has no matching data. If no backup data exists for this package
|
||
|
* in either source, a nonzero value will be returned.
|
||
|
*
|
||
|
* <p class="caution">Note: Unlike other restore operations, this method doesn't terminate the
|
||
|
* application after the restore. The application continues running to receive the
|
||
|
* {@link RestoreObserver} callbacks on the {@code observer} argument.
|
||
|
*
|
||
|
* @return Zero on success; nonzero on error. The observer will only receive
|
||
|
* progress callbacks if this method returned zero.
|
||
|
* @param packageName The name of the package whose data to restore. If this is
|
||
|
* not the name of the caller's own package, then the android.permission.BACKUP
|
||
|
* permission must be held.
|
||
|
* @param observer If non-null, this binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
*
|
||
|
* @param monitor If non-null, this binder points to an object that will receive
|
||
|
* event callbacks during the restore operation.
|
||
|
*/
|
||
|
public int restorePackage(String packageName, RestoreObserver observer,
|
||
|
BackupManagerMonitor monitor) {
|
||
|
int err = -1;
|
||
|
if (mObserver != null) {
|
||
|
Log.d(TAG, "restorePackage() called during active restore");
|
||
|
return -1;
|
||
|
}
|
||
|
mObserver = new RestoreObserverWrapper(mContext, observer);
|
||
|
BackupManagerMonitorWrapper monitorWrapper = monitor == null
|
||
|
? null
|
||
|
: new BackupManagerMonitorWrapper(monitor);
|
||
|
try {
|
||
|
err = mBinder.restorePackage(packageName, mObserver, monitorWrapper);
|
||
|
} catch (RemoteException e) {
|
||
|
Log.d(TAG, "Can't contact server to restore package");
|
||
|
}
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Restore a single application from backup. The data will be restored from the
|
||
|
* current backup dataset if the given package has stored data there, or from
|
||
|
* the dataset used during the last full device setup operation if the current
|
||
|
* backup dataset has no matching data. If no backup data exists for this package
|
||
|
* in either source, a nonzero value will be returned.
|
||
|
*
|
||
|
* @return Zero on success; nonzero on error. The observer will only receive
|
||
|
* progress callbacks if this method returned zero.
|
||
|
* @param packageName The name of the package whose data to restore. If this is
|
||
|
* not the name of the caller's own package, then the android.permission.BACKUP
|
||
|
* permission must be held.
|
||
|
* @param observer If non-null, this binder points to an object that will receive
|
||
|
* progress callbacks during the restore operation.
|
||
|
*/
|
||
|
public int restorePackage(String packageName, RestoreObserver observer) {
|
||
|
return restorePackage(packageName, observer, null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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 #restorePackage(String, 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 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;
|
||
|
|
||
|
static final int MSG_RESTORE_STARTING = 1;
|
||
|
static final int MSG_UPDATE = 2;
|
||
|
static final int MSG_RESTORE_FINISHED = 3;
|
||
|
static final int MSG_RESTORE_SETS_AVAILABLE = 4;
|
||
|
|
||
|
RestoreObserverWrapper(Context context, RestoreObserver appObserver) {
|
||
|
mHandler = new Handler(context.getMainLooper()) {
|
||
|
@Override
|
||
|
public void handleMessage(Message msg) {
|
||
|
switch (msg.what) {
|
||
|
case MSG_RESTORE_STARTING:
|
||
|
mAppObserver.restoreStarting(msg.arg1);
|
||
|
break;
|
||
|
case MSG_UPDATE:
|
||
|
mAppObserver.onUpdate(msg.arg1, (String)msg.obj);
|
||
|
break;
|
||
|
case MSG_RESTORE_FINISHED:
|
||
|
mAppObserver.restoreFinished(msg.arg1);
|
||
|
break;
|
||
|
case MSG_RESTORE_SETS_AVAILABLE:
|
||
|
mAppObserver.restoreSetsAvailable((RestoreSet[])msg.obj);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
mAppObserver = appObserver;
|
||
|
}
|
||
|
|
||
|
// Binder calls into this object just enqueue on the main-thread handler
|
||
|
public void restoreSetsAvailable(RestoreSet[] result) {
|
||
|
mHandler.sendMessage(
|
||
|
mHandler.obtainMessage(MSG_RESTORE_SETS_AVAILABLE, result));
|
||
|
}
|
||
|
|
||
|
public void restoreStarting(int numPackages) {
|
||
|
mHandler.sendMessage(
|
||
|
mHandler.obtainMessage(MSG_RESTORE_STARTING, numPackages, 0));
|
||
|
}
|
||
|
|
||
|
public void onUpdate(int nowBeingRestored, String currentPackage) {
|
||
|
mHandler.sendMessage(
|
||
|
mHandler.obtainMessage(MSG_UPDATE, nowBeingRestored, 0, currentPackage));
|
||
|
}
|
||
|
|
||
|
public void restoreFinished(int error) {
|
||
|
mHandler.sendMessage(
|
||
|
mHandler.obtainMessage(MSG_RESTORE_FINISHED, error, 0));
|
||
|
}
|
||
|
}
|
||
|
}
|