diff options
author | Ruslan Tkhakokhov <rthakohov@google.com> | 2018-12-03 17:28:39 +0000 |
---|---|---|
committer | Ruslan Tkhakokhov <rthakohov@google.com> | 2018-12-17 16:48:13 +0000 |
commit | a2fe6c5bb914bb3374a13d7c718614dd98698b71 (patch) | |
tree | b9151fb44e4b8d3df789158e9c590bdcadded722 /cmds/bu/src | |
parent | 1982ca78e30ae156d77d8a3216593f6272fc0ec9 (diff) |
[Multi-user] Add -user param to adb backup/restore
Add an optional parameter -user to provide ID of the user for which to
run backup/restore operation. Add robolectric test to verify the
new parameter is proccessed correctly.
Bug: 119908153
Test: 1) atest BackupTest
2) atest BackupManagerServiceTest
3) atest TrampolineTest
4) atest GtsBackupTestCases
5) atest GtsBackupHostTestCases
6) Manual:
- Run "adb backup -all" and verify that backup is successfull
- Run "adb restore" and verify that restore is successfull
- Run "adb backup -all -user 10" and verify that backup faield as
it's only currently supported for system user
- Run "adb restore -user 10" and verify that restore failed as it's
only currently supported for system user
Change-Id: I6dbf9c87eedd5a72da0446beff7d2551f98f2654
Diffstat (limited to 'cmds/bu/src')
-rw-r--r-- | cmds/bu/src/com/android/commands/bu/Backup.java | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java index 834658da8ccc..373677eccf62 100644 --- a/cmds/bu/src/com/android/commands/bu/Backup.java +++ b/cmds/bu/src/com/android/commands/bu/Backup.java @@ -16,13 +16,17 @@ package com.android.commands.bu; +import android.annotation.UserIdInt; import android.app.backup.IBackupManager; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.system.OsConstants; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import java.io.IOException; import java.util.ArrayList; @@ -33,35 +37,50 @@ public final class Backup { int mNextArg; IBackupManager mBackupManager; + @VisibleForTesting + Backup(IBackupManager backupManager) { + mBackupManager = backupManager; + } + + Backup() { + mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); + } + public static void main(String[] args) { - Log.d(TAG, "Beginning: " + args[0]); - mArgs = args; try { - new Backup().run(); + new Backup().run(args); } catch (Exception e) { Log.e(TAG, "Error running backup/restore", e); } Log.d(TAG, "Finished."); } - public void run() { - mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); + public void run(String[] args) { if (mBackupManager == null) { Log.e(TAG, "Can't obtain Backup Manager binder"); return; } + Log.d(TAG, "Beginning: " + args[0]); + mArgs = args; + + int userId = parseUserId(); + if (!isBackupActiveForUser(userId)) { + Log.e(TAG, "BackupManager is not available for user " + userId); + return; + } + String arg = nextArg(); if (arg.equals("backup")) { - doBackup(OsConstants.STDOUT_FILENO); + doBackup(OsConstants.STDOUT_FILENO, userId); } else if (arg.equals("restore")) { - doRestore(OsConstants.STDIN_FILENO); + doRestore(OsConstants.STDIN_FILENO, userId); } else { showUsage(); } } - private void doBackup(int socketFd) { + private void doBackup(int socketFd, @UserIdInt int userId) { ArrayList<String> packages = new ArrayList<String>(); boolean saveApks = false; boolean saveObbs = false; @@ -105,6 +124,10 @@ public final class Backup { doKeyValue = true; } else if ("-nokeyvalue".equals(arg)) { doKeyValue = false; + } else if ("-user".equals(arg)) { + // User ID has been processed in run(), ignore the next argument. + nextArg(); + continue; } else { Log.w(TAG, "Unknown backup flag " + arg); continue; @@ -128,7 +151,7 @@ public final class Backup { try { fd = ParcelFileDescriptor.adoptFd(socketFd); String[] packArray = new String[packages.size()]; - mBackupManager.adbBackup(fd, saveApks, saveObbs, saveShared, doWidgets, doEverything, + mBackupManager.adbBackup(userId, fd, saveApks, saveObbs, saveShared, doWidgets, doEverything, allIncludesSystem, doCompress, doKeyValue, packages.toArray(packArray)); } catch (RemoteException e) { Log.e(TAG, "Unable to invoke backup manager for backup"); @@ -143,12 +166,12 @@ public final class Backup { } } - private void doRestore(int socketFd) { + private void doRestore(int socketFd, @UserIdInt int userId) { // No arguments to restore ParcelFileDescriptor fd = null; try { fd = ParcelFileDescriptor.adoptFd(socketFd); - mBackupManager.adbRestore(fd); + mBackupManager.adbRestore(userId, fd); } catch (RemoteException e) { Log.e(TAG, "Unable to invoke backup manager for restore"); } finally { @@ -160,11 +183,31 @@ public final class Backup { } } + private @UserIdInt int parseUserId() { + for (int argNumber = 0; argNumber < mArgs.length - 1; argNumber++) { + if ("-user".equals(mArgs[argNumber])) { + return UserHandle.parseUserArg(mArgs[argNumber + 1]); + } + } + + return UserHandle.USER_SYSTEM; + } + + private boolean isBackupActiveForUser(int userId) { + try { + return mBackupManager.isBackupServiceActive(userId); + } catch (RemoteException e) { + Log.e(TAG, "Could not access BackupManager: " + e.toString()); + return false; + } + } + private static void showUsage() { - System.err.println(" backup [-f FILE] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all]"); - System.err.println(" [-system|-nosystem] [-keyvalue|-nokeyvalue] [PACKAGE...]"); + System.err.println(" backup [-user USER_ID] [-f FILE] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared]"); + System.err.println(" [-all] [-system|-nosystem] [-keyvalue|-nokeyvalue] [PACKAGE...]"); System.err.println(" write an archive of the device's data to FILE [default=backup.adb]"); System.err.println(" package list optional if -all/-shared are supplied"); + System.err.println(" -user: user ID for which to perform the operation (default - system user)"); System.err.println(" -apk/-noapk: do/don't back up .apk files (default -noapk)"); System.err.println(" -obb/-noobb: do/don't back up .obb files (default -noobb)"); System.err.println(" -shared|-noshared: do/don't back up shared storage (default -noshared)"); @@ -172,7 +215,8 @@ public final class Backup { System.err.println(" -system|-nosystem: include system apps in -all (default -system)"); System.err.println(" -keyvalue|-nokeyvalue: include apps that perform key/value backups."); System.err.println(" (default -nokeyvalue)"); - System.err.println(" restore FILE restore device contents from FILE"); + System.err.println(" restore [-user USER_ID] FILE restore device contents from FILE"); + System.err.println(" -user: user ID for which to perform the operation (default - system user)"); } private String nextArg() { |