Skip to content

Commit 4573e29

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Flesh out multi-user in am commands." into jb-mr1-dev
2 parents d7f5a51 + 1676c85 commit 4573e29

File tree

8 files changed

+269
-158
lines changed

8 files changed

+269
-158
lines changed

cmds/am/src/com/android/commands/am/Am.java

Lines changed: 116 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public class Am {
6363
private boolean mStopOption = false;
6464

6565
private int mRepeat = 0;
66-
private int mUserId = 0;
66+
private int mUserId;
6767

6868
private String mProfileFile;
6969

@@ -160,7 +160,7 @@ int parseUserArg(String arg) {
160160
return userId;
161161
}
162162

163-
private Intent makeIntent() throws URISyntaxException {
163+
private Intent makeIntent(int defUser) throws URISyntaxException {
164164
Intent intent = new Intent();
165165
Intent baseIntent = intent;
166166
boolean hasIntentInfo = false;
@@ -170,7 +170,7 @@ private Intent makeIntent() throws URISyntaxException {
170170
mStopOption = false;
171171
mRepeat = 0;
172172
mProfileFile = null;
173-
mUserId = 0;
173+
mUserId = defUser;
174174
Uri data = null;
175175
String type = null;
176176

@@ -404,7 +404,7 @@ private Intent makeIntent() throws URISyntaxException {
404404
}
405405

406406
private void runStartService() throws Exception {
407-
Intent intent = makeIntent();
407+
Intent intent = makeIntent(UserHandle.USER_CURRENT);
408408
if (mUserId == UserHandle.USER_ALL) {
409409
System.err.println("Error: Can't start activity with user 'all'");
410410
return;
@@ -417,7 +417,7 @@ private void runStartService() throws Exception {
417417
}
418418

419419
private void runStart() throws Exception {
420-
Intent intent = makeIntent();
420+
Intent intent = makeIntent(UserHandle.USER_CURRENT);
421421

422422
if (mUserId == UserHandle.USER_ALL) {
423423
System.err.println("Error: Can't start service with user 'all'");
@@ -456,7 +456,7 @@ private void runStart() throws Exception {
456456
packageName = activities.get(0).activityInfo.packageName;
457457
}
458458
System.out.println("Stopping: " + packageName);
459-
mAm.forceStopPackage(packageName);
459+
mAm.forceStopPackage(packageName, mUserId);
460460
Thread.sleep(250);
461461
}
462462

@@ -570,19 +570,41 @@ private void runStart() throws Exception {
570570
}
571571

572572
private void runForceStop() throws Exception {
573-
mAm.forceStopPackage(nextArgRequired());
573+
int userId = UserHandle.USER_ALL;
574+
575+
String opt;
576+
while ((opt=nextOption()) != null) {
577+
if (opt.equals("--user")) {
578+
userId = parseUserArg(nextArgRequired());
579+
} else {
580+
System.err.println("Error: Unknown option: " + opt);
581+
return;
582+
}
583+
}
584+
mAm.forceStopPackage(nextArgRequired(), userId);
574585
}
575586

576587
private void runKill() throws Exception {
577-
mAm.killBackgroundProcesses(nextArgRequired());
588+
int userId = UserHandle.USER_ALL;
589+
590+
String opt;
591+
while ((opt=nextOption()) != null) {
592+
if (opt.equals("--user")) {
593+
userId = parseUserArg(nextArgRequired());
594+
} else {
595+
System.err.println("Error: Unknown option: " + opt);
596+
return;
597+
}
598+
}
599+
mAm.killBackgroundProcesses(nextArgRequired(), userId);
578600
}
579601

580602
private void runKillAll() throws Exception {
581603
mAm.killAllBackgroundProcesses();
582604
}
583605

584606
private void sendBroadcast() throws Exception {
585-
Intent intent = makeIntent();
607+
Intent intent = makeIntent(UserHandle.USER_ALL);
586608
IntentReceiver receiver = new IntentReceiver();
587609
System.out.println("Broadcasting: " + intent);
588610
mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
@@ -595,7 +617,7 @@ private void runInstrument() throws Exception {
595617
boolean wait = false;
596618
boolean rawMode = false;
597619
boolean no_window_animation = false;
598-
int userId = 0;
620+
int userId = UserHandle.USER_CURRENT;
599621
Bundle args = new Bundle();
600622
String argKey = null, argValue = null;
601623
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
@@ -672,17 +694,37 @@ private void runProfile() throws Exception {
672694
String profileFile = null;
673695
boolean start = false;
674696
boolean wall = false;
697+
int userId = UserHandle.USER_CURRENT;
675698
int profileType = 0;
676-
699+
677700
String process = null;
678-
701+
679702
String cmd = nextArgRequired();
680703

681704
if ("start".equals(cmd)) {
682705
start = true;
683-
wall = "--wall".equals(nextOption());
706+
String opt;
707+
while ((opt=nextOption()) != null) {
708+
if (opt.equals("--user")) {
709+
userId = parseUserArg(nextArgRequired());
710+
} else if (opt.equals("--wall")) {
711+
wall = true;
712+
} else {
713+
System.err.println("Error: Unknown option: " + opt);
714+
return;
715+
}
716+
}
684717
process = nextArgRequired();
685718
} else if ("stop".equals(cmd)) {
719+
String opt;
720+
while ((opt=nextOption()) != null) {
721+
if (opt.equals("--user")) {
722+
userId = parseUserArg(nextArgRequired());
723+
} else {
724+
System.err.println("Error: Unknown option: " + opt);
725+
return;
726+
}
727+
}
686728
process = nextArg();
687729
} else {
688730
// Compatibility with old syntax: process is specified first.
@@ -694,7 +736,12 @@ private void runProfile() throws Exception {
694736
throw new IllegalArgumentException("Profile command " + process + " not valid");
695737
}
696738
}
697-
739+
740+
if (userId == UserHandle.USER_ALL) {
741+
System.err.println("Error: Can't profile with user 'all'");
742+
return;
743+
}
744+
698745
ParcelFileDescriptor fd = null;
699746

700747
if (start) {
@@ -722,7 +769,7 @@ private void runProfile() throws Exception {
722769
} else if (start) {
723770
//removeWallOption();
724771
}
725-
if (!mAm.profileControl(process, start, profileFile, fd, profileType)) {
772+
if (!mAm.profileControl(process, userId, start, profileFile, fd, profileType)) {
726773
wall = false;
727774
throw new AndroidException("PROFILE FAILED on process " + process);
728775
}
@@ -734,7 +781,24 @@ private void runProfile() throws Exception {
734781
}
735782

736783
private void runDumpHeap() throws Exception {
737-
boolean managed = !"-n".equals(nextOption());
784+
boolean managed = true;
785+
int userId = UserHandle.USER_CURRENT;
786+
787+
String opt;
788+
while ((opt=nextOption()) != null) {
789+
if (opt.equals("--user")) {
790+
userId = parseUserArg(nextArgRequired());
791+
if (userId == UserHandle.USER_ALL) {
792+
System.err.println("Error: Can't dump heap with user 'all'");
793+
return;
794+
}
795+
} else if (opt.equals("-n")) {
796+
managed = false;
797+
} else {
798+
System.err.println("Error: Unknown option: " + opt);
799+
return;
800+
}
801+
}
738802
String process = nextArgRequired();
739803
String heapFile = nextArgRequired();
740804
ParcelFileDescriptor fd = null;
@@ -750,7 +814,7 @@ private void runDumpHeap() throws Exception {
750814
return;
751815
}
752816

753-
if (!mAm.dumpHeap(process, managed, heapFile, fd)) {
817+
if (!mAm.dumpHeap(process, userId, managed, heapFile, fd)) {
754818
throw new AndroidException("HEAP DUMP FAILED on process " + process);
755819
}
756820
}
@@ -1204,7 +1268,7 @@ private void runDisplayDensity() throws Exception {
12041268
}
12051269

12061270
private void runToUri(boolean intentScheme) throws Exception {
1207-
Intent intent = makeIntent();
1271+
Intent intent = makeIntent(UserHandle.USER_CURRENT);
12081272
System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
12091273
}
12101274

@@ -1363,18 +1427,19 @@ private static void showUsage() {
13631427
System.err.println(
13641428
"usage: am [subcommand] [options]\n" +
13651429
"usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
1366-
" [--R COUNT] [-S] [--opengl-trace] <INTENT>\n" +
1367-
" am startservice <INTENT>\n" +
1368-
" am force-stop <PACKAGE>\n" +
1369-
" am kill <PACKAGE>\n" +
1430+
" [--R COUNT] [-S] [--opengl-trace]\n" +
1431+
" [--user <USER_ID> | current] <INTENT>\n" +
1432+
" am startservice [--user <USER_ID> | current] <INTENT>\n" +
1433+
" am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
1434+
" am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
13701435
" am kill-all\n" +
1371-
" am broadcast <INTENT>\n" +
1436+
" am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
13721437
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
1373-
" [--user <USER_ID> | all | current]\n" +
1438+
" [--user <USER_ID> | current]\n" +
13741439
" [--no-window-animation] <COMPONENT>\n" +
1375-
" am profile start <PROCESS> <FILE>\n" +
1376-
" am profile stop [<PROCESS>]\n" +
1377-
" am dumpheap [flags] <PROCESS> <FILE>\n" +
1440+
" am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
1441+
" am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
1442+
" am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
13781443
" am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
13791444
" am clear-debug-app\n" +
13801445
" am monitor [--gdb <port>]\n" +
@@ -1395,18 +1460,28 @@ private static void showUsage() {
13951460
" the top activity will be finished.\n" +
13961461
" -S: force stop the target app before starting the activity\n" +
13971462
" --opengl-trace: enable tracing of OpenGL functions\n" +
1463+
" --user <USER_ID> | current: Specify which user to run as; if not\n" +
1464+
" specified then run as the current user.\n" +
13981465
"\n" +
1399-
"am startservice: start a Service.\n" +
1466+
"am startservice: start a Service. Options are:\n" +
1467+
" --user <USER_ID> | current: Specify which user to run as; if not\n" +
1468+
" specified then run as the current user.\n" +
14001469
"\n" +
14011470
"am force-stop: force stop everything associated with <PACKAGE>.\n" +
1471+
" --user <USER_ID> | all | current: Specify user to force stop;\n" +
1472+
" all users if not specified.\n" +
14021473
"\n" +
14031474
"am kill: Kill all processes associated with <PACKAGE>. Only kills.\n" +
14041475
" processes that are safe to kill -- that is, will not impact the user\n" +
14051476
" experience.\n" +
1477+
" --user <USER_ID> | all | current: Specify user whose processes to kill;\n" +
1478+
" all users if not specified.\n" +
14061479
"\n" +
14071480
"am kill-all: Kill all background processes.\n" +
14081481
"\n" +
1409-
"am broadcast: send a broadcast Intent.\n" +
1482+
"am broadcast: send a broadcast Intent. Options are:\n" +
1483+
" --user <USER_ID> | all | current: Specify which user to send to; if not\n" +
1484+
" specified then send to all users.\n" +
14101485
"\n" +
14111486
"am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" +
14121487
" is the form <TEST_PACKAGE>/<RUNNER_CLASS>. Options are:\n" +
@@ -1417,13 +1492,20 @@ private static void showUsage() {
14171492
" -p <FILE>: write profiling data to <FILE>\n" +
14181493
" -w: wait for instrumentation to finish before returning. Required for\n" +
14191494
" test runners.\n" +
1420-
" --user [<USER_ID> | all | current]: Specify user instrumentation runs in.\n" +
1495+
" --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
1496+
" current user if not specified.\n" +
14211497
" --no-window-animation: turn off window animations will running.\n" +
14221498
"\n" +
1423-
"am profile: start and stop profiler on a process.\n" +
1499+
"am profile: start and stop profiler on a process. The given <PROCESS> argument\n" +
1500+
" may be either a process name or pid. Options are:\n" +
1501+
" --user <USER_ID> | current: When supplying a process name,\n" +
1502+
" specify user of process to profile; uses current user if not specified.\n" +
14241503
"\n" +
1425-
"am dumpheap: dump the heap of a process. Options are:\n" +
1504+
"am dumpheap: dump the heap of a process. The given <PROCESS> argument may\n" +
1505+
" be either a process name or pid. Options are:\n" +
14261506
" -n: dump native heap instead of managed heap\n" +
1507+
" --user <USER_ID> | current: When supplying a process name,\n" +
1508+
" specify user of process to dump; uses current user if not specified.\n" +
14271509
"\n" +
14281510
"am set-debug-app: set application <PACKAGE> to debug. Options are:\n" +
14291511
" -w: wait for debugger when application starts\n" +
@@ -1444,10 +1526,10 @@ private static void showUsage() {
14441526
"\n" +
14451527
"am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
14461528
"\n" +
1447-
"am switch-user: switch to put USER_ID in the foreground, starting" +
1529+
"am switch-user: switch to put USER_ID in the foreground, starting\n" +
14481530
" execution of that user if it is currently stopped.\n" +
14491531
"\n" +
1450-
"am stop-user: stop execution of USER_ID, not allowing it to run any" +
1532+
"am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
14511533
" code until a later explicit switch to it.\n" +
14521534
"\n" +
14531535
"<INTENT> specifications include these flags and arguments:\n" +
@@ -1465,7 +1547,6 @@ private static void showUsage() {
14651547
" [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
14661548
" [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
14671549
" [-n <COMPONENT>] [-f <FLAGS>]\n" +
1468-
" [--user [<USER_ID> | all | current]\n" +
14691550
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
14701551
" [--debug-log-resolution] [--exclude-stopped-packages]\n" +
14711552
" [--include-stopped-packages]\n" +

core/java/android/app/ActivityManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,7 +1693,8 @@ public void restartPackage(String packageName) {
16931693
*/
16941694
public void killBackgroundProcesses(String packageName) {
16951695
try {
1696-
ActivityManagerNative.getDefault().killBackgroundProcesses(packageName);
1696+
ActivityManagerNative.getDefault().killBackgroundProcesses(packageName,
1697+
UserHandle.myUserId());
16971698
} catch (RemoteException e) {
16981699
}
16991700
}
@@ -1718,7 +1719,8 @@ public void killBackgroundProcesses(String packageName) {
17181719
*/
17191720
public void forceStopPackage(String packageName) {
17201721
try {
1721-
ActivityManagerNative.getDefault().forceStopPackage(packageName);
1722+
ActivityManagerNative.getDefault().forceStopPackage(packageName,
1723+
UserHandle.myUserId());
17221724
} catch (RemoteException e) {
17231725
}
17241726
}

0 commit comments

Comments
 (0)