Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/ISearchManager.aidl \ core/java/android/app/ISearchManagerCallback.aidl \ core/java/android/app/IServiceConnection.aidl \ core/java/android/app/IStopUserCallback.aidl \ core/java/android/app/IThumbnailReceiver.aidl \ core/java/android/app/IThumbnailRetriever.aidl \ core/java/android/app/ITransientNotification.aidl \ Loading cmds/am/src/com/android/commands/am/Am.java +26 −13 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; Loading Loading @@ -141,6 +140,8 @@ public class Am { runToUri(true); } else if (op.equals("switch-user")) { runSwitchUser(); } else if (op.equals("stop-user")) { runStopUser(); } else { throw new IllegalArgumentException("Unknown command: " + op); } Loading Loading @@ -323,7 +324,6 @@ public class Am { mUserId = Integer.parseInt(nextArgRequired()); } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return null; } } Loading Loading @@ -594,7 +594,6 @@ public class Am { no_window_animation = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading Loading @@ -738,7 +737,6 @@ public class Am { persistent = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading @@ -752,13 +750,27 @@ public class Am { } private void runSwitchUser() throws Exception { if (android.os.Process.myUid() != 0) { throw new RuntimeException("switchuser can only be run as root"); } String user = nextArgRequired(); mAm.switchUser(Integer.parseInt(user)); } private void runStopUser() throws Exception { String user = nextArgRequired(); int res = mAm.stopUser(Integer.parseInt(user), null); if (res != ActivityManager.USER_OP_SUCCESS) { String txt = ""; switch (res) { case ActivityManager.USER_OP_IS_CURRENT: txt = " (Can't stop current user)"; break; case ActivityManager.USER_OP_UNKNOWN_USER: txt = " (Unknown user " + user + ")"; break; } System.err.println("Switch failed: " + res + txt); } } class MyActivityController extends IActivityController.Stub { final String mGdbPort; Loading Loading @@ -1047,7 +1059,6 @@ public class Am { gdbPort = nextArgRequired(); } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading @@ -1065,7 +1076,6 @@ public class Am { enabled = false; } else { System.err.println("Error: enabled mode must be 'on' or 'off' at " + mode); showUsage(); return; } Loading @@ -1090,7 +1100,6 @@ public class Am { int div = size.indexOf('x'); if (div <= 0 || div >= (size.length()-1)) { System.err.println("Error: bad size " + size); showUsage(); return; } String mstr = size.substring(0, div); Loading @@ -1100,7 +1109,6 @@ public class Am { n = Integer.parseInt(nstr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); showUsage(); return; } } Loading Loading @@ -1139,12 +1147,10 @@ public class Am { density = Integer.parseInt(densityStr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); showUsage(); return; } if (density < 72) { System.err.println("Error: density must be >= 72"); showUsage(); return; } } Loading Loading @@ -1345,6 +1351,7 @@ public class Am { " am to-uri [INTENT]\n" + " am to-intent-uri [INTENT]\n" + " am switch-user <USER_ID>\n" + " am stop-user <USER_ID>\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + Loading Loading @@ -1403,6 +1410,12 @@ public class Am { "\n" + "am to-intent-uri: print the given Intent specification as an intent: URI.\n" + "\n" + "am switch-user: switch to put USER_ID in the foreground, starting" + " execution of that user if it is currently stopped.\n" + "\n" + "am stop-user: stop execution of USER_ID, not allowing it to run any" + " code until a later explicit switch to it.\n" + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" + Loading core/java/android/app/ActivityManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -211,6 +211,15 @@ public class ActivityManager { */ public static final int INTENT_SENDER_SERVICE = 4; /** @hide User operation call: success! */ public static final int USER_OP_SUCCESS = 0; /** @hide User operation call: given user id is not known. */ public static final int USER_OP_UNKNOWN_USER = -1; /** @hide User operation call: given user id is the current user, can't be stopped. */ public static final int USER_OP_IS_CURRENT = -2; /*package*/ ActivityManager(Context context, Handler handler) { mContext = context; mHandler = handler; Loading core/java/android/app/ActivityManagerNative.java +26 −1 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case STOP_USER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int userid = data.readInt(); IStopUserCallback callback = IStopUserCallback.Stub.asInterface( data.readStrongBinder()); int result = stopUser(userid, callback); reply.writeNoException(); reply.writeInt(result); return true; } case GET_CURRENT_USER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); UserInfo userInfo = getCurrentUser(); Loading Loading @@ -3756,11 +3767,25 @@ class ActivityManagerProxy implements IActivityManager return result; } public int stopUser(int userid, IStopUserCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(userid); data.writeStrongInterface(callback); mRemote.transact(STOP_USER_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } public UserInfo getCurrentUser() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); mRemote.transact(SWITCH_USER_TRANSACTION, data, reply, 0); mRemote.transact(GET_CURRENT_USER_TRANSACTION, data, reply, 0); reply.readException(); UserInfo userInfo = UserInfo.CREATOR.createFromParcel(reply); reply.recycle(); Loading core/java/android/app/IActivityManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,7 @@ public interface IActivityManager extends IInterface { // Multi-user APIs public boolean switchUser(int userid) throws RemoteException; public int stopUser(int userid, IStopUserCallback callback) throws RemoteException; public UserInfo getCurrentUser() throws RemoteException; public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException; Loading Loading @@ -611,4 +612,5 @@ public interface IActivityManager extends IInterface { int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150; int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151; int START_ACTIVITY_AS_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+152; int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153; } Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/ISearchManager.aidl \ core/java/android/app/ISearchManagerCallback.aidl \ core/java/android/app/IServiceConnection.aidl \ core/java/android/app/IStopUserCallback.aidl \ core/java/android/app/IThumbnailReceiver.aidl \ core/java/android/app/IThumbnailRetriever.aidl \ core/java/android/app/ITransientNotification.aidl \ Loading
cmds/am/src/com/android/commands/am/Am.java +26 −13 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; Loading Loading @@ -141,6 +140,8 @@ public class Am { runToUri(true); } else if (op.equals("switch-user")) { runSwitchUser(); } else if (op.equals("stop-user")) { runStopUser(); } else { throw new IllegalArgumentException("Unknown command: " + op); } Loading Loading @@ -323,7 +324,6 @@ public class Am { mUserId = Integer.parseInt(nextArgRequired()); } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return null; } } Loading Loading @@ -594,7 +594,6 @@ public class Am { no_window_animation = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading Loading @@ -738,7 +737,6 @@ public class Am { persistent = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading @@ -752,13 +750,27 @@ public class Am { } private void runSwitchUser() throws Exception { if (android.os.Process.myUid() != 0) { throw new RuntimeException("switchuser can only be run as root"); } String user = nextArgRequired(); mAm.switchUser(Integer.parseInt(user)); } private void runStopUser() throws Exception { String user = nextArgRequired(); int res = mAm.stopUser(Integer.parseInt(user), null); if (res != ActivityManager.USER_OP_SUCCESS) { String txt = ""; switch (res) { case ActivityManager.USER_OP_IS_CURRENT: txt = " (Can't stop current user)"; break; case ActivityManager.USER_OP_UNKNOWN_USER: txt = " (Unknown user " + user + ")"; break; } System.err.println("Switch failed: " + res + txt); } } class MyActivityController extends IActivityController.Stub { final String mGdbPort; Loading Loading @@ -1047,7 +1059,6 @@ public class Am { gdbPort = nextArgRequired(); } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } Loading @@ -1065,7 +1076,6 @@ public class Am { enabled = false; } else { System.err.println("Error: enabled mode must be 'on' or 'off' at " + mode); showUsage(); return; } Loading @@ -1090,7 +1100,6 @@ public class Am { int div = size.indexOf('x'); if (div <= 0 || div >= (size.length()-1)) { System.err.println("Error: bad size " + size); showUsage(); return; } String mstr = size.substring(0, div); Loading @@ -1100,7 +1109,6 @@ public class Am { n = Integer.parseInt(nstr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); showUsage(); return; } } Loading Loading @@ -1139,12 +1147,10 @@ public class Am { density = Integer.parseInt(densityStr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); showUsage(); return; } if (density < 72) { System.err.println("Error: density must be >= 72"); showUsage(); return; } } Loading Loading @@ -1345,6 +1351,7 @@ public class Am { " am to-uri [INTENT]\n" + " am to-intent-uri [INTENT]\n" + " am switch-user <USER_ID>\n" + " am stop-user <USER_ID>\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + Loading Loading @@ -1403,6 +1410,12 @@ public class Am { "\n" + "am to-intent-uri: print the given Intent specification as an intent: URI.\n" + "\n" + "am switch-user: switch to put USER_ID in the foreground, starting" + " execution of that user if it is currently stopped.\n" + "\n" + "am stop-user: stop execution of USER_ID, not allowing it to run any" + " code until a later explicit switch to it.\n" + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" + Loading
core/java/android/app/ActivityManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -211,6 +211,15 @@ public class ActivityManager { */ public static final int INTENT_SENDER_SERVICE = 4; /** @hide User operation call: success! */ public static final int USER_OP_SUCCESS = 0; /** @hide User operation call: given user id is not known. */ public static final int USER_OP_UNKNOWN_USER = -1; /** @hide User operation call: given user id is the current user, can't be stopped. */ public static final int USER_OP_IS_CURRENT = -2; /*package*/ ActivityManager(Context context, Handler handler) { mContext = context; mHandler = handler; Loading
core/java/android/app/ActivityManagerNative.java +26 −1 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case STOP_USER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int userid = data.readInt(); IStopUserCallback callback = IStopUserCallback.Stub.asInterface( data.readStrongBinder()); int result = stopUser(userid, callback); reply.writeNoException(); reply.writeInt(result); return true; } case GET_CURRENT_USER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); UserInfo userInfo = getCurrentUser(); Loading Loading @@ -3756,11 +3767,25 @@ class ActivityManagerProxy implements IActivityManager return result; } public int stopUser(int userid, IStopUserCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(userid); data.writeStrongInterface(callback); mRemote.transact(STOP_USER_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } public UserInfo getCurrentUser() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); mRemote.transact(SWITCH_USER_TRANSACTION, data, reply, 0); mRemote.transact(GET_CURRENT_USER_TRANSACTION, data, reply, 0); reply.readException(); UserInfo userInfo = UserInfo.CREATOR.createFromParcel(reply); reply.recycle(); Loading
core/java/android/app/IActivityManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,7 @@ public interface IActivityManager extends IInterface { // Multi-user APIs public boolean switchUser(int userid) throws RemoteException; public int stopUser(int userid, IStopUserCallback callback) throws RemoteException; public UserInfo getCurrentUser() throws RemoteException; public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException; Loading Loading @@ -611,4 +612,5 @@ public interface IActivityManager extends IInterface { int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150; int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151; int START_ACTIVITY_AS_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+152; int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153; }