diff options
author | Christopher Tate <ctate@google.com> | 2011-07-07 14:31:18 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2011-07-08 12:28:48 -0700 |
commit | 284f1bb4daf77f7e6b688c0936dd4a31ec2e7c74 (patch) | |
tree | d651aa41ee14b9137285163166b391badfe4cbe2 /services/java/com/android/server/BackupManagerService.java | |
parent | 1d19c18f9bd66b2b4883f8ce33c04ff5c87dd881 (diff) | |
download | frameworks_base-284f1bb4daf77f7e6b688c0936dd4a31ec2e7c74.zip frameworks_base-284f1bb4daf77f7e6b688c0936dd4a31ec2e7c74.tar.gz frameworks_base-284f1bb4daf77f7e6b688c0936dd4a31ec2e7c74.tar.bz2 |
Can now restore a subset of apps from historical dataset
Adds the ability to filter a restore of an historical dataset so that it
only restores certain apps' data regardless of what is actually present
in the dataset. This is currently only used by the bmgr command-line tool,
for debugging / developer support.
Bug 2021590
Change-Id: I7685e5d609b0f5506f71d70c26410602bb387659
Diffstat (limited to 'services/java/com/android/server/BackupManagerService.java')
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 108 |
1 files changed, 105 insertions, 3 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 6afccec..786f2fa 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -224,6 +224,7 @@ class BackupManagerService extends IBackupManager.Stub { public PackageInfo pkgInfo; public int pmToken; // in post-install restore, the PM's token for this transaction public boolean needFullBackup; + public String[] filterSet; RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) { @@ -233,6 +234,7 @@ class BackupManagerService extends IBackupManager.Stub { pkgInfo = _pkg; pmToken = _pmToken; needFullBackup = _needFullBackup; + filterSet = null; } RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, @@ -243,6 +245,18 @@ class BackupManagerService extends IBackupManager.Stub { pkgInfo = null; pmToken = 0; needFullBackup = _needFullBackup; + filterSet = null; + } + + RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, + String[] _filterSet, boolean _needFullBackup) { + transport = _transport; + observer = _obs; + token = _token; + pkgInfo = null; + pmToken = 0; + needFullBackup = _needFullBackup; + filterSet = _filterSet; } } @@ -404,7 +418,7 @@ class BackupManagerService extends IBackupManager.Stub { Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer); (new PerformRestoreTask(params.transport, params.observer, params.token, params.pkgInfo, params.pmToken, - params.needFullBackup)).run(); + params.needFullBackup, params.filterSet)).run(); break; } @@ -3020,6 +3034,7 @@ class BackupManagerService extends IBackupManager.Stub { private File mStateDir; private int mPmToken; private boolean mNeedFullBackup; + private HashSet<String> mFilterSet; class RestoreRequest { public PackageInfo app; @@ -3033,7 +3048,7 @@ class BackupManagerService extends IBackupManager.Stub { PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer, long restoreSetToken, PackageInfo targetPackage, int pmToken, - boolean needFullBackup) { + boolean needFullBackup, String[] filterSet) { mTransport = transport; mObserver = observer; mToken = restoreSetToken; @@ -3041,6 +3056,15 @@ class BackupManagerService extends IBackupManager.Stub { mPmToken = pmToken; mNeedFullBackup = needFullBackup; + if (filterSet != null) { + mFilterSet = new HashSet<String>(); + for (String pkg : filterSet) { + mFilterSet.add(pkg); + } + } else { + mFilterSet = null; + } + try { mStateDir = new File(mBaseStateDir, transport.transportDirName()); } catch (RemoteException e) { @@ -3052,7 +3076,8 @@ class BackupManagerService extends IBackupManager.Stub { long startRealtime = SystemClock.elapsedRealtime(); if (DEBUG) Slog.v(TAG, "Beginning restore process mTransport=" + mTransport + " mObserver=" + mObserver + " mToken=" + Long.toHexString(mToken) - + " mTargetPackage=" + mTargetPackage + " mPmToken=" + mPmToken); + + " mTargetPackage=" + mTargetPackage + " mFilterSet=" + mFilterSet + + " mPmToken=" + mPmToken); PackageManagerBackupAgent pmAgent = null; int error = -1; // assume error @@ -3071,6 +3096,22 @@ class BackupManagerService extends IBackupManager.Stub { List<PackageInfo> agentPackages = allAgentPackages(); if (mTargetPackage == null) { + // if there's a filter set, strip out anything that isn't + // present before proceeding + if (mFilterSet != null) { + for (int i = agentPackages.size() - 1; i >= 0; i--) { + final PackageInfo pkg = agentPackages.get(i); + if (! mFilterSet.contains(pkg.packageName)) { + agentPackages.remove(i); + } + } + if (DEBUG) { + Slog.i(TAG, "Post-filter package set for restore:"); + for (PackageInfo p : agentPackages) { + Slog.i(TAG, " " + p); + } + } + } restorePackages.addAll(agentPackages); } else { // Just one package to attempt restore of @@ -4266,6 +4307,67 @@ class BackupManagerService extends IBackupManager.Stub { return -1; } + public synchronized int restoreSome(long token, IRestoreObserver observer, + String[] packages) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, + "performRestore"); + + if (DEBUG) { + StringBuilder b = new StringBuilder(128); + b.append("restoreSome token="); + b.append(Long.toHexString(token)); + b.append(" observer="); + b.append(observer.toString()); + b.append(" packages="); + if (packages == null) { + b.append("null"); + } else { + b.append('{'); + boolean first = true; + for (String s : packages) { + if (!first) { + b.append(", "); + } else first = false; + b.append(s); + } + b.append('}'); + } + Slog.d(TAG, b.toString()); + } + + if (mEnded) { + throw new IllegalStateException("Restore session already ended"); + } + + if (mRestoreTransport == null || mRestoreSets == null) { + Slog.e(TAG, "Ignoring restoreAll() with no restore set"); + return -1; + } + + if (mPackageName != null) { + Slog.e(TAG, "Ignoring restoreAll() on single-package session"); + return -1; + } + + synchronized (mQueueLock) { + for (int i = 0; i < mRestoreSets.length; i++) { + if (token == mRestoreSets[i].token) { + long oldId = Binder.clearCallingIdentity(); + mWakelock.acquire(); + Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); + msg.obj = new RestoreParams(mRestoreTransport, observer, token, + packages, true); + mBackupHandler.sendMessage(msg); + Binder.restoreCallingIdentity(oldId); + return 0; + } + } + } + + Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found"); + return -1; + } + public synchronized int restorePackage(String packageName, IRestoreObserver observer) { if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer); |