OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / cmds / bmgr / src / com / android / commands / bmgr / Bmgr.java
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
17 package com.android.commands.bmgr;
18
19 import android.app.backup.RestoreSet;
20 import android.app.backup.IBackupManager;
21 import android.app.backup.IRestoreObserver;
22 import android.app.backup.IRestoreSession;
23 import android.os.RemoteException;
24 import android.os.ServiceManager;
25
26 public 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
38     public static void main(String[] args) {
39         try {
40             new Bmgr().run(args);
41         } catch (Exception e) {
42             System.err.println("Exception caught:");
43             e.printStackTrace();
44         }
45     }
46
47     public void run(String[] args) {
48         boolean validCommand = false;
49         if (args.length < 1) {
50             showUsage();
51             return;
52         }
53
54         mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup"));
55         if (mBmgr == null) {
56             System.err.println(BMGR_NOT_RUNNING_ERR);
57             return;
58         }
59
60         mArgs = args;
61         String op = args[0];
62         mNextArg = 1;
63
64         if ("enabled".equals(op)) {
65             doEnabled();
66             return;
67         }
68
69         if ("enable".equals(op)) {
70             doEnable();
71             return;
72         }
73
74         if ("run".equals(op)) {
75             doRun();
76             return;
77         }
78
79         if ("backup".equals(op)) {
80             doBackup();
81             return;
82         }
83
84         if ("list".equals(op)) {
85             doList();
86             return;
87         }
88
89         if ("restore".equals(op)) {
90             doRestore();
91             return;
92         }
93
94         if ("transport".equals(op)) {
95             doTransport();
96             return;
97         }
98
99         if ("wipe".equals(op)) {
100             doWipe();
101             return;
102         }
103
104         System.err.println("Unknown command");
105         showUsage();
106     }
107
108     private String enableToString(boolean enabled) {
109         return enabled ? "enabled" : "disabled";
110     }
111
112     private void doEnabled() {
113         try {
114             boolean isEnabled = mBmgr.isBackupEnabled();
115             System.out.println("Backup Manager currently "
116                     + enableToString(isEnabled));
117         } catch (RemoteException e) {
118             System.err.println(e.toString());
119             System.err.println(BMGR_NOT_RUNNING_ERR);
120         }
121     }
122
123     private void doEnable() {
124         String arg = nextArg();
125         if (arg == null) {
126             showUsage();
127             return;
128         }
129
130         try {
131             boolean enable = Boolean.parseBoolean(arg);
132             mBmgr.setBackupEnabled(enable);
133             System.out.println("Backup Manager now " + enableToString(enable));
134         } catch (NumberFormatException e) {
135             showUsage();
136             return;
137         } catch (RemoteException e) {
138             System.err.println(e.toString());
139             System.err.println(BMGR_NOT_RUNNING_ERR);
140         }
141     }
142
143     private void doRun() {
144         try {
145             mBmgr.backupNow();
146         } catch (RemoteException e) {
147             System.err.println(e.toString());
148             System.err.println(BMGR_NOT_RUNNING_ERR);
149         }
150     }
151
152     private void doBackup() {
153         boolean isFull = false;
154         String pkg = nextArg();
155         if ("-f".equals(pkg)) {
156             isFull = true;
157             pkg = nextArg();
158         }
159
160         if (pkg == null || pkg.startsWith("-")) {
161             showUsage();
162             return;
163         }
164
165         try {
166             // !!! TODO: handle full backup
167             mBmgr.dataChanged(pkg);
168         } catch (RemoteException e) {
169             System.err.println(e.toString());
170             System.err.println(BMGR_NOT_RUNNING_ERR);
171         }
172     }
173
174     private void doTransport() {
175         try {
176             String which = nextArg();
177             if (which == null) {
178                 showUsage();
179                 return;
180             }
181
182             String old = mBmgr.selectBackupTransport(which);
183             if (old == null) {
184                 System.out.println("Unknown transport '" + which
185                         + "' specified; no changes made.");
186             } else {
187                 System.out.println("Selected transport " + which + " (formerly " + old + ")");
188             }
189         } catch (RemoteException e) {
190             System.err.println(e.toString());
191             System.err.println(BMGR_NOT_RUNNING_ERR);
192         }
193     }
194
195     private void doWipe() {
196         String pkg = nextArg();
197         if (pkg == null) {
198             showUsage();
199             return;
200         }
201
202         try {
203             mBmgr.clearBackupData(pkg);
204             System.out.println("Wiped backup data for " + pkg);
205         } catch (RemoteException e) {
206             System.err.println(e.toString());
207             System.err.println(BMGR_NOT_RUNNING_ERR);
208         }
209     }
210
211     private void doList() {
212         String arg = nextArg();     // sets, transports, packages set#
213         if ("transports".equals(arg)) {
214             doListTransports();
215             return;
216         }
217
218         // The rest of the 'list' options work with a restore session on the current transport
219         try {
220             mRestore = mBmgr.beginRestoreSession(null, null);
221             if (mRestore == null) {
222                 System.err.println(BMGR_NOT_RUNNING_ERR);
223                 return;
224             }
225
226             if ("sets".equals(arg)) {
227                 doListRestoreSets();
228             } else if ("transports".equals(arg)) {
229                 doListTransports();
230             }
231
232             mRestore.endRestoreSession();
233         } catch (RemoteException e) {
234             System.err.println(e.toString());
235             System.err.println(BMGR_NOT_RUNNING_ERR);
236         }
237     }
238
239     private void doListTransports() {
240         try {
241             String current = mBmgr.getCurrentTransport();
242             String[] transports = mBmgr.listAllTransports();
243             if (transports == null || transports.length == 0) {
244                 System.out.println("No transports available.");
245                 return;
246             }
247
248             for (String t : transports) {
249                 String pad = (t.equals(current)) ? "  * " : "    ";
250                 System.out.println(pad + t);
251             }
252         } catch (RemoteException e) {
253             System.err.println(e.toString());
254             System.err.println(BMGR_NOT_RUNNING_ERR);
255         }
256     }
257
258     private void doListRestoreSets() {
259         try {
260             RestoreObserver observer = new RestoreObserver();
261             int err = mRestore.getAvailableRestoreSets(observer);
262             if (err != 0) {
263                 System.out.println("Unable to request restore sets");
264             } else {
265                 observer.waitForCompletion();
266                 printRestoreSets(observer.sets);
267             }
268         } catch (RemoteException e) {
269             System.err.println(e.toString());
270             System.err.println(TRANSPORT_NOT_RUNNING_ERR);
271         }
272     }
273
274     private void printRestoreSets(RestoreSet[] sets) {
275         if (sets == null || sets.length == 0) {
276             System.out.println("No restore sets");
277             return;
278         }
279         for (RestoreSet s : sets) {
280             System.out.println("  " + Long.toHexString(s.token) + " : " + s.name);
281         }
282     }
283
284     class RestoreObserver extends IRestoreObserver.Stub {
285         boolean done;
286         RestoreSet[] sets = null;
287
288         public void restoreSetsAvailable(RestoreSet[] result) {
289             synchronized (this) {
290                 sets = result;
291                 done = true;
292                 this.notify();
293             }
294         }
295
296         public void restoreStarting(int numPackages) {
297             System.out.println("restoreStarting: " + numPackages + " packages");
298         }
299
300         public void onUpdate(int nowBeingRestored, String currentPackage) {
301             System.out.println("onUpdate: " + nowBeingRestored + " = " + currentPackage);
302         }
303
304         public void restoreFinished(int error) {
305             System.out.println("restoreFinished: " + error);
306             synchronized (this) {
307                 done = true;
308                 this.notify();
309             }
310         }
311
312         public void waitForCompletion() {
313             // The restoreFinished() callback will throw the 'done' flag; we
314             // just sit and wait on that notification.
315             synchronized (this) {
316                 while (!this.done) {
317                     try {
318                         this.wait();
319                     } catch (InterruptedException ex) {
320                     }
321                 }
322             }
323         }
324     }
325
326     private void doRestore() {
327         String arg = nextArg();
328         if (arg == null) {
329             showUsage();
330             return;
331         }
332
333         if (arg.indexOf('.') >= 0) {
334             // it's a package name
335             doRestorePackage(arg);
336         } else {
337             try {
338                 long token = Long.parseLong(arg, 16);
339                 doRestoreAll(token);
340             } catch (NumberFormatException e) {
341                 showUsage();
342                 return;
343             }
344         }
345
346         System.out.println("done");
347     }
348
349     private void doRestorePackage(String pkg) {
350         try {
351             mRestore = mBmgr.beginRestoreSession(pkg, null);
352             if (mRestore == null) {
353                 System.err.println(BMGR_NOT_RUNNING_ERR);
354                 return;
355             }
356
357             RestoreObserver observer = new RestoreObserver();
358             int err = mRestore.restorePackage(pkg, observer);
359             if (err == 0) {
360                 // Off and running -- wait for the restore to complete
361                 observer.waitForCompletion();
362             } else {
363                 System.err.println("Unable to restore package " + pkg);
364             }
365
366             // And finally shut down the session
367             mRestore.endRestoreSession();
368         } catch (RemoteException e) {
369             System.err.println(e.toString());
370             System.err.println(BMGR_NOT_RUNNING_ERR);
371         }
372     }
373
374     private void doRestoreAll(long token) {
375         RestoreObserver observer = new RestoreObserver();
376
377         try {
378             boolean didRestore = false;
379             mRestore = mBmgr.beginRestoreSession(null, null);
380             if (mRestore == null) {
381                 System.err.println(BMGR_NOT_RUNNING_ERR);
382                 return;
383             }
384             RestoreSet[] sets = null;
385             int err = mRestore.getAvailableRestoreSets(observer);
386             if (err == 0) {
387                 observer.waitForCompletion();
388                 sets = observer.sets;
389                 for (RestoreSet s : sets) {
390                     if (s.token == token) {
391                         System.out.println("Scheduling restore: " + s.name);
392                         didRestore = (mRestore.restoreAll(token, observer) == 0);
393                         break;
394                     }
395                 }
396             }
397             if (!didRestore) {
398                 if (sets == null || sets.length == 0) {
399                     System.out.println("No available restore sets; no restore performed");
400                 } else {
401                     System.out.println("No matching restore set token.  Available sets:");
402                     printRestoreSets(sets);
403                 }
404             }
405
406             // if we kicked off a restore successfully, we have to wait for it
407             // to complete before we can shut down the restore session safely
408             if (didRestore) {
409                 observer.waitForCompletion();
410             }
411
412             // once the restore has finished, close down the session and we're done
413             mRestore.endRestoreSession();
414         } catch (RemoteException e) {
415             System.err.println(e.toString());
416             System.err.println(BMGR_NOT_RUNNING_ERR);
417         }
418     }
419
420     private String nextArg() {
421         if (mNextArg >= mArgs.length) {
422             return null;
423         }
424         String arg = mArgs[mNextArg];
425         mNextArg++;
426         return arg;
427     }
428
429     private static void showUsage() {
430         System.err.println("usage: bmgr [backup|restore|list|transport|run]");
431         System.err.println("       bmgr backup PACKAGE");
432         System.err.println("       bmgr enable BOOL");
433         System.err.println("       bmgr enabled");
434         System.err.println("       bmgr list transports");
435         System.err.println("       bmgr list sets");
436         System.err.println("       bmgr transport WHICH");
437         System.err.println("       bmgr restore TOKEN");
438         System.err.println("       bmgr restore PACKAGE");
439         System.err.println("       bmgr run");
440         System.err.println("       bmgr wipe PACKAGE");
441         System.err.println("");
442         System.err.println("The 'backup' command schedules a backup pass for the named package.");
443         System.err.println("Note that the backup pass will effectively be a no-op if the package");
444         System.err.println("does not actually have changed data to store.");
445         System.err.println("");
446         System.err.println("The 'enable' command enables or disables the entire backup mechanism.");
447         System.err.println("If the argument is 'true' it will be enabled, otherwise it will be");
448         System.err.println("disabled.  When disabled, neither backup or restore operations will");
449         System.err.println("be performed.");
450         System.err.println("");
451         System.err.println("The 'enabled' command reports the current enabled/disabled state of");
452         System.err.println("the backup mechanism.");
453         System.err.println("");
454         System.err.println("The 'list transports' command reports the names of the backup transports");
455         System.err.println("currently available on the device.  These names can be passed as arguments");
456         System.err.println("to the 'transport' command.  The currently selected transport is indicated");
457         System.err.println("with a '*' character.");
458         System.err.println("");
459         System.err.println("The 'list sets' command reports the token and name of each restore set");
460         System.err.println("available to the device via the current transport.");
461         System.err.println("");
462         System.err.println("The 'transport' command designates the named transport as the currently");
463         System.err.println("active one.  This setting is persistent across reboots.");
464         System.err.println("");
465         System.err.println("The 'restore' command when given a restore token initiates a full-system");
466         System.err.println("restore operation from the currently active transport.  It will deliver");
467         System.err.println("the restore set designated by the TOKEN argument to each application");
468         System.err.println("that had contributed data to that restore set.");
469         System.err.println("");
470         System.err.println("The 'restore' command when given a package name intiates a restore of");
471         System.err.println("just that one package according to the restore set selection algorithm");
472         System.err.println("used by the RestoreSession.restorePackage() method.");
473         System.err.println("");
474         System.err.println("The 'run' command causes any scheduled backup operation to be initiated");
475         System.err.println("immediately, without the usual waiting period for batching together");
476         System.err.println("data changes.");
477         System.err.println("");
478         System.err.println("The 'wipe' command causes all backed-up data for the given package to be");
479         System.err.println("erased from the current transport's storage.  The next backup operation");
480         System.err.println("that the given application performs will rewrite its entire data set.");
481     }
482 }