Bmgr.java revision fa51853ae56ed74a0c854c01851cb1435453005f
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.commands.bmgr; 18 19import android.app.backup.BackupManager; 20import android.app.backup.BackupProgress; 21import android.app.backup.BackupTransport; 22import android.app.backup.IBackupManager; 23import android.app.backup.IBackupObserver; 24import android.app.backup.IRestoreObserver; 25import android.app.backup.IRestoreSession; 26import android.app.backup.ISelectBackupTransportCallback; 27import android.app.backup.RestoreSet; 28import android.content.ComponentName; 29import android.content.pm.IPackageManager; 30import android.content.pm.PackageInfo; 31import android.os.RemoteException; 32import android.os.ServiceManager; 33import android.os.SystemClock; 34import android.os.UserHandle; 35import android.util.ArraySet; 36 37import com.android.internal.annotations.GuardedBy; 38 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.HashSet; 42import java.util.List; 43import java.util.concurrent.CountDownLatch; 44 45public final class Bmgr { 46 IBackupManager mBmgr; 47 IRestoreSession mRestore; 48 49 static final String BMGR_NOT_RUNNING_ERR = 50 "Error: Could not access the Backup Manager. Is the system running?"; 51 static final String TRANSPORT_NOT_RUNNING_ERR = 52 "Error: Could not access the backup transport. Is the system running?"; 53 static final String PM_NOT_RUNNING_ERR = 54 "Error: Could not access the Package Manager. Is the system running?"; 55 56 private String[] mArgs; 57 private int mNextArg; 58 59 public static void main(String[] args) { 60 try { 61 new Bmgr().run(args); 62 } catch (Exception e) { 63 System.err.println("Exception caught:"); 64 e.printStackTrace(); 65 } 66 } 67 68 public void run(String[] args) { 69 if (args.length < 1) { 70 showUsage(); 71 return; 72 } 73 74 mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); 75 if (mBmgr == null) { 76 System.err.println(BMGR_NOT_RUNNING_ERR); 77 return; 78 } 79 80 mArgs = args; 81 String op = args[0]; 82 mNextArg = 1; 83 84 if ("enabled".equals(op)) { 85 doEnabled(); 86 return; 87 } 88 89 if ("enable".equals(op)) { 90 doEnable(); 91 return; 92 } 93 94 if ("run".equals(op)) { 95 doRun(); 96 return; 97 } 98 99 if ("backup".equals(op)) { 100 doBackup(); 101 return; 102 } 103 104 if ("init".equals(op)) { 105 doInit(); 106 return; 107 } 108 109 if ("list".equals(op)) { 110 doList(); 111 return; 112 } 113 114 if ("restore".equals(op)) { 115 doRestore(); 116 return; 117 } 118 119 if ("transport".equals(op)) { 120 doTransport(); 121 return; 122 } 123 124 if ("wipe".equals(op)) { 125 doWipe(); 126 return; 127 } 128 129 if ("fullbackup".equals(op)) { 130 doFullTransportBackup(); 131 return; 132 } 133 134 if ("backupnow".equals(op)) { 135 doBackupNow(); 136 return; 137 } 138 139 if ("cancel".equals(op)) { 140 doCancel(); 141 return; 142 } 143 144 if ("whitelist".equals(op)) { 145 doPrintWhitelist(); 146 return; 147 } 148 149 System.err.println("Unknown command"); 150 showUsage(); 151 } 152 153 private String enableToString(boolean enabled) { 154 return enabled ? "enabled" : "disabled"; 155 } 156 157 private void doEnabled() { 158 try { 159 boolean isEnabled = mBmgr.isBackupEnabled(); 160 System.out.println("Backup Manager currently " 161 + enableToString(isEnabled)); 162 } catch (RemoteException e) { 163 System.err.println(e.toString()); 164 System.err.println(BMGR_NOT_RUNNING_ERR); 165 } 166 } 167 168 private void doEnable() { 169 String arg = nextArg(); 170 if (arg == null) { 171 showUsage(); 172 return; 173 } 174 175 try { 176 boolean enable = Boolean.parseBoolean(arg); 177 mBmgr.setBackupEnabled(enable); 178 System.out.println("Backup Manager now " + enableToString(enable)); 179 } catch (NumberFormatException e) { 180 showUsage(); 181 return; 182 } catch (RemoteException e) { 183 System.err.println(e.toString()); 184 System.err.println(BMGR_NOT_RUNNING_ERR); 185 } 186 } 187 188 private void doRun() { 189 try { 190 mBmgr.backupNow(); 191 } catch (RemoteException e) { 192 System.err.println(e.toString()); 193 System.err.println(BMGR_NOT_RUNNING_ERR); 194 } 195 } 196 197 private void doBackup() { 198 String pkg = nextArg(); 199 if (pkg == null) { 200 showUsage(); 201 return; 202 } 203 204 try { 205 mBmgr.dataChanged(pkg); 206 } catch (RemoteException e) { 207 System.err.println(e.toString()); 208 System.err.println(BMGR_NOT_RUNNING_ERR); 209 } 210 } 211 212 private void doFullTransportBackup() { 213 System.out.println("Performing full transport backup"); 214 215 String pkg; 216 ArraySet<String> allPkgs = new ArraySet<String>(); 217 while ((pkg = nextArg()) != null) { 218 allPkgs.add(pkg); 219 } 220 if (allPkgs.size() > 0) { 221 try { 222 mBmgr.fullTransportBackup(allPkgs.toArray(new String[allPkgs.size()])); 223 } catch (RemoteException e) { 224 System.err.println(e.toString()); 225 System.err.println(BMGR_NOT_RUNNING_ERR); 226 } 227 } 228 } 229 230 // IBackupObserver generically usable for any backup/init operation 231 abstract class Observer extends IBackupObserver.Stub { 232 private final Object trigger = new Object(); 233 234 @GuardedBy("trigger") 235 private volatile boolean done = false; 236 237 @Override 238 public void onUpdate(String currentPackage, BackupProgress backupProgress) { 239 } 240 241 @Override 242 public void onResult(String currentPackage, int status) { 243 } 244 245 @Override 246 public void backupFinished(int status) { 247 synchronized (trigger) { 248 done = true; 249 trigger.notify(); 250 } 251 } 252 253 public boolean done() { 254 return this.done; 255 } 256 257 // Wait forever 258 public void waitForCompletion() { 259 waitForCompletion(0); 260 } 261 262 // Wait for a given time and then give up 263 public void waitForCompletion(long timeout) { 264 // The backupFinished() callback will throw the 'done' flag; we 265 // just sit and wait on that notification. 266 final long targetTime = SystemClock.elapsedRealtime() + timeout; 267 synchronized (trigger) { 268 // Wait until either we're done, or we've reached a stated positive timeout 269 while (!done && (timeout <= 0 || SystemClock.elapsedRealtime() < targetTime)) { 270 try { 271 trigger.wait(1000L); 272 } catch (InterruptedException ex) { 273 } 274 } 275 } 276 } 277 } 278 279 class BackupObserver extends Observer { 280 @Override 281 public void onUpdate(String currentPackage, BackupProgress backupProgress) { 282 super.onUpdate(currentPackage, backupProgress); 283 System.out.println( 284 "Package " + currentPackage + " with progress: " + backupProgress.bytesTransferred 285 + "/" + backupProgress.bytesExpected); 286 } 287 288 @Override 289 public void onResult(String currentPackage, int status) { 290 super.onResult(currentPackage, status); 291 System.out.println("Package " + currentPackage + " with result: " 292 + convertBackupStatusToString(status)); 293 } 294 295 @Override 296 public void backupFinished(int status) { 297 super.backupFinished(status); 298 System.out.println("Backup finished with result: " 299 + convertBackupStatusToString(status)); 300 } 301 } 302 303 private static String convertBackupStatusToString(int errorCode) { 304 switch (errorCode) { 305 case BackupManager.SUCCESS: 306 return "Success"; 307 case BackupManager.ERROR_BACKUP_NOT_ALLOWED: 308 return "Backup is not allowed"; 309 case BackupManager.ERROR_PACKAGE_NOT_FOUND: 310 return "Package not found"; 311 case BackupManager.ERROR_TRANSPORT_ABORTED: 312 return "Transport error"; 313 case BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED: 314 return "Transport rejected package because it wasn't able to process it" 315 + " at the time"; 316 case BackupManager.ERROR_AGENT_FAILURE: 317 return "Agent error"; 318 case BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED: 319 return "Size quota exceeded"; 320 case BackupManager.ERROR_BACKUP_CANCELLED: 321 return "Backup Cancelled"; 322 default: 323 return "Unknown error"; 324 } 325 } 326 327 private void backupNowAllPackages(boolean nonIncrementalBackup) { 328 int userId = UserHandle.USER_SYSTEM; 329 IPackageManager mPm = 330 IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 331 if (mPm == null) { 332 System.err.println(PM_NOT_RUNNING_ERR); 333 return; 334 } 335 List<PackageInfo> installedPackages = null; 336 try { 337 installedPackages = mPm.getInstalledPackages(0, userId).getList(); 338 } catch (RemoteException e) { 339 System.err.println(e.toString()); 340 System.err.println(PM_NOT_RUNNING_ERR); 341 } 342 if (installedPackages != null) { 343 String[] packages = 344 installedPackages.stream().map(p -> p.packageName).toArray(String[]::new); 345 String[] filteredPackages = {}; 346 try { 347 filteredPackages = mBmgr.filterAppsEligibleForBackup(packages); 348 } catch (RemoteException e) { 349 System.err.println(e.toString()); 350 System.err.println(BMGR_NOT_RUNNING_ERR); 351 } 352 backupNowPackages(Arrays.asList(filteredPackages), nonIncrementalBackup); 353 } 354 } 355 356 private void backupNowPackages(List<String> packages, boolean nonIncrementalBackup) { 357 int flags = 0; 358 if (nonIncrementalBackup) { 359 flags |= BackupManager.FLAG_NON_INCREMENTAL_BACKUP; 360 } 361 try { 362 BackupObserver observer = new BackupObserver(); 363 // TODO: implement monitor here? 364 int err = mBmgr.requestBackup(packages.toArray(new String[packages.size()]), observer, 365 null, flags); 366 if (err == 0) { 367 // Off and running -- wait for the backup to complete 368 observer.waitForCompletion(); 369 } else { 370 System.err.println("Unable to run backup"); 371 } 372 } catch (RemoteException e) { 373 System.err.println(e.toString()); 374 System.err.println(BMGR_NOT_RUNNING_ERR); 375 } 376 } 377 378 private void doBackupNow() { 379 String pkg; 380 boolean backupAll = false; 381 boolean nonIncrementalBackup = false; 382 ArrayList<String> allPkgs = new ArrayList<String>(); 383 while ((pkg = nextArg()) != null) { 384 if (pkg.equals("--all")) { 385 backupAll = true; 386 } else if (pkg.equals("--non-incremental")) { 387 nonIncrementalBackup = true; 388 } else if (pkg.equals("--incremental")) { 389 nonIncrementalBackup = false; 390 } else { 391 if (!allPkgs.contains(pkg)) { 392 allPkgs.add(pkg); 393 } 394 } 395 } 396 if (backupAll) { 397 if (allPkgs.size() == 0) { 398 System.out.println("Running " + (nonIncrementalBackup ? "non-" : "") + 399 "incremental backup for all packages."); 400 backupNowAllPackages(nonIncrementalBackup); 401 } else { 402 System.err.println("Provide only '--all' flag or list of packages."); 403 } 404 } else if (allPkgs.size() > 0) { 405 System.out.println("Running " + (nonIncrementalBackup ? "non-" : "") + 406 "incremental backup for " + allPkgs.size() +" requested packages."); 407 backupNowPackages(allPkgs, nonIncrementalBackup); 408 } else { 409 System.err.println("Provide '--all' flag or list of packages."); 410 } 411 } 412 413 private void doCancel() { 414 String arg = nextArg(); 415 if ("backups".equals(arg)) { 416 try { 417 mBmgr.cancelBackups(); 418 } catch (RemoteException e) { 419 System.err.println(e.toString()); 420 System.err.println(BMGR_NOT_RUNNING_ERR); 421 } 422 return; 423 } 424 425 System.err.println("Unknown command."); 426 } 427 428 private void doTransport() { 429 try { 430 String which = nextArg(); 431 if (which == null) { 432 showUsage(); 433 return; 434 } 435 436 if ("-c".equals(which)) { 437 doTransportByComponent(); 438 return; 439 } 440 441 String old = mBmgr.selectBackupTransport(which); 442 if (old == null) { 443 System.out.println("Unknown transport '" + which 444 + "' specified; no changes made."); 445 } else { 446 System.out.println("Selected transport " + which + " (formerly " + old + ")"); 447 } 448 449 } catch (RemoteException e) { 450 System.err.println(e.toString()); 451 System.err.println(BMGR_NOT_RUNNING_ERR); 452 } 453 } 454 455 private void doTransportByComponent() { 456 String which = nextArg(); 457 if (which == null) { 458 showUsage(); 459 return; 460 } 461 462 final CountDownLatch latch = new CountDownLatch(1); 463 464 try { 465 mBmgr.selectBackupTransportAsync(ComponentName.unflattenFromString(which), 466 new ISelectBackupTransportCallback.Stub() { 467 @Override 468 public void onSuccess(String transportName) { 469 System.out.println("Success. Selected transport: " + transportName); 470 latch.countDown(); 471 } 472 473 @Override 474 public void onFailure(int reason) { 475 System.err.println("Failure. error=" + reason); 476 latch.countDown(); 477 } 478 }); 479 } catch (RemoteException e) { 480 System.err.println(e.toString()); 481 System.err.println(BMGR_NOT_RUNNING_ERR); 482 return; 483 } 484 485 try { 486 latch.await(); 487 } catch (InterruptedException e) { 488 System.err.println("Operation interrupted."); 489 } 490 } 491 492 private void doWipe() { 493 String transport = nextArg(); 494 if (transport == null) { 495 showUsage(); 496 return; 497 } 498 499 String pkg = nextArg(); 500 if (pkg == null) { 501 showUsage(); 502 return; 503 } 504 505 try { 506 mBmgr.clearBackupData(transport, pkg); 507 System.out.println("Wiped backup data for " + pkg + " on " + transport); 508 } catch (RemoteException e) { 509 System.err.println(e.toString()); 510 System.err.println(BMGR_NOT_RUNNING_ERR); 511 } 512 } 513 514 class InitObserver extends Observer { 515 public int result = BackupTransport.TRANSPORT_ERROR; 516 517 @Override 518 public void backupFinished(int status) { 519 super.backupFinished(status); 520 result = status; 521 } 522 } 523 524 private void doInit() { 525 ArraySet<String> transports = new ArraySet<>(); 526 String transport; 527 while ((transport = nextArg()) != null) { 528 transports.add(transport); 529 } 530 if (transports.size() == 0) { 531 showUsage(); 532 return; 533 } 534 535 InitObserver observer = new InitObserver(); 536 try { 537 System.out.println("Initializing transports: " + transports); 538 mBmgr.initializeTransports(transports.toArray(new String[transports.size()]), observer); 539 observer.waitForCompletion(30*1000L); 540 System.out.println("Initialization result: " + observer.result); 541 } catch (RemoteException e) { 542 System.err.println(e.toString()); 543 System.err.println(BMGR_NOT_RUNNING_ERR); 544 } 545 } 546 547 private void doList() { 548 String arg = nextArg(); // sets, transports, packages set# 549 if ("transports".equals(arg)) { 550 doListTransports(); 551 return; 552 } 553 554 // The rest of the 'list' options work with a restore session on the current transport 555 try { 556 mRestore = mBmgr.beginRestoreSession(null, null); 557 if (mRestore == null) { 558 System.err.println(BMGR_NOT_RUNNING_ERR); 559 return; 560 } 561 562 if ("sets".equals(arg)) { 563 doListRestoreSets(); 564 } else if ("transports".equals(arg)) { 565 doListTransports(); 566 } 567 568 mRestore.endRestoreSession(); 569 } catch (RemoteException e) { 570 System.err.println(e.toString()); 571 System.err.println(BMGR_NOT_RUNNING_ERR); 572 } 573 } 574 575 private void doListTransports() { 576 String arg = nextArg(); 577 578 try { 579 if ("-c".equals(arg)) { 580 for (ComponentName transport : mBmgr.listAllTransportComponents()) { 581 System.out.println(transport.flattenToShortString()); 582 } 583 return; 584 } 585 586 String current = mBmgr.getCurrentTransport(); 587 String[] transports = mBmgr.listAllTransports(); 588 if (transports == null || transports.length == 0) { 589 System.out.println("No transports available."); 590 return; 591 } 592 593 for (String t : transports) { 594 String pad = (t.equals(current)) ? " * " : " "; 595 System.out.println(pad + t); 596 } 597 } catch (RemoteException e) { 598 System.err.println(e.toString()); 599 System.err.println(BMGR_NOT_RUNNING_ERR); 600 } 601 } 602 603 private void doListRestoreSets() { 604 try { 605 RestoreObserver observer = new RestoreObserver(); 606 // TODO implement monitor here 607 int err = mRestore.getAvailableRestoreSets(observer, null); 608 if (err != 0) { 609 System.out.println("Unable to request restore sets"); 610 } else { 611 observer.waitForCompletion(); 612 printRestoreSets(observer.sets); 613 } 614 } catch (RemoteException e) { 615 System.err.println(e.toString()); 616 System.err.println(TRANSPORT_NOT_RUNNING_ERR); 617 } 618 } 619 620 private void printRestoreSets(RestoreSet[] sets) { 621 if (sets == null || sets.length == 0) { 622 System.out.println("No restore sets"); 623 return; 624 } 625 for (RestoreSet s : sets) { 626 System.out.println(" " + Long.toHexString(s.token) + " : " + s.name); 627 } 628 } 629 630 class RestoreObserver extends IRestoreObserver.Stub { 631 boolean done; 632 RestoreSet[] sets = null; 633 634 public void restoreSetsAvailable(RestoreSet[] result) { 635 synchronized (this) { 636 sets = result; 637 done = true; 638 this.notify(); 639 } 640 } 641 642 public void restoreStarting(int numPackages) { 643 System.out.println("restoreStarting: " + numPackages + " packages"); 644 } 645 646 public void onUpdate(int nowBeingRestored, String currentPackage) { 647 System.out.println("onUpdate: " + nowBeingRestored + " = " + currentPackage); 648 } 649 650 public void restoreFinished(int error) { 651 System.out.println("restoreFinished: " + error); 652 synchronized (this) { 653 done = true; 654 this.notify(); 655 } 656 } 657 658 /** 659 * Wait until either {@link #restoreFinished} or {@link #restoreStarting} is called. 660 * Once one is called, it clears the internal flag again, so that the same observer intance 661 * can be reused for a next operation. 662 */ 663 public void waitForCompletion() { 664 // The restoreFinished() callback will throw the 'done' flag; we 665 // just sit and wait on that notification. 666 synchronized (this) { 667 while (!this.done) { 668 try { 669 this.wait(); 670 } catch (InterruptedException ex) { 671 } 672 } 673 done = false; 674 } 675 } 676 } 677 678 private void doRestore() { 679 String arg = nextArg(); 680 if (arg == null) { 681 showUsage(); 682 return; 683 } 684 685 if (arg.indexOf('.') >= 0 || arg.equals("android")) { 686 // it's a package name 687 doRestorePackage(arg); 688 } else { 689 try { 690 long token = Long.parseLong(arg, 16); 691 HashSet<String> filter = null; 692 while ((arg = nextArg()) != null) { 693 if (filter == null) filter = new HashSet<String>(); 694 filter.add(arg); 695 } 696 697 doRestoreAll(token, filter); 698 } catch (NumberFormatException e) { 699 showUsage(); 700 return; 701 } 702 } 703 704 System.out.println("done"); 705 } 706 707 private void doRestorePackage(String pkg) { 708 try { 709 mRestore = mBmgr.beginRestoreSession(pkg, null); 710 if (mRestore == null) { 711 System.err.println(BMGR_NOT_RUNNING_ERR); 712 return; 713 } 714 715 RestoreObserver observer = new RestoreObserver(); 716 // TODO implement monitor here 717 int err = mRestore.restorePackage(pkg, observer, null ); 718 if (err == 0) { 719 // Off and running -- wait for the restore to complete 720 observer.waitForCompletion(); 721 } else { 722 System.err.println("Unable to restore package " + pkg); 723 } 724 725 // And finally shut down the session 726 mRestore.endRestoreSession(); 727 } catch (RemoteException e) { 728 System.err.println(e.toString()); 729 System.err.println(BMGR_NOT_RUNNING_ERR); 730 } 731 } 732 733 private void doRestoreAll(long token, HashSet<String> filter) { 734 RestoreObserver observer = new RestoreObserver(); 735 736 try { 737 boolean didRestore = false; 738 mRestore = mBmgr.beginRestoreSession(null, null); 739 if (mRestore == null) { 740 System.err.println(BMGR_NOT_RUNNING_ERR); 741 return; 742 } 743 RestoreSet[] sets = null; 744 // TODO implement monitor here 745 int err = mRestore.getAvailableRestoreSets(observer, null); 746 if (err == 0) { 747 observer.waitForCompletion(); 748 sets = observer.sets; 749 if (sets != null) { 750 for (RestoreSet s : sets) { 751 if (s.token == token) { 752 System.out.println("Scheduling restore: " + s.name); 753 if (filter == null) { 754 didRestore = (mRestore.restoreAll(token, observer, null) == 0); 755 } else { 756 String[] names = new String[filter.size()]; 757 filter.toArray(names); 758 didRestore = (mRestore.restoreSome(token, observer, 759 null, names) == 0); 760 } 761 break; 762 } 763 } 764 } 765 } 766 if (!didRestore) { 767 if (sets == null || sets.length == 0) { 768 System.out.println("No available restore sets; no restore performed"); 769 } else { 770 System.out.println("No matching restore set token. Available sets:"); 771 printRestoreSets(sets); 772 } 773 } 774 775 // if we kicked off a restore successfully, we have to wait for it 776 // to complete before we can shut down the restore session safely 777 if (didRestore) { 778 observer.waitForCompletion(); 779 } 780 781 // once the restore has finished, close down the session and we're done 782 mRestore.endRestoreSession(); 783 } catch (RemoteException e) { 784 System.err.println(e.toString()); 785 System.err.println(BMGR_NOT_RUNNING_ERR); 786 } 787 } 788 789 private void doPrintWhitelist() { 790 try { 791 final String[] whitelist = mBmgr.getTransportWhitelist(); 792 if (whitelist != null) { 793 for (String transport : whitelist) { 794 System.out.println(transport); 795 } 796 } 797 } catch (RemoteException e) { 798 System.err.println(e.toString()); 799 System.err.println(BMGR_NOT_RUNNING_ERR); 800 } 801 } 802 803 private String nextArg() { 804 if (mNextArg >= mArgs.length) { 805 return null; 806 } 807 String arg = mArgs[mNextArg]; 808 mNextArg++; 809 return arg; 810 } 811 812 private static void showUsage() { 813 System.err.println("usage: bmgr [backup|restore|list|transport|run]"); 814 System.err.println(" bmgr backup PACKAGE"); 815 System.err.println(" bmgr enable BOOL"); 816 System.err.println(" bmgr enabled"); 817 System.err.println(" bmgr list transports [-c]"); 818 System.err.println(" bmgr list sets"); 819 System.err.println(" bmgr transport WHICH|-c WHICH_COMPONENT"); 820 System.err.println(" bmgr restore TOKEN"); 821 System.err.println(" bmgr restore TOKEN PACKAGE..."); 822 System.err.println(" bmgr restore PACKAGE"); 823 System.err.println(" bmgr run"); 824 System.err.println(" bmgr wipe TRANSPORT PACKAGE"); 825 System.err.println(" bmgr fullbackup PACKAGE..."); 826 System.err.println(" bmgr backupnow --all|PACKAGE..."); 827 System.err.println(" bmgr cancel backups"); 828 System.err.println(""); 829 System.err.println("The 'backup' command schedules a backup pass for the named package."); 830 System.err.println("Note that the backup pass will effectively be a no-op if the package"); 831 System.err.println("does not actually have changed data to store."); 832 System.err.println(""); 833 System.err.println("The 'enable' command enables or disables the entire backup mechanism."); 834 System.err.println("If the argument is 'true' it will be enabled, otherwise it will be"); 835 System.err.println("disabled. When disabled, neither backup or restore operations will"); 836 System.err.println("be performed."); 837 System.err.println(""); 838 System.err.println("The 'enabled' command reports the current enabled/disabled state of"); 839 System.err.println("the backup mechanism."); 840 System.err.println(""); 841 System.err.println("The 'list transports' command reports the names of the backup transports"); 842 System.err.println("BackupManager is currently bound to. These names can be passed as arguments"); 843 System.err.println("to the 'transport' and 'wipe' commands. The currently active transport"); 844 System.err.println("is indicated with a '*' character. If -c flag is used, all available"); 845 System.err.println("transport components on the device are listed. These can be used with"); 846 System.err.println("the component variant of 'transport' command."); 847 System.err.println(""); 848 System.err.println("The 'list sets' command reports the token and name of each restore set"); 849 System.err.println("available to the device via the currently active transport."); 850 System.err.println(""); 851 System.err.println("The 'transport' command designates the named transport as the currently"); 852 System.err.println("active one. This setting is persistent across reboots. If -c flag is"); 853 System.err.println("specified, the following string is treated as a component name."); 854 System.err.println(""); 855 System.err.println("The 'restore' command when given just a restore token initiates a full-system"); 856 System.err.println("restore operation from the currently active transport. It will deliver"); 857 System.err.println("the restore set designated by the TOKEN argument to each application"); 858 System.err.println("that had contributed data to that restore set."); 859 System.err.println(""); 860 System.err.println("The 'restore' command when given a token and one or more package names"); 861 System.err.println("initiates a restore operation of just those given packages from the restore"); 862 System.err.println("set designated by the TOKEN argument. It is effectively the same as the"); 863 System.err.println("'restore' operation supplying only a token, but applies a filter to the"); 864 System.err.println("set of applications to be restored."); 865 System.err.println(""); 866 System.err.println("The 'restore' command when given just a package name intiates a restore of"); 867 System.err.println("just that one package according to the restore set selection algorithm"); 868 System.err.println("used by the RestoreSession.restorePackage() method."); 869 System.err.println(""); 870 System.err.println("The 'run' command causes any scheduled backup operation to be initiated"); 871 System.err.println("immediately, without the usual waiting period for batching together"); 872 System.err.println("data changes."); 873 System.err.println(""); 874 System.err.println("The 'wipe' command causes all backed-up data for the given package to be"); 875 System.err.println("erased from the given transport's storage. The next backup operation"); 876 System.err.println("that the given application performs will rewrite its entire data set."); 877 System.err.println("Transport names to use here are those reported by 'list transports'."); 878 System.err.println(""); 879 System.err.println("The 'fullbackup' command induces a full-data stream backup for one or more"); 880 System.err.println("packages. The data is sent via the currently active transport."); 881 System.err.println(""); 882 System.err.println("The 'backupnow' command runs an immediate backup for one or more packages."); 883 System.err.println(" --all flag runs backup for all eligible packages."); 884 System.err.println("For each package it will run key/value or full data backup "); 885 System.err.println("depending on the package's manifest declarations."); 886 System.err.println("The data is sent via the currently active transport."); 887 System.err.println("The 'cancel backups' command cancels all running backups."); 888 } 889} 890