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 17package com.android.commands.bu; 18 19import android.app.backup.IBackupManager; 20import android.os.ParcelFileDescriptor; 21import android.os.RemoteException; 22import android.os.ServiceManager; 23import android.system.OsConstants; 24import android.util.Log; 25 26import java.io.IOException; 27import java.util.ArrayList; 28 29public final class Backup { 30 static final String TAG = "bu"; 31 32 static String[] mArgs; 33 int mNextArg; 34 IBackupManager mBackupManager; 35 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 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 doBackup(OsConstants.STDOUT_FILENO); 57 } else if (arg.equals("restore")) { 58 doRestore(OsConstants.STDIN_FILENO); 59 } else { 60 showUsage(); 61 } 62 } 63 64 private void doBackup(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 boolean doKeyValue = false; 74 75 String arg; 76 while ((arg = nextArg()) != null) { 77 if (arg.startsWith("-")) { 78 if ("-apk".equals(arg)) { 79 saveApks = true; 80 } else if ("-noapk".equals(arg)) { 81 saveApks = false; 82 } else if ("-obb".equals(arg)) { 83 saveObbs = true; 84 } else if ("-noobb".equals(arg)) { 85 saveObbs = false; 86 } else if ("-shared".equals(arg)) { 87 saveShared = true; 88 } else if ("-noshared".equals(arg)) { 89 saveShared = false; 90 } else if ("-system".equals(arg)) { 91 allIncludesSystem = true; 92 } else if ("-nosystem".equals(arg)) { 93 allIncludesSystem = false; 94 } else if ("-widgets".equals(arg)) { 95 doWidgets = true; 96 } else if ("-nowidgets".equals(arg)) { 97 doWidgets = false; 98 } else if ("-all".equals(arg)) { 99 doEverything = true; 100 } else if ("-compress".equals(arg)) { 101 doCompress = true; 102 } else if ("-nocompress".equals(arg)) { 103 doCompress = false; 104 } else if ("-keyvalue".equals(arg)) { 105 doKeyValue = true; 106 } else if ("-nokeyvalue".equals(arg)) { 107 doKeyValue = false; 108 } else { 109 Log.w(TAG, "Unknown backup flag " + arg); 110 continue; 111 } 112 } else { 113 // Not a flag; treat as a package name 114 packages.add(arg); 115 } 116 } 117 118 if (doEverything && packages.size() > 0) { 119 Log.w(TAG, "-all passed for backup along with specific package names"); 120 } 121 122 if (!doEverything && !saveShared && packages.size() == 0) { 123 Log.e(TAG, "no backup packages supplied and neither -shared nor -all given"); 124 return; 125 } 126 127 ParcelFileDescriptor fd = null; 128 try { 129 fd = ParcelFileDescriptor.adoptFd(socketFd); 130 String[] packArray = new String[packages.size()]; 131 mBackupManager.adbBackup(fd, saveApks, saveObbs, saveShared, doWidgets, doEverything, 132 allIncludesSystem, doCompress, doKeyValue, packages.toArray(packArray)); 133 } catch (RemoteException e) { 134 Log.e(TAG, "Unable to invoke backup manager for backup"); 135 } finally { 136 if (fd != null) { 137 try { 138 fd.close(); 139 } catch (IOException e) { 140 Log.e(TAG, "IO error closing output for backup: " + e.getMessage()); 141 } 142 } 143 } 144 } 145 146 private void doRestore(int socketFd) { 147 // No arguments to restore 148 ParcelFileDescriptor fd = null; 149 try { 150 fd = ParcelFileDescriptor.adoptFd(socketFd); 151 mBackupManager.adbRestore(fd); 152 } catch (RemoteException e) { 153 Log.e(TAG, "Unable to invoke backup manager for restore"); 154 } finally { 155 if (fd != null) { 156 try { 157 fd.close(); 158 } catch (IOException e) {} 159 } 160 } 161 } 162 163 private static void showUsage() { 164 System.err.println(" backup [-f FILE] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all]"); 165 System.err.println(" [-system|-nosystem] [-keyvalue|-nokeyvalue] [PACKAGE...]"); 166 System.err.println(" write an archive of the device's data to FILE [default=backup.adb]"); 167 System.err.println(" package list optional if -all/-shared are supplied"); 168 System.err.println(" -apk/-noapk: do/don't back up .apk files (default -noapk)"); 169 System.err.println(" -obb/-noobb: do/don't back up .obb files (default -noobb)"); 170 System.err.println(" -shared|-noshared: do/don't back up shared storage (default -noshared)"); 171 System.err.println(" -all: back up all installed applications"); 172 System.err.println(" -system|-nosystem: include system apps in -all (default -system)"); 173 System.err.println(" -keyvalue|-nokeyvalue: include apps that perform key/value backups."); 174 System.err.println(" (default -nokeyvalue)"); 175 System.err.println(" restore FILE restore device contents from FILE"); 176 } 177 178 private String nextArg() { 179 if (mNextArg >= mArgs.length) { 180 return null; 181 } 182 String arg = mArgs[mNextArg]; 183 mNextArg++; 184 return arg; 185 } 186}