Bmgr.java revision 6ef58a1509b9d3348a33ca5686917796c2759aa5
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.backup.IBackupManager; 20import android.backup.IRestoreObserver; 21import android.backup.IRestoreSession; 22import android.backup.RestoreSet; 23import android.os.RemoteException; 24import android.os.ServiceManager; 25 26public final class Bmgr { 27 IBackupManager mBmgr; 28 IRestoreSession mRestore; 29 30 static final String BMGR_NOT_RUNNING_ERR = 31 "Error: Could not access the Backup Manager. Is the system running?"; 32 static final String TRANSPORT_NOT_RUNNING_ERR = 33 "Error: Could not access the backup transport. Is the system running?"; 34 35 private String[] mArgs; 36 private int mNextArg; 37 private String mCurArgData; 38 39 public static void main(String[] args) { 40 try { 41 new Bmgr().run(args); 42 } catch (Exception e) { 43 System.err.println("Exception caught:"); 44 e.printStackTrace(); 45 } 46 } 47 48 public void run(String[] args) { 49 boolean validCommand = false; 50 if (args.length < 1) { 51 showUsage(); 52 return; 53 } 54 55 mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); 56 if (mBmgr == null) { 57 System.err.println(BMGR_NOT_RUNNING_ERR); 58 return; 59 } 60 61 mArgs = args; 62 String op = args[0]; 63 mNextArg = 1; 64 65 if ("enabled".equals(op)) { 66 doEnabled(); 67 return; 68 } 69 70 if ("enable".equals(op)) { 71 doEnable(); 72 return; 73 } 74 75 if ("run".equals(op)) { 76 doRun(); 77 return; 78 } 79 80 if ("backup".equals(op)) { 81 doBackup(); 82 return; 83 } 84 85 if ("list".equals(op)) { 86 doList(); 87 return; 88 } 89 90 if ("restore".equals(op)) { 91 doRestore(); 92 return; 93 } 94 95 if ("transport".equals(op)) { 96 doTransport(); 97 return; 98 } 99 100 System.err.println("Unknown command"); 101 showUsage(); 102 } 103 104 private String enableToString(boolean enabled) { 105 return enabled ? "enabled" : "disabled"; 106 } 107 108 private void doEnabled() { 109 try { 110 boolean isEnabled = mBmgr.isBackupEnabled(); 111 System.out.println("Backup Manager currently " 112 + enableToString(isEnabled)); 113 } catch (RemoteException e) { 114 System.err.println(e.toString()); 115 System.err.println(BMGR_NOT_RUNNING_ERR); 116 } 117 } 118 119 private void doEnable() { 120 String arg = nextArg(); 121 if (arg == null) { 122 showUsage(); 123 return; 124 } 125 126 try { 127 boolean enable = Boolean.parseBoolean(arg); 128 mBmgr.setBackupEnabled(enable); 129 System.out.println("Backup Manager now " + enableToString(enable)); 130 } catch (NumberFormatException e) { 131 showUsage(); 132 return; 133 } catch (RemoteException e) { 134 System.err.println(e.toString()); 135 System.err.println(BMGR_NOT_RUNNING_ERR); 136 } 137 } 138 139 private void doRun() { 140 try { 141 mBmgr.backupNow(); 142 } catch (RemoteException e) { 143 System.err.println(e.toString()); 144 System.err.println(BMGR_NOT_RUNNING_ERR); 145 } 146 } 147 148 private void doBackup() { 149 boolean isFull = false; 150 String pkg = nextArg(); 151 if ("-f".equals(pkg)) { 152 isFull = true; 153 pkg = nextArg(); 154 } 155 156 if (pkg == null || pkg.startsWith("-")) { 157 showUsage(); 158 return; 159 } 160 161 try { 162 // !!! TODO: handle full backup 163 mBmgr.dataChanged(pkg); 164 } catch (RemoteException e) { 165 System.err.println(e.toString()); 166 System.err.println(BMGR_NOT_RUNNING_ERR); 167 } 168 } 169 170 private void doTransport() { 171 try { 172 String which = nextArg(); 173 String old = mBmgr.selectBackupTransport(which); 174 if (old == null) { 175 System.out.println("Unknown transport '" + which 176 + "' specified; no changes made."); 177 } else { 178 System.out.println("Selected transport " + which + " (formerly " + old + ")"); 179 } 180 } catch (RemoteException e) { 181 System.err.println(e.toString()); 182 System.err.println(BMGR_NOT_RUNNING_ERR); 183 } 184 } 185 186 private void doList() { 187 String arg = nextArg(); // sets, transports, packages set# 188 if ("transports".equals(arg)) { 189 doListTransports(); 190 return; 191 } 192 193 // The rest of the 'list' options work with a restore session on the current transport 194 try { 195 String curTransport = mBmgr.getCurrentTransport(); 196 mRestore = mBmgr.beginRestoreSession(curTransport); 197 if (mRestore == null) { 198 System.err.println(BMGR_NOT_RUNNING_ERR); 199 return; 200 } 201 202 if ("sets".equals(arg)) { 203 doListRestoreSets(); 204 } else if ("transports".equals(arg)) { 205 doListTransports(); 206 } 207 208 mRestore.endRestoreSession(); 209 } catch (RemoteException e) { 210 System.err.println(e.toString()); 211 System.err.println(BMGR_NOT_RUNNING_ERR); 212 } 213 } 214 215 private void doListTransports() { 216 try { 217 String current = mBmgr.getCurrentTransport(); 218 String[] transports = mBmgr.listAllTransports(); 219 if (transports == null || transports.length == 0) { 220 System.out.println("No transports available."); 221 return; 222 } 223 224 for (String t : transports) { 225 String pad = (t.equals(current)) ? " * " : " "; 226 System.out.println(pad + t); 227 } 228 } catch (RemoteException e) { 229 System.err.println(e.toString()); 230 System.err.println(BMGR_NOT_RUNNING_ERR); 231 } 232 } 233 234 private void doListRestoreSets() { 235 try { 236 RestoreSet[] sets = mRestore.getAvailableRestoreSets(); 237 if (sets == null || sets.length == 0) { 238 System.out.println("No restore sets available"); 239 } else { 240 printRestoreSets(sets); 241 } 242 } catch (RemoteException e) { 243 System.err.println(e.toString()); 244 System.err.println(TRANSPORT_NOT_RUNNING_ERR); 245 } 246 } 247 248 private void printRestoreSets(RestoreSet[] sets) { 249 for (RestoreSet s : sets) { 250 System.out.println(" " + s.token + " : " + s.name); 251 } 252 } 253 254 class RestoreObserver extends IRestoreObserver.Stub { 255 boolean done; 256 public void restoreStarting(int numPackages) { 257 System.out.println("restoreStarting: " + numPackages + " packages"); 258 } 259 260 public void onUpdate(int nowBeingRestored) { 261 System.out.println("onUpdate: " + nowBeingRestored); 262 } 263 264 public void restoreFinished(int error) { 265 System.out.println("restoreFinished: " + error); 266 synchronized (this) { 267 done = true; 268 this.notify(); 269 } 270 } 271 } 272 273 private void doRestore() { 274 long token; 275 try { 276 token = Long.parseLong(nextArg()); 277 } catch (NumberFormatException e) { 278 showUsage(); 279 return; 280 } 281 282 RestoreObserver observer = new RestoreObserver(); 283 284 try { 285 boolean didRestore = false; 286 String curTransport = mBmgr.getCurrentTransport(); 287 mRestore = mBmgr.beginRestoreSession(curTransport); 288 if (mRestore == null) { 289 System.err.println(BMGR_NOT_RUNNING_ERR); 290 return; 291 } 292 RestoreSet[] sets = mRestore.getAvailableRestoreSets(); 293 for (RestoreSet s : sets) { 294 if (s.token == token) { 295 System.out.println("Scheduling restore: " + s.name); 296 mRestore.performRestore(token, observer); 297 didRestore = true; 298 break; 299 } 300 } 301 if (!didRestore) { 302 if (sets == null || sets.length == 0) { 303 System.out.println("No available restore sets; no restore performed"); 304 } else { 305 System.out.println("No matching restore set token. Available sets:"); 306 printRestoreSets(sets); 307 } 308 } 309 mRestore.endRestoreSession(); 310 } catch (RemoteException e) { 311 System.err.println(e.toString()); 312 System.err.println(BMGR_NOT_RUNNING_ERR); 313 } 314 315 // now wait for it to be done 316 synchronized (observer) { 317 while (!observer.done) { 318 try { 319 observer.wait(); 320 } catch (InterruptedException ex) { 321 } 322 } 323 } 324 System.out.println("done"); 325 } 326 327 private String nextArg() { 328 if (mNextArg >= mArgs.length) { 329 return null; 330 } 331 String arg = mArgs[mNextArg]; 332 mNextArg++; 333 return arg; 334 } 335 336 private static void showUsage() { 337 System.err.println("usage: bmgr [backup|restore|list|transport|run]"); 338 System.err.println(" bmgr backup PACKAGE"); 339 System.err.println(" bmgr enable BOOL"); 340 System.err.println(" bmgr enabled"); 341 System.err.println(" bmgr list transports"); 342 System.err.println(" bmgr list sets"); 343 System.err.println(" bmgr transport WHICH"); 344 System.err.println(" bmgr restore TOKEN"); 345 System.err.println(" bmgr run"); 346 System.err.println(""); 347 System.err.println("The 'backup' command schedules a backup pass for the named package."); 348 System.err.println("Note that the backup pass will effectively be a no-op if the package"); 349 System.err.println("does not actually have changed data to store."); 350 System.err.println(""); 351 System.err.println("The 'enable' command enables or disables the entire backup mechanism."); 352 System.err.println("If the argument is 'true' it will be enabled, otherwise it will be"); 353 System.err.println("disabled. When disabled, neither backup or restore operations will"); 354 System.err.println("be performed."); 355 System.err.println(""); 356 System.err.println("The 'enabled' command reports the current enabled/disabled state of"); 357 System.err.println("the backup mechanism."); 358 System.err.println(""); 359 System.err.println("The 'list transports' command reports the names of the backup transports"); 360 System.err.println("currently available on the device. These names can be passed as arguments"); 361 System.err.println("to the 'transport' command. The currently selected transport is indicated"); 362 System.err.println("with a '*' character."); 363 System.err.println(""); 364 System.err.println("The 'list sets' command reports the token and name of each restore set"); 365 System.err.println("available to the device via the current transport."); 366 System.err.println(""); 367 System.err.println("The 'transport' command designates the named transport as the currently"); 368 System.err.println("active one. This setting is persistent across reboots."); 369 System.err.println(""); 370 System.err.println("The 'restore' command initiates a restore operation, using the restore set"); 371 System.err.println("from the current transport whose token matches the argument."); 372 System.err.println(""); 373 System.err.println("The 'run' command causes any scheduled backup operation to be initiated"); 374 System.err.println("immediately, without the usual waiting period for batching together"); 375 System.err.println("data changes."); 376 } 377} 378