1 /*
2  * Copyright (C) 2011 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.bu;
18 
19 import android.app.backup.IBackupManager;
20 import android.os.ParcelFileDescriptor;
21 import android.os.RemoteException;
22 import android.os.ServiceManager;
23 import android.system.OsConstants;
24 import android.util.Log;
25 
26 import java.io.IOException;
27 import java.util.ArrayList;
28 
29 public final class Backup {
30     static final String TAG = "bu";
31 
32     static String[] mArgs;
33     int mNextArg;
34     IBackupManager mBackupManager;
35 
main(String[] args)36     public static void main(String[] args) {
37         Log.d(TAG, "Beginning: " + args[0]);
38         mArgs = args;
39         try {
40             new Backup().run();
41         } catch (Exception e) {
42             Log.e(TAG, "Error running backup/restore", e);
43         }
44         Log.d(TAG, "Finished.");
45     }
46 
run()47     public void run() {
48         mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup"));
49         if (mBackupManager == null) {
50             Log.e(TAG, "Can't obtain Backup Manager binder");
51             return;
52         }
53 
54         String arg = nextArg();
55         if (arg.equals("backup")) {
56             doFullBackup(OsConstants.STDOUT_FILENO);
57         } else if (arg.equals("restore")) {
58             doFullRestore(OsConstants.STDIN_FILENO);
59         } else {
60             Log.e(TAG, "Invalid operation '" + arg + "'");
61         }
62     }
63 
doFullBackup(int socketFd)64     private void doFullBackup(int socketFd) {
65         ArrayList<String> packages = new ArrayList<String>();
66         boolean saveApks = false;
67         boolean saveObbs = false;
68         boolean saveShared = false;
69         boolean doEverything = false;
70         boolean doWidgets = false;
71         boolean allIncludesSystem = true;
72         boolean doCompress = true;
73 
74         String arg;
75         while ((arg = nextArg()) != null) {
76             if (arg.startsWith("-")) {
77                 if ("-apk".equals(arg)) {
78                     saveApks = true;
79                 } else if ("-noapk".equals(arg)) {
80                     saveApks = false;
81                 } else if ("-obb".equals(arg)) {
82                     saveObbs = true;
83                 } else if ("-noobb".equals(arg)) {
84                     saveObbs = false;
85                 } else if ("-shared".equals(arg)) {
86                     saveShared = true;
87                 } else if ("-noshared".equals(arg)) {
88                     saveShared = false;
89                 } else if ("-system".equals(arg)) {
90                     allIncludesSystem = true;
91                 } else if ("-nosystem".equals(arg)) {
92                     allIncludesSystem = false;
93                 } else if ("-widgets".equals(arg)) {
94                     doWidgets = true;
95                 } else if ("-nowidgets".equals(arg)) {
96                     doWidgets = false;
97                 } else if ("-all".equals(arg)) {
98                     doEverything = true;
99                 } else if ("-compress".equals(arg)) {
100                     doCompress = true;
101                 } else if ("-nocompress".equals(arg)) {
102                     doCompress = false;
103                 } else {
104                     Log.w(TAG, "Unknown backup flag " + arg);
105                     continue;
106                 }
107             } else {
108                 // Not a flag; treat as a package name
109                 packages.add(arg);
110             }
111         }
112 
113         if (doEverything && packages.size() > 0) {
114             Log.w(TAG, "-all passed for backup along with specific package names");
115         }
116 
117         if (!doEverything && !saveShared && packages.size() == 0) {
118             Log.e(TAG, "no backup packages supplied and neither -shared nor -all given");
119             return;
120         }
121 
122         ParcelFileDescriptor fd = null;
123         try {
124             fd = ParcelFileDescriptor.adoptFd(socketFd);
125             String[] packArray = new String[packages.size()];
126             mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doWidgets,
127                     doEverything, allIncludesSystem, doCompress, packages.toArray(packArray));
128         } catch (RemoteException e) {
129             Log.e(TAG, "Unable to invoke backup manager for backup");
130         } finally {
131             if (fd != null) {
132                 try {
133                     fd.close();
134                 } catch (IOException e) {}
135             }
136         }
137     }
138 
doFullRestore(int socketFd)139     private void doFullRestore(int socketFd) {
140         // No arguments to restore
141         ParcelFileDescriptor fd = null;
142         try {
143             fd = ParcelFileDescriptor.adoptFd(socketFd);
144             mBackupManager.fullRestore(fd);
145         } catch (RemoteException e) {
146             Log.e(TAG, "Unable to invoke backup manager for restore");
147         } finally {
148             if (fd != null) {
149                 try {
150                     fd.close();
151                 } catch (IOException e) {}
152             }
153         }
154     }
155 
nextArg()156     private String nextArg() {
157         if (mNextArg >= mArgs.length) {
158             return null;
159         }
160         String arg = mArgs[mNextArg];
161         mNextArg++;
162         return arg;
163     }
164 }