Merge "Harden against transiently unavailable backup transports" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d6bbc54423
@ -187,6 +187,12 @@ public final class Bmgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doWipe() {
|
private void doWipe() {
|
||||||
|
String transport = nextArg();
|
||||||
|
if (transport == null) {
|
||||||
|
showUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String pkg = nextArg();
|
String pkg = nextArg();
|
||||||
if (pkg == null) {
|
if (pkg == null) {
|
||||||
showUsage();
|
showUsage();
|
||||||
@ -194,8 +200,8 @@ public final class Bmgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mBmgr.clearBackupData(pkg);
|
mBmgr.clearBackupData(transport, pkg);
|
||||||
System.out.println("Wiped backup data for " + pkg);
|
System.out.println("Wiped backup data for " + pkg + " on " + transport);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
System.err.println(e.toString());
|
System.err.println(e.toString());
|
||||||
System.err.println(BMGR_NOT_RUNNING_ERR);
|
System.err.println(BMGR_NOT_RUNNING_ERR);
|
||||||
@ -446,7 +452,7 @@ public final class Bmgr {
|
|||||||
System.err.println(" bmgr restore TOKEN PACKAGE...");
|
System.err.println(" bmgr restore TOKEN PACKAGE...");
|
||||||
System.err.println(" bmgr restore PACKAGE");
|
System.err.println(" bmgr restore PACKAGE");
|
||||||
System.err.println(" bmgr run");
|
System.err.println(" bmgr run");
|
||||||
System.err.println(" bmgr wipe PACKAGE");
|
System.err.println(" bmgr wipe TRANSPORT PACKAGE");
|
||||||
System.err.println("");
|
System.err.println("");
|
||||||
System.err.println("The 'backup' command schedules a backup pass for the named package.");
|
System.err.println("The 'backup' command schedules a backup pass for the named package.");
|
||||||
System.err.println("Note that the backup pass will effectively be a no-op if the package");
|
System.err.println("Note that the backup pass will effectively be a no-op if the package");
|
||||||
@ -462,8 +468,8 @@ public final class Bmgr {
|
|||||||
System.err.println("");
|
System.err.println("");
|
||||||
System.err.println("The 'list transports' command reports the names of the backup transports");
|
System.err.println("The 'list transports' command reports the names of the backup transports");
|
||||||
System.err.println("currently available on the device. These names can be passed as arguments");
|
System.err.println("currently available on the device. These names can be passed as arguments");
|
||||||
System.err.println("to the 'transport' command. The currently selected transport is indicated");
|
System.err.println("to the 'transport' and 'wipe' commands. The currently selected transport");
|
||||||
System.err.println("with a '*' character.");
|
System.err.println("is indicated with a '*' character.");
|
||||||
System.err.println("");
|
System.err.println("");
|
||||||
System.err.println("The 'list sets' command reports the token and name of each restore set");
|
System.err.println("The 'list sets' command reports the token and name of each restore set");
|
||||||
System.err.println("available to the device via the current transport.");
|
System.err.println("available to the device via the current transport.");
|
||||||
@ -491,7 +497,8 @@ public final class Bmgr {
|
|||||||
System.err.println("data changes.");
|
System.err.println("data changes.");
|
||||||
System.err.println("");
|
System.err.println("");
|
||||||
System.err.println("The 'wipe' command causes all backed-up data for the given package to be");
|
System.err.println("The 'wipe' command causes all backed-up data for the given package to be");
|
||||||
System.err.println("erased from the current transport's storage. The next backup operation");
|
System.err.println("erased from the given transport's storage. The next backup operation");
|
||||||
System.err.println("that the given application performs will rewrite its entire data set.");
|
System.err.println("that the given application performs will rewrite its entire data set.");
|
||||||
|
System.err.println("Transport names to use here are those reported by 'list transports'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,14 @@ interface IBackupManager {
|
|||||||
void dataChanged(String packageName);
|
void dataChanged(String packageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erase all backed-up data for the given package from the storage
|
* Erase all backed-up data for the given package from the given storage
|
||||||
* destination.
|
* destination.
|
||||||
*
|
*
|
||||||
* Any application can invoke this method for its own package, but
|
* Any application can invoke this method for its own package, but
|
||||||
* only callers who hold the android.permission.BACKUP permission
|
* only callers who hold the android.permission.BACKUP permission
|
||||||
* may invoke it for arbitrary packages.
|
* may invoke it for arbitrary packages.
|
||||||
*/
|
*/
|
||||||
void clearBackupData(String packageName);
|
void clearBackupData(String transportName, String packageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the Backup Manager Service that an agent has become available. This
|
* Notifies the Backup Manager Service that an agent has become available. This
|
||||||
|
@ -161,6 +161,9 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// the first backup pass.
|
// the first backup pass.
|
||||||
private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
|
private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
|
||||||
|
|
||||||
|
// Retry interval for clear/init when the transport is unavailable
|
||||||
|
private static final long TRANSPORT_RETRY_INTERVAL = 1 * AlarmManager.INTERVAL_HOUR;
|
||||||
|
|
||||||
private static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
|
private static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
|
||||||
private static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
|
private static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
|
||||||
private static final String RUN_CLEAR_ACTION = "android.app.backup.intent.CLEAR";
|
private static final String RUN_CLEAR_ACTION = "android.app.backup.intent.CLEAR";
|
||||||
@ -174,6 +177,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
private static final int MSG_RESTORE_TIMEOUT = 8;
|
private static final int MSG_RESTORE_TIMEOUT = 8;
|
||||||
private static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
|
private static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
|
||||||
private static final int MSG_RUN_FULL_RESTORE = 10;
|
private static final int MSG_RUN_FULL_RESTORE = 10;
|
||||||
|
private static final int MSG_RETRY_INIT = 11;
|
||||||
|
private static final int MSG_RETRY_CLEAR = 12;
|
||||||
|
|
||||||
// backup task state machine tick
|
// backup task state machine tick
|
||||||
static final int MSG_BACKUP_RESTORE_STEP = 20;
|
static final int MSG_BACKUP_RESTORE_STEP = 20;
|
||||||
@ -306,6 +311,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
class RestoreParams {
|
class RestoreParams {
|
||||||
public IBackupTransport transport;
|
public IBackupTransport transport;
|
||||||
|
public String dirName;
|
||||||
public IRestoreObserver observer;
|
public IRestoreObserver observer;
|
||||||
public long token;
|
public long token;
|
||||||
public PackageInfo pkgInfo;
|
public PackageInfo pkgInfo;
|
||||||
@ -313,9 +319,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
public boolean needFullBackup;
|
public boolean needFullBackup;
|
||||||
public String[] filterSet;
|
public String[] filterSet;
|
||||||
|
|
||||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs,
|
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
|
||||||
long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
|
long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
|
||||||
transport = _transport;
|
transport = _transport;
|
||||||
|
dirName = _dirName;
|
||||||
observer = _obs;
|
observer = _obs;
|
||||||
token = _token;
|
token = _token;
|
||||||
pkgInfo = _pkg;
|
pkgInfo = _pkg;
|
||||||
@ -324,9 +331,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
filterSet = null;
|
filterSet = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token,
|
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
|
||||||
boolean _needFullBackup) {
|
long _token, boolean _needFullBackup) {
|
||||||
transport = _transport;
|
transport = _transport;
|
||||||
|
dirName = _dirName;
|
||||||
observer = _obs;
|
observer = _obs;
|
||||||
token = _token;
|
token = _token;
|
||||||
pkgInfo = null;
|
pkgInfo = null;
|
||||||
@ -335,9 +343,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
filterSet = null;
|
filterSet = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token,
|
RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
|
||||||
String[] _filterSet, boolean _needFullBackup) {
|
long _token, String[] _filterSet, boolean _needFullBackup) {
|
||||||
transport = _transport;
|
transport = _transport;
|
||||||
|
dirName = _dirName;
|
||||||
observer = _obs;
|
observer = _obs;
|
||||||
token = _token;
|
token = _token;
|
||||||
pkgInfo = null;
|
pkgInfo = null;
|
||||||
@ -357,6 +366,16 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClearRetryParams {
|
||||||
|
public String transportName;
|
||||||
|
public String packageName;
|
||||||
|
|
||||||
|
ClearRetryParams(String transport, String pkg) {
|
||||||
|
transportName = transport;
|
||||||
|
packageName = pkg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class FullParams {
|
class FullParams {
|
||||||
public ParcelFileDescriptor fd;
|
public ParcelFileDescriptor fd;
|
||||||
public final AtomicBoolean latch;
|
public final AtomicBoolean latch;
|
||||||
@ -516,13 +535,28 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// When it completes successfully, that old journal file will be
|
// When it completes successfully, that old journal file will be
|
||||||
// deleted. If we crash prior to that, the old journal is parsed
|
// deleted. If we crash prior to that, the old journal is parsed
|
||||||
// at next boot and the journaled requests fulfilled.
|
// at next boot and the journaled requests fulfilled.
|
||||||
|
boolean staged = true;
|
||||||
if (queue.size() > 0) {
|
if (queue.size() > 0) {
|
||||||
// Spin up a backup state sequence and set it running
|
// Spin up a backup state sequence and set it running
|
||||||
PerformBackupTask pbt = new PerformBackupTask(transport, queue, oldJournal);
|
try {
|
||||||
|
String dirName = transport.transportDirName();
|
||||||
|
PerformBackupTask pbt = new PerformBackupTask(transport, dirName,
|
||||||
|
queue, oldJournal);
|
||||||
Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
|
Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
|
||||||
sendMessage(pbtMessage);
|
sendMessage(pbtMessage);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// unable to ask the transport its dir name -- transient failure, since
|
||||||
|
// the above check succeeded. Try again next time.
|
||||||
|
Slog.e(TAG, "Transport became unavailable attempting backup");
|
||||||
|
staged = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Slog.v(TAG, "Backup requested but nothing pending");
|
Slog.v(TAG, "Backup requested but nothing pending");
|
||||||
|
staged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!staged) {
|
||||||
|
// if we didn't actually hand off the wakelock, rewind until next time
|
||||||
synchronized (mQueueLock) {
|
synchronized (mQueueLock) {
|
||||||
mBackupRunning = false;
|
mBackupRunning = false;
|
||||||
}
|
}
|
||||||
@ -572,7 +606,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
RestoreParams params = (RestoreParams)msg.obj;
|
RestoreParams params = (RestoreParams)msg.obj;
|
||||||
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
|
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
|
||||||
PerformRestoreTask task = new PerformRestoreTask(
|
PerformRestoreTask task = new PerformRestoreTask(
|
||||||
params.transport, params.observer,
|
params.transport, params.dirName, params.observer,
|
||||||
params.token, params.pkgInfo, params.pmToken,
|
params.token, params.pkgInfo, params.pmToken,
|
||||||
params.needFullBackup, params.filterSet);
|
params.needFullBackup, params.filterSet);
|
||||||
Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
|
Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
|
||||||
@ -599,6 +633,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_RETRY_CLEAR:
|
||||||
|
{
|
||||||
|
// reenqueues if the transport remains unavailable
|
||||||
|
ClearRetryParams params = (ClearRetryParams)msg.obj;
|
||||||
|
clearBackupData(params.transportName, params.packageName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MSG_RUN_INITIALIZE:
|
case MSG_RUN_INITIALIZE:
|
||||||
{
|
{
|
||||||
HashSet<String> queue;
|
HashSet<String> queue;
|
||||||
@ -613,6 +655,16 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_RETRY_INIT:
|
||||||
|
{
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
recordInitPendingLocked(msg.arg1 != 0, (String)msg.obj);
|
||||||
|
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
|
||||||
|
mRunInitIntent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MSG_RUN_GET_RESTORE_SETS:
|
case MSG_RUN_GET_RESTORE_SETS:
|
||||||
{
|
{
|
||||||
// Like other async operations, this is entered with the wakelock held
|
// Like other async operations, this is entered with the wakelock held
|
||||||
@ -1250,8 +1302,11 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
void recordInitPendingLocked(boolean isPending, String transportName) {
|
void recordInitPendingLocked(boolean isPending, String transportName) {
|
||||||
if (DEBUG) Slog.i(TAG, "recordInitPendingLocked: " + isPending
|
if (DEBUG) Slog.i(TAG, "recordInitPendingLocked: " + isPending
|
||||||
+ " on transport " + transportName);
|
+ " on transport " + transportName);
|
||||||
|
mBackupHandler.removeMessages(MSG_RETRY_INIT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IBackupTransport transport = getTransport(transportName);
|
IBackupTransport transport = getTransport(transportName);
|
||||||
|
if (transport != null) {
|
||||||
String transportDirName = transport.transportDirName();
|
String transportDirName = transport.transportDirName();
|
||||||
File stateDir = new File(mBaseStateDir, transportDirName);
|
File stateDir = new File(mBaseStateDir, transportDirName);
|
||||||
File initPendingFile = new File(stateDir, INIT_SENTINEL_FILE_NAME);
|
File initPendingFile = new File(stateDir, INIT_SENTINEL_FILE_NAME);
|
||||||
@ -1271,8 +1326,23 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
initPendingFile.delete();
|
initPendingFile.delete();
|
||||||
mPendingInits.remove(transportName);
|
mPendingInits.remove(transportName);
|
||||||
}
|
}
|
||||||
|
return; // done; don't fall through to the error case
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// can't happen; the transport is local
|
// transport threw when asked its name; fall through to the lookup-failed case
|
||||||
|
}
|
||||||
|
|
||||||
|
// The named transport doesn't exist or threw. This operation is
|
||||||
|
// important, so we record the need for a an init and post a message
|
||||||
|
// to retry the init later.
|
||||||
|
if (isPending) {
|
||||||
|
mPendingInits.add(transportName);
|
||||||
|
mBackupHandler.sendMessageDelayed(
|
||||||
|
mBackupHandler.obtainMessage(MSG_RETRY_INIT,
|
||||||
|
(isPending ? 1 : 0),
|
||||||
|
0,
|
||||||
|
transportName),
|
||||||
|
TRANSPORT_RETRY_INTERVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1348,7 +1418,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// can't happen, the transport is local
|
// the transport threw when asked its file naming prefs; declare it invalid
|
||||||
|
Slog.e(TAG, "Unable to register transport as " + name);
|
||||||
|
mTransportNames.remove(component);
|
||||||
|
mTransports.remove(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1668,7 +1741,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
agent = mConnectedAgent;
|
agent = mConnectedAgent;
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// can't happen
|
// can't happen - ActivityManager is local
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return agent;
|
return agent;
|
||||||
@ -1844,17 +1917,13 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
int mStatus;
|
int mStatus;
|
||||||
boolean mFinished;
|
boolean mFinished;
|
||||||
|
|
||||||
public PerformBackupTask(IBackupTransport transport, ArrayList<BackupRequest> queue,
|
public PerformBackupTask(IBackupTransport transport, String dirName,
|
||||||
File journal) {
|
ArrayList<BackupRequest> queue, File journal) {
|
||||||
mTransport = transport;
|
mTransport = transport;
|
||||||
mOriginalQueue = queue;
|
mOriginalQueue = queue;
|
||||||
mJournal = journal;
|
mJournal = journal;
|
||||||
|
|
||||||
try {
|
mStateDir = new File(mBaseStateDir, dirName);
|
||||||
mStateDir = new File(mBaseStateDir, transport.transportDirName());
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
// can't happen; the transport is local
|
|
||||||
}
|
|
||||||
|
|
||||||
mCurrentState = BackupState.INITIAL;
|
mCurrentState = BackupState.INITIAL;
|
||||||
mFinished = false;
|
mFinished = false;
|
||||||
@ -2100,8 +2169,12 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
addBackupTrace("success; recording token");
|
addBackupTrace("success; recording token");
|
||||||
try {
|
try {
|
||||||
mCurrentToken = mTransport.getCurrentRestoreSet();
|
mCurrentToken = mTransport.getCurrentRestoreSet();
|
||||||
} catch (RemoteException e) {} // can't happen
|
|
||||||
writeRestoreTokens();
|
writeRestoreTokens();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// nothing for it at this point, unfortunately, but this will be
|
||||||
|
// recorded the next time we fully succeed.
|
||||||
|
addBackupTrace("transport threw returning token");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the next backup pass - at this point we can set mBackupRunning
|
// Set up the next backup pass - at this point we can set mBackupRunning
|
||||||
@ -2322,7 +2395,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
addBackupTrace("unbinding " + mCurrentPackage.packageName);
|
addBackupTrace("unbinding " + mCurrentPackage.packageName);
|
||||||
try { // unbind even on timeout, just in case
|
try { // unbind even on timeout, just in case
|
||||||
mActivityManager.unbindBackupAgent(mCurrentPackage.applicationInfo);
|
mActivityManager.unbindBackupAgent(mCurrentPackage.applicationInfo);
|
||||||
} catch (RemoteException e) {}
|
} catch (RemoteException e) { /* can't happen; activity manager is local */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4337,7 +4410,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer,
|
PerformRestoreTask(IBackupTransport transport, String dirName, IRestoreObserver observer,
|
||||||
long restoreSetToken, PackageInfo targetPackage, int pmToken,
|
long restoreSetToken, PackageInfo targetPackage, int pmToken,
|
||||||
boolean needFullBackup, String[] filterSet) {
|
boolean needFullBackup, String[] filterSet) {
|
||||||
mCurrentState = RestoreState.INITIAL;
|
mCurrentState = RestoreState.INITIAL;
|
||||||
@ -4360,11 +4433,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
mFilterSet = null;
|
mFilterSet = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
mStateDir = new File(mBaseStateDir, dirName);
|
||||||
mStateDir = new File(mBaseStateDir, transport.transportDirName());
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
// can't happen; the transport is local
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute one tick of whatever state machine the task implements
|
// Execute one tick of whatever state machine the task implements
|
||||||
@ -5090,8 +5159,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear the given package's backup data from the current transport
|
// Clear the given package's backup data from the current transport
|
||||||
public void clearBackupData(String packageName) {
|
public void clearBackupData(String transportName, String packageName) {
|
||||||
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName);
|
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
|
||||||
PackageInfo info;
|
PackageInfo info;
|
||||||
try {
|
try {
|
||||||
info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||||
@ -5122,13 +5191,22 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
// Is the given app an available participant?
|
// Is the given app an available participant?
|
||||||
if (apps.contains(packageName)) {
|
if (apps.contains(packageName)) {
|
||||||
if (DEBUG) Slog.v(TAG, "Found the app - running clear process");
|
|
||||||
// found it; fire off the clear request
|
// found it; fire off the clear request
|
||||||
|
if (DEBUG) Slog.v(TAG, "Found the app - running clear process");
|
||||||
|
mBackupHandler.removeMessages(MSG_RETRY_CLEAR);
|
||||||
synchronized (mQueueLock) {
|
synchronized (mQueueLock) {
|
||||||
|
final IBackupTransport transport = getTransport(transportName);
|
||||||
|
if (transport == null) {
|
||||||
|
// transport is currently unavailable -- make sure to retry
|
||||||
|
Message msg = mBackupHandler.obtainMessage(MSG_RETRY_CLEAR,
|
||||||
|
new ClearRetryParams(transportName, packageName));
|
||||||
|
mBackupHandler.sendMessageDelayed(msg, TRANSPORT_RETRY_INTERVAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
long oldId = Binder.clearCallingIdentity();
|
long oldId = Binder.clearCallingIdentity();
|
||||||
mWakelock.acquire();
|
mWakelock.acquire();
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
|
Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
|
||||||
new ClearParams(getTransport(mCurrentTransport), info));
|
new ClearParams(transport, info));
|
||||||
mBackupHandler.sendMessage(msg);
|
mBackupHandler.sendMessage(msg);
|
||||||
Binder.restoreCallingIdentity(oldId);
|
Binder.restoreCallingIdentity(oldId);
|
||||||
}
|
}
|
||||||
@ -5626,10 +5704,21 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
+ " restoreSet=" + Long.toHexString(restoreSet));
|
+ " restoreSet=" + Long.toHexString(restoreSet));
|
||||||
|
|
||||||
if (mAutoRestore && mProvisioned && restoreSet != 0) {
|
if (mAutoRestore && mProvisioned && restoreSet != 0) {
|
||||||
|
// Do we have a transport to fetch data for us?
|
||||||
|
IBackupTransport transport = getTransport(mCurrentTransport);
|
||||||
|
if (transport == null) {
|
||||||
|
if (DEBUG) Slog.w(TAG, "No transport for install-time restore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// okay, we're going to attempt a restore of this package from this restore set.
|
// okay, we're going to attempt a restore of this package from this restore set.
|
||||||
// The eventual message back into the Package Manager to run the post-install
|
// The eventual message back into the Package Manager to run the post-install
|
||||||
// steps for 'token' will be issued from the restore handling code.
|
// steps for 'token' will be issued from the restore handling code.
|
||||||
|
|
||||||
|
// This can throw and so *must* happen before the wakelock is acquired
|
||||||
|
String dirName = transport.transportDirName();
|
||||||
|
|
||||||
// We can use a synthetic PackageInfo here because:
|
// We can use a synthetic PackageInfo here because:
|
||||||
// 1. We know it's valid, since the Package Manager supplied the name
|
// 1. We know it's valid, since the Package Manager supplied the name
|
||||||
// 2. Only the packageName field will be used by the restore code
|
// 2. Only the packageName field will be used by the restore code
|
||||||
@ -5638,9 +5727,13 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
mWakelock.acquire();
|
mWakelock.acquire();
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
||||||
msg.obj = new RestoreParams(getTransport(mCurrentTransport), null,
|
msg.obj = new RestoreParams(transport, dirName, null,
|
||||||
restoreSet, pkg, token, true);
|
restoreSet, pkg, token, true);
|
||||||
mBackupHandler.sendMessage(msg);
|
mBackupHandler.sendMessage(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Binding to the transport broke; back off and proceed with the installation.
|
||||||
|
Slog.e(TAG, "Unable to contact transport for install-time restore");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Auto-restore disabled or no way to attempt a restore; just tell the Package
|
// Auto-restore disabled or no way to attempt a restore; just tell the Package
|
||||||
// Manager to proceed with the post-install handling for this package.
|
// Manager to proceed with the post-install handling for this package.
|
||||||
|
Reference in New Issue
Block a user