diff options
-rw-r--r-- | cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java | 81 | ||||
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 6 |
2 files changed, 70 insertions, 17 deletions
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index acfbb07..7e9fd61 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -289,17 +289,66 @@ public final class Bmgr { this.notify(); } } + + public void waitForCompletion() { + // The restoreFinished() callback will throw the 'done' flag; we + // just sit and wait on that notification. + synchronized (this) { + while (!this.done) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + } + } } private void doRestore() { - long token; + String arg = nextArg(); + if (arg.indexOf('.') >= 0) { + // it's a package name + doRestorePackage(arg); + } else { + try { + long token = Long.parseLong(nextArg(), 16); + doRestoreAll(token); + } catch (NumberFormatException e) { + showUsage(); + return; + } + } + + System.out.println("done"); + } + + private void doRestorePackage(String pkg) { try { - token = Long.parseLong(nextArg(), 16); - } catch (NumberFormatException e) { - showUsage(); - return; + String curTransport = mBmgr.getCurrentTransport(); + mRestore = mBmgr.beginRestoreSession(curTransport); + if (mRestore == null) { + System.err.println(BMGR_NOT_RUNNING_ERR); + return; + } + + RestoreObserver observer = new RestoreObserver(); + int err = mRestore.restorePackage(pkg, observer); + if (err == 0) { + // Off and running -- wait for the restore to complete + observer.waitForCompletion(); + } else { + System.err.println("Unable to restore package " + pkg); + } + + // And finally shut down the session + mRestore.endRestoreSession(); + } catch (RemoteException e) { + System.err.println(e.toString()); + System.err.println(BMGR_NOT_RUNNING_ERR); } + } + private void doRestoreAll(long token) { RestoreObserver observer = new RestoreObserver(); try { @@ -332,14 +381,7 @@ public final class Bmgr { // if we kicked off a restore successfully, we have to wait for it // to complete before we can shut down the restore session safely if (didRestore) { - synchronized (observer) { - while (!observer.done) { - try { - observer.wait(); - } catch (InterruptedException ex) { - } - } - } + observer.waitForCompletion(); } // once the restore has finished, close down the session and we're done @@ -348,8 +390,6 @@ public final class Bmgr { System.err.println(e.toString()); System.err.println(BMGR_NOT_RUNNING_ERR); } - - System.out.println("done"); } private String nextArg() { @@ -370,6 +410,7 @@ public final class Bmgr { System.err.println(" bmgr list sets"); System.err.println(" bmgr transport WHICH"); System.err.println(" bmgr restore TOKEN"); + System.err.println(" bmgr restore PACKAGE"); System.err.println(" bmgr run"); System.err.println(" bmgr wipe PACKAGE"); System.err.println(""); @@ -396,8 +437,14 @@ public final class Bmgr { System.err.println("The 'transport' command designates the named transport as the currently"); System.err.println("active one. This setting is persistent across reboots."); System.err.println(""); - System.err.println("The 'restore' command initiates a restore operation, using the restore set"); - System.err.println("from the current transport whose token matches the argument."); + System.err.println("The 'restore' command when given a restore token initiates a full-system"); + System.err.println("restore operation from the currently active transport. It will deliver"); + System.err.println("the restore set designated by the TOKEN argument to each application"); + System.err.println("that had contributed data to that restore set."); + System.err.println(""); + System.err.println("The 'restore' command when given a package name intiates a restore of"); + System.err.println("just that one package according to the restore set selection algorithm"); + System.err.println("used by the RestoreSession.restorePackage() method."); System.err.println(""); System.err.println("The 'run' command causes any scheduled backup operation to be initiated"); System.err.println("immediately, without the usual waiting period for batching together"); diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 27faf3d..34e9cb9 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -2427,6 +2427,12 @@ class BackupManagerService extends IBackupManager.Stub { throw new SecurityException("No permission to restore other packages"); } + // If the package has no backup agent, we obviously cannot proceed + if (app.applicationInfo.backupAgentName == null) { + Log.w(TAG, "Asked to restore package " + packageName + " with no agent"); + return -1; + } + // So far so good; we're allowed to try to restore this package. Now // check whether there is data for it in the current dataset, falling back // to the ancestral dataset if not. |