@@ -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 " +
0 commit comments