private PowerManager mPowerManager;
private AlarmManager mAlarmManager;
private IStorageManager mStorageManager;
+
IBackupManager mBackupManagerBinder;
private final TransportManager mTransportManager;
ArrayList<FullBackupEntry> mFullBackupQueue;
// Utility: build a new random integer token
- int generateToken() {
+ @Override
+ public int generateRandomIntegerToken() {
int token;
do {
synchronized (mTokenGenerator) {
}
// fire off a backup agent, blocking until it attaches or times out
- IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+ @Override
+ public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
IBackupAgent agent = null;
synchronized(mAgentConnectLock) {
mConnecting = true;
}
}
- // -----
- // Interface and methods used by the asynchronous-with-timeout backup/restore operations
-
- interface BackupRestoreTask {
- // Execute one tick of whatever state machine the task implements
- void execute();
-
- // An operation that wanted a callback has completed
- void operationComplete(long result);
-
- // An operation that wanted a callback has timed out
- void handleCancel(boolean cancelAll);
- }
-
- void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
- int operationType) {
+ @Override
+ public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+ int operationType) {
if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
Integer.toHexString(token) + " of type " + operationType);
}
// synchronous waiter case
- boolean waitUntilOperationComplete(int token) {
+ @Override
+ public boolean waitUntilOperationComplete(int token) {
if (MORE_DEBUG) Slog.i(TAG, "Blocking until operation complete for "
+ Integer.toHexString(token));
int finalState = OP_PENDING;
mNonIncremental = nonIncremental;
mStateDir = new File(mBaseStateDir, dirName);
- mCurrentOpToken = generateToken();
+ mCurrentOpToken = generateRandomIntegerToken();
mFinished = false;
mNewState = null;
boolean callingAgent = false;
- mEphemeralOpToken = generateToken();
+ mEphemeralOpToken = generateRandomIntegerToken();
try {
// Look up the package info & signatures. This is first so that if it
// throws an exception, there's no file setup yet that would need to
ParcelFileDescriptor[] pipes = null;
try {
pipes = ParcelFileDescriptor.createPipe();
- int token = generateToken();
+ int token = generateRandomIntegerToken();
prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
null, OP_TYPE_BACKUP_WAIT);
mService.backupObbs(pkg.packageName, pipes[1], token, mBackupManagerBinder);
}
}
- void tearDownAgentAndKill(ApplicationInfo app) {
+ @Override
+ public void tearDownAgentAndKill(ApplicationInfo app) {
if (app == null) {
// Null means the system package, so just quietly move on. :)
return;
String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
super(observer);
- mCurrentOpToken = generateToken();
+ mCurrentOpToken = generateRandomIntegerToken();
mLatch = latch;
mOutputFile = fd;
mBackupObserver = backupObserver;
mMonitor = monitor;
mUserInitiated = userInitiated;
- mCurrentOpToken = generateToken();
- mBackupRunnerOpToken = generateToken();
+ mCurrentOpToken = generateRandomIntegerToken();
+ mBackupRunnerOpToken = generateRandomIntegerToken();
if (isBackupOperationInProgress()) {
if (DEBUG) {
mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
mTarget = target;
mCurrentOpToken = currentOpToken;
- mEphemeralToken = generateToken();
+ mEphemeralToken = generateRandomIntegerToken();
mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
mPreflightLatch = new CountDownLatch(1);
mBackupLatch = new CountDownLatch(1);
* @return Whether ongoing work will continue. The return value here will be passed
* along as the return value to the scheduled job's onStartJob() callback.
*/
- boolean beginFullBackup(FullBackupJob scheduledJob) {
+ @Override
+ public boolean beginFullBackup(FullBackupJob scheduledJob) {
long now = System.currentTimeMillis();
FullBackupEntry entry = null;
long latency = MIN_FULL_BACKUP_INTERVAL;
// The job scheduler says our constraints don't hold any more,
// so tear down any ongoing backup task right away.
- void endFullBackup() {
+ @Override
+ public void endFullBackup() {
synchronized (mQueueLock) {
if (mRunningFullBackupTask != null) {
if (DEBUG_SCHEDULING) {
// ----- Full restore from a file/socket -----
- // Description of a file in the restore datastream
- static class FileMetadata {
- String packageName; // name of the owning app
- String installerPackageName; // name of the market-type app that installed the owner
- int type; // e.g. BackupAgent.TYPE_DIRECTORY
- String domain; // e.g. FullBackup.DATABASE_TREE_TOKEN
- String path; // subpath within the semantic domain
- long mode; // e.g. 0666 (actually int)
- long mtime; // last mod time, UTC time_t (actually int)
- long size; // bytes of content
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(128);
- sb.append("FileMetadata{");
- sb.append(packageName); sb.append(',');
- sb.append(type); sb.append(',');
- sb.append(domain); sb.append(':'); sb.append(path); sb.append(',');
- sb.append(size);
- sb.append('}');
- return sb.toString();
- }
- }
-
enum RestorePolicy {
IGNORE,
ACCEPT,
if (okay) {
boolean agentSuccess = true;
long toCopy = info.size;
- final int token = generateToken();
+ final int token = generateRandomIntegerToken();
try {
prepareOperationTimeout(token, TIMEOUT_RESTORE_INTERVAL, null,
OP_TYPE_RESTORE_WAIT);
try {
// In the adb restore case, we do restore-finished here
if (doRestoreFinished) {
- final int token = generateToken();
+ final int token = generateRandomIntegerToken();
final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(token);
prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch,
OP_TYPE_RESTORE_WAIT);
PerformUnifiedRestoreTask(IBackupTransport transport, IRestoreObserver observer,
IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
int pmToken, boolean isFullSystemRestore, String[] filterSet) {
- mEphemeralOpToken = generateToken();
+ mEphemeralOpToken = generateRandomIntegerToken();
mState = UnifiedRestoreState.INITIAL;
mStartRealtime = SystemClock.elapsedRealtime();
private final int mEphemeralOpToken;
public StreamFeederThread() throws IOException {
- mEphemeralOpToken = generateToken();
+ mEphemeralOpToken = generateRandomIntegerToken();
mTransportPipes = ParcelFileDescriptor.createPipe();
mEnginePipes = ParcelFileDescriptor.createPipe();
setRunning(true);
AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
pkgList);
- final int token = generateToken();
+ final int token = generateRandomIntegerToken();
synchronized (mAdbBackupRestoreConfirmations) {
mAdbBackupRestoreConfirmations.put(token, params);
}
Slog.i(TAG, "Beginning restore...");
AdbRestoreParams params = new AdbRestoreParams(fd);
- final int token = generateToken();
+ final int token = generateRandomIntegerToken();
synchronized (mAdbBackupRestoreConfirmations) {
mAdbBackupRestoreConfirmations.put(token, params);
}
}
return null;
}
+
+ @Override
+ public IBackupManager getBackupManagerBinder() {
+ return mBackupManagerBinder;
+ }
+
}
package com.android.server.backup;
+import android.app.IBackupAgent;
+import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.ISelectBackupTransportCallback;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
*/
public interface BackupManagerServiceInterface {
+ // Utility: build a new random integer token
+ int generateRandomIntegerToken();
+
boolean setBackupPassword(String currentPw, String newPw);
boolean hasBackupPassword();
+ // fire off a backup agent, blocking until it attaches or times out
+ IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode);
+
// Get the restore-set token for the best-available restore set for this package:
// the active set if possible, else the ancestral one. Returns zero if none available.
long getAvailableRestoreToken(String packageName);
// Cancel all running backups.
void cancelBackups();
+ void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+ int operationType);
+
+ // synchronous waiter case
+ boolean waitUntilOperationComplete(int token);
+
+ void tearDownAgentAndKill(ApplicationInfo app);
+
+ boolean beginFullBackup(FullBackupJob scheduledJob);
+
+ // The job scheduler says our constraints don't hold any more,
+ // so tear down any ongoing backup task right away.
+ void endFullBackup();
+
void dataChanged(String packageName);
// Clear the given package's backup data from the current transport
boolean isAppEligibleForBackup(String packageName);
void dump(FileDescriptor fd, PrintWriter pw, String[] args);
+
+ IBackupManager getBackupManagerBinder();
}
private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";
- private BackupManagerService mBackupManagerService;
+ private BackupManagerServiceInterface mBackupManagerService;
private final PackageManager mPackageManager;
private final OutputStream mOutput;
private final PackageInfo mCurrentPackage;
private ParcelFileDescriptor mNewState;
KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
- BackupManagerService backupManagerService, PackageManager packageManager,
+ BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
File baseStateDir, File dataDir) {
mOutput = output;
mCurrentPackage = packageInfo;
// Return true on backup success, false otherwise
private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
- int token = mBackupManagerService.generateToken();
+ int token = mBackupManagerService.generateRandomIntegerToken();
try {
mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
OP_TYPE_BACKUP_WAIT);
// Start backup and wait for BackupManagerService to get callback for success or timeout
agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
- mBackupManagerService.mBackupManagerBinder);
+ mBackupManagerService.getBackupManagerBinder());
if (!mBackupManagerService.waitUntilOperationComplete(token)) {
Slog.e(TAG, "Key-value backup failed on package " + packageName);
return false;
}
try {
- mBackupManagerService.mBackupManagerBinder.opComplete(mToken, 0);
+ mBackupManagerService.getBackupManagerBinder().opComplete(mToken, 0);
} catch (RemoteException e) {
// we'll time out anyway, so we're safe
}
private void writeBackupData() throws IOException {
- int token = mBackupManagerService.generateToken();
+ int token = mBackupManagerService.generateRandomIntegerToken();
ParcelFileDescriptor[] pipes = null;
try {