3131import android .content .pm .IPackageManager ;
3232import android .content .pm .ResolveInfo ;
3333import android .net .Uri ;
34- import android .os .Binder ;
3534import android .os .Bundle ;
3635import android .os .ParcelFileDescriptor ;
3736import android .os .RemoteException ;
@@ -141,6 +140,8 @@ private void run(String[] args) throws Exception {
141140 runToUri (true );
142141 } else if (op .equals ("switch-user" )) {
143142 runSwitchUser ();
143+ } else if (op .equals ("stop-user" )) {
144+ runStopUser ();
144145 } else {
145146 throw new IllegalArgumentException ("Unknown command: " + op );
146147 }
@@ -323,7 +324,6 @@ private Intent makeIntent() throws URISyntaxException {
323324 mUserId = Integer .parseInt (nextArgRequired ());
324325 } else {
325326 System .err .println ("Error: Unknown option: " + opt );
326- showUsage ();
327327 return null ;
328328 }
329329 }
@@ -594,7 +594,6 @@ private void runInstrument() throws Exception {
594594 no_window_animation = true ;
595595 } else {
596596 System .err .println ("Error: Unknown option: " + opt );
597- showUsage ();
598597 return ;
599598 }
600599 }
@@ -738,7 +737,6 @@ private void runSetDebugApp() throws Exception {
738737 persistent = true ;
739738 } else {
740739 System .err .println ("Error: Unknown option: " + opt );
741- showUsage ();
742740 return ;
743741 }
744742 }
@@ -752,13 +750,27 @@ private void runClearDebugApp() throws Exception {
752750 }
753751
754752 private void runSwitchUser () throws Exception {
755- if (android .os .Process .myUid () != 0 ) {
756- throw new RuntimeException ("switchuser can only be run as root" );
757- }
758753 String user = nextArgRequired ();
759754 mAm .switchUser (Integer .parseInt (user ));
760755 }
761756
757+ private void runStopUser () throws Exception {
758+ String user = nextArgRequired ();
759+ int res = mAm .stopUser (Integer .parseInt (user ), null );
760+ if (res != ActivityManager .USER_OP_SUCCESS ) {
761+ String txt = "" ;
762+ switch (res ) {
763+ case ActivityManager .USER_OP_IS_CURRENT :
764+ txt = " (Can't stop current user)" ;
765+ break ;
766+ case ActivityManager .USER_OP_UNKNOWN_USER :
767+ txt = " (Unknown user " + user + ")" ;
768+ break ;
769+ }
770+ System .err .println ("Switch failed: " + res + txt );
771+ }
772+ }
773+
762774 class MyActivityController extends IActivityController .Stub {
763775 final String mGdbPort ;
764776
@@ -1047,7 +1059,6 @@ private void runMonitor() throws Exception {
10471059 gdbPort = nextArgRequired ();
10481060 } else {
10491061 System .err .println ("Error: Unknown option: " + opt );
1050- showUsage ();
10511062 return ;
10521063 }
10531064 }
@@ -1065,7 +1076,6 @@ private void runScreenCompat() throws Exception {
10651076 enabled = false ;
10661077 } else {
10671078 System .err .println ("Error: enabled mode must be 'on' or 'off' at " + mode );
1068- showUsage ();
10691079 return ;
10701080 }
10711081
@@ -1090,7 +1100,6 @@ private void runDisplaySize() throws Exception {
10901100 int div = size .indexOf ('x' );
10911101 if (div <= 0 || div >= (size .length ()-1 )) {
10921102 System .err .println ("Error: bad size " + size );
1093- showUsage ();
10941103 return ;
10951104 }
10961105 String mstr = size .substring (0 , div );
@@ -1100,7 +1109,6 @@ private void runDisplaySize() throws Exception {
11001109 n = Integer .parseInt (nstr );
11011110 } catch (NumberFormatException e ) {
11021111 System .err .println ("Error: bad number " + e );
1103- showUsage ();
11041112 return ;
11051113 }
11061114 }
@@ -1139,12 +1147,10 @@ private void runDisplayDensity() throws Exception {
11391147 density = Integer .parseInt (densityStr );
11401148 } catch (NumberFormatException e ) {
11411149 System .err .println ("Error: bad number " + e );
1142- showUsage ();
11431150 return ;
11441151 }
11451152 if (density < 72 ) {
11461153 System .err .println ("Error: density must be >= 72" );
1147- showUsage ();
11481154 return ;
11491155 }
11501156 }
@@ -1345,6 +1351,7 @@ private static void showUsage() {
13451351 " am to-uri [INTENT]\n " +
13461352 " am to-intent-uri [INTENT]\n " +
13471353 " am switch-user <USER_ID>\n " +
1354+ " am stop-user <USER_ID>\n " +
13481355 "\n " +
13491356 "am start: start an Activity. Options are:\n " +
13501357 " -D: enable debugging\n " +
@@ -1403,6 +1410,12 @@ private static void showUsage() {
14031410 "\n " +
14041411 "am to-intent-uri: print the given Intent specification as an intent: URI.\n " +
14051412 "\n " +
1413+ "am switch-user: switch to put USER_ID in the foreground, starting" +
1414+ " execution of that user if it is currently stopped.\n " +
1415+ "\n " +
1416+ "am stop-user: stop execution of USER_ID, not allowing it to run any" +
1417+ " code until a later explicit switch to it.\n " +
1418+ "\n " +
14061419 "<INTENT> specifications include these flags and arguments:\n " +
14071420 " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n " +
14081421 " [-c <CATEGORY> [-c <CATEGORY>] ...]\n " +
0 commit comments