Skip to content

Commit 649d0d7

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "More multi-user stuff:" into jb-mr1-dev
2 parents 55e6b77 + 5e03e2c commit 649d0d7

File tree

17 files changed

+543
-304
lines changed

17 files changed

+543
-304
lines changed

api/current.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6327,6 +6327,7 @@ package android.content.pm {
63276327
field public static final int FLAG_FACTORY_TEST = 16; // 0x10
63286328
field public static final int FLAG_HAS_CODE = 4; // 0x4
63296329
field public static final int FLAG_INSTALLED = 8388608; // 0x800000
6330+
field public static final int FLAG_IS_DATA_ONLY = 16777216; // 0x1000000
63306331
field public static final int FLAG_KILL_AFTER_RESTORE = 65536; // 0x10000
63316332
field public static final int FLAG_LARGE_HEAP = 1048576; // 0x100000
63326333
field public static final int FLAG_PERSISTENT = 8; // 0x8

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

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import android.os.RemoteException;
3737
import android.os.ServiceManager;
3838
import android.os.SystemProperties;
39+
import android.os.UserHandle;
3940
import android.util.AndroidException;
4041
import android.view.Display;
4142
import android.view.IWindowManager;
@@ -147,6 +148,18 @@ private void run(String[] args) throws Exception {
147148
}
148149
}
149150

151+
int parseUserArg(String arg) {
152+
int userId;
153+
if ("all".equals(arg)) {
154+
userId = UserHandle.USER_ALL;
155+
} else if ("current".equals(arg) || "cur".equals(arg)) {
156+
userId = UserHandle.USER_CURRENT;
157+
} else {
158+
userId = Integer.parseInt(arg);
159+
}
160+
return userId;
161+
}
162+
150163
private Intent makeIntent() throws URISyntaxException {
151164
Intent intent = new Intent();
152165
Intent baseIntent = intent;
@@ -321,7 +334,7 @@ private Intent makeIntent() throws URISyntaxException {
321334
} else if (opt.equals("--opengl-trace")) {
322335
mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES;
323336
} else if (opt.equals("--user")) {
324-
mUserId = Integer.parseInt(nextArgRequired());
337+
mUserId = parseUserArg(nextArgRequired());
325338
} else {
326339
System.err.println("Error: Unknown option: " + opt);
327340
return null;
@@ -392,8 +405,12 @@ private Intent makeIntent() throws URISyntaxException {
392405

393406
private void runStartService() throws Exception {
394407
Intent intent = makeIntent();
408+
if (mUserId == UserHandle.USER_ALL) {
409+
System.err.println("Error: Can't start activity with user 'all'");
410+
return;
411+
}
395412
System.out.println("Starting service: " + intent);
396-
ComponentName cn = mAm.startService(null, intent, intent.getType(), 0);
413+
ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId);
397414
if (cn == null) {
398415
System.err.println("Error: Not found; no service started.");
399416
}
@@ -402,10 +419,15 @@ private void runStartService() throws Exception {
402419
private void runStart() throws Exception {
403420
Intent intent = makeIntent();
404421

422+
if (mUserId == UserHandle.USER_ALL) {
423+
System.err.println("Error: Can't start service with user 'all'");
424+
return;
425+
}
426+
405427
String mimeType = intent.getType();
406428
if (mimeType == null && intent.getData() != null
407429
&& "content".equals(intent.getData().getScheme())) {
408-
mimeType = mAm.getProviderMimeType(intent.getData());
430+
mimeType = mAm.getProviderMimeType(intent.getData(), mUserId);
409431
}
410432

411433
do {
@@ -460,11 +482,11 @@ private void runStart() throws Exception {
460482
int res;
461483
if (mWaitOption) {
462484
result = mAm.startActivityAndWait(null, intent, mimeType,
463-
null, null, 0, mStartFlags, mProfileFile, fd, null);
485+
null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
464486
res = result.result;
465487
} else {
466-
res = mAm.startActivity(null, intent, mimeType,
467-
null, null, 0, mStartFlags, mProfileFile, fd, null);
488+
res = mAm.startActivityAsUser(null, intent, mimeType,
489+
null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
468490
}
469491
PrintStream out = mWaitOption ? System.out : System.err;
470492
boolean launched = false;
@@ -573,6 +595,7 @@ private void runInstrument() throws Exception {
573595
boolean wait = false;
574596
boolean rawMode = false;
575597
boolean no_window_animation = false;
598+
int userId = 0;
576599
Bundle args = new Bundle();
577600
String argKey = null, argValue = null;
578601
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
@@ -592,12 +615,19 @@ private void runInstrument() throws Exception {
592615
} else if (opt.equals("--no_window_animation")
593616
|| opt.equals("--no-window-animation")) {
594617
no_window_animation = true;
618+
} else if (opt.equals("--user")) {
619+
userId = parseUserArg(nextArgRequired());
595620
} else {
596621
System.err.println("Error: Unknown option: " + opt);
597622
return;
598623
}
599624
}
600625

626+
if (userId == UserHandle.USER_ALL) {
627+
System.err.println("Error: Can't start instrumentation with user 'all'");
628+
return;
629+
}
630+
601631
String cnArg = nextArgRequired();
602632
ComponentName cn = ComponentName.unflattenFromString(cnArg);
603633
if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
@@ -614,7 +644,7 @@ private void runInstrument() throws Exception {
614644
wm.setAnimationScale(1, 0.0f);
615645
}
616646

617-
if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher)) {
647+
if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, userId)) {
618648
throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
619649
}
620650

@@ -1340,6 +1370,7 @@ private static void showUsage() {
13401370
" am kill-all\n" +
13411371
" am broadcast <INTENT>\n" +
13421372
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
1373+
" [--user <USER_ID> | all | current]\n" +
13431374
" [--no-window-animation] <COMPONENT>\n" +
13441375
" am profile start <PROCESS> <FILE>\n" +
13451376
" am profile stop [<PROCESS>]\n" +
@@ -1386,6 +1417,7 @@ private static void showUsage() {
13861417
" -p <FILE>: write profiling data to <FILE>\n" +
13871418
" -w: wait for instrumentation to finish before returning. Required for\n" +
13881419
" test runners.\n" +
1420+
" --user [<USER_ID> | all | current]: Specify user instrumentation runs in.\n" +
13891421
" --no-window-animation: turn off window animations will running.\n" +
13901422
"\n" +
13911423
"am profile: start and stop profiler on a process.\n" +
@@ -1433,6 +1465,7 @@ private static void showUsage() {
14331465
" [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
14341466
" [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
14351467
" [-n <COMPONENT>] [-f <FLAGS>]\n" +
1468+
" [--user [<USER_ID> | all | current]\n" +
14361469
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
14371470
" [--debug-log-resolution] [--exclude-stopped-packages]\n" +
14381471
" [--include-stopped-packages]\n" +

cmds/pm/src/com/android/commands/pm/Pm.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import android.app.ActivityManagerNative;
2222
import android.content.ComponentName;
23-
import android.content.Context;
2423
import android.content.pm.ApplicationInfo;
2524
import android.content.pm.ContainerEncryptionParams;
2625
import android.content.pm.FeatureInfo;
@@ -40,12 +39,9 @@
4039
import android.content.res.AssetManager;
4140
import android.content.res.Resources;
4241
import android.net.Uri;
43-
import android.os.Binder;
4442
import android.os.IUserManager;
45-
import android.os.Process;
4643
import android.os.RemoteException;
4744
import android.os.ServiceManager;
48-
import android.os.UserManager;
4945

5046
import java.io.File;
5147
import java.lang.reflect.Field;
@@ -74,7 +70,6 @@ public final class Pm {
7470

7571
private static final String PM_NOT_RUNNING_ERR =
7672
"Error: Could not access the Package Manager. Is the system running?";
77-
private static final int ROOT_UID = 0;
7873

7974
public static void main(String[] args) {
8075
new Pm().run(args);
@@ -1054,11 +1049,16 @@ public void packageDeleted(String packageName, int returnCode) {
10541049
}
10551050

10561051
private void runUninstall() {
1057-
int unInstallFlags = 0;
1052+
int unInstallFlags = PackageManager.DELETE_ALL_USERS;
10581053

1059-
String opt = nextOption();
1060-
if (opt != null && opt.equals("-k")) {
1061-
unInstallFlags = PackageManager.DELETE_KEEP_DATA;
1054+
String opt;
1055+
while ((opt=nextOption()) != null) {
1056+
if (opt.equals("-k")) {
1057+
unInstallFlags |= PackageManager.DELETE_KEEP_DATA;
1058+
} else {
1059+
System.err.println("Error: Unknown option: " + opt);
1060+
return;
1061+
}
10621062
}
10631063

10641064
String pkg = nextArg();

core/java/android/app/ActivityManager.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,4 +1957,21 @@ public boolean switchUser(int userid) {
19571957
return false;
19581958
}
19591959
}
1960+
1961+
/**
1962+
* Return whether the given user is actively running. This means that
1963+
* the user is in the "started" state, not "stopped" -- it is currently
1964+
* allowed to run code through scheduled alarms, receiving broadcasts,
1965+
* etc. A started user may be either the current foreground user or a
1966+
* background user; the result here does not distinguish between the two.
1967+
* @param userid the user's id. Zero indicates the default user.
1968+
* @hide
1969+
*/
1970+
public boolean isUserRunning(int userid) {
1971+
try {
1972+
return ActivityManagerNative.getDefault().isUserRunning(userid);
1973+
} catch (RemoteException e) {
1974+
return false;
1975+
}
1976+
}
19601977
}

core/java/android/app/ActivityManagerNative.java

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,10 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
177177
? data.readFileDescriptor() : null;
178178
Bundle options = data.readInt() != 0
179179
? Bundle.CREATOR.createFromParcel(data) : null;
180+
int userId = data.readInt();
180181
WaitResult result = startActivityAndWait(app, intent, resolvedType,
181182
resultTo, resultWho, requestCode, startFlags,
182-
profileFile, profileFd, options);
183+
profileFile, profileFd, options, userId);
183184
reply.writeNoException();
184185
result.writeToParcel(reply, 0);
185186
return true;
@@ -811,7 +812,8 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
811812
Bundle arguments = data.readBundle();
812813
IBinder b = data.readStrongBinder();
813814
IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b);
814-
boolean res = startInstrumentation(className, profileFile, fl, arguments, w);
815+
int userId = data.readInt();
816+
boolean res = startInstrumentation(className, profileFile, fl, arguments, w, userId);
815817
reply.writeNoException();
816818
reply.writeInt(res ? 1 : 0);
817819
return true;
@@ -1323,11 +1325,11 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
13231325
return true;
13241326
}
13251327

1326-
case KILL_APPLICATION_WITH_UID_TRANSACTION: {
1328+
case KILL_APPLICATION_WITH_APPID_TRANSACTION: {
13271329
data.enforceInterface(IActivityManager.descriptor);
13281330
String pkg = data.readString();
1329-
int uid = data.readInt();
1330-
killApplicationWithUid(pkg, uid);
1331+
int appid = data.readInt();
1332+
killApplicationWithAppId(pkg, appid);
13311333
reply.writeNoException();
13321334
return true;
13331335
}
@@ -1424,7 +1426,8 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
14241426
case GET_PROVIDER_MIME_TYPE_TRANSACTION: {
14251427
data.enforceInterface(IActivityManager.descriptor);
14261428
Uri uri = Uri.CREATOR.createFromParcel(data);
1427-
String type = getProviderMimeType(uri);
1429+
int userId = data.readInt();
1430+
String type = getProviderMimeType(uri, userId);
14281431
reply.writeNoException();
14291432
reply.writeString(type);
14301433
return true;
@@ -1573,6 +1576,15 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
15731576
return true;
15741577
}
15751578

1579+
case IS_USER_RUNNING_TRANSACTION: {
1580+
data.enforceInterface(IActivityManager.descriptor);
1581+
int userid = data.readInt();
1582+
boolean result = isUserRunning(userid);
1583+
reply.writeNoException();
1584+
reply.writeInt(result ? 1 : 0);
1585+
return true;
1586+
}
1587+
15761588
case REMOVE_SUB_TASK_TRANSACTION:
15771589
{
15781590
data.enforceInterface(IActivityManager.descriptor);
@@ -1827,7 +1839,7 @@ public int startActivityAsUser(IApplicationThread caller, Intent intent,
18271839
public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent,
18281840
String resolvedType, IBinder resultTo, String resultWho,
18291841
int requestCode, int startFlags, String profileFile,
1830-
ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
1842+
ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
18311843
Parcel data = Parcel.obtain();
18321844
Parcel reply = Parcel.obtain();
18331845
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -1851,6 +1863,7 @@ public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent,
18511863
} else {
18521864
data.writeInt(0);
18531865
}
1866+
data.writeInt(userId);
18541867
mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0);
18551868
reply.readException();
18561869
WaitResult result = WaitResult.CREATOR.createFromParcel(reply);
@@ -2719,7 +2732,7 @@ public void unbindBackupAgent(ApplicationInfo app) throws RemoteException {
27192732
}
27202733

27212734
public boolean startInstrumentation(ComponentName className, String profileFile,
2722-
int flags, Bundle arguments, IInstrumentationWatcher watcher)
2735+
int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)
27232736
throws RemoteException {
27242737
Parcel data = Parcel.obtain();
27252738
Parcel reply = Parcel.obtain();
@@ -2729,6 +2742,7 @@ public boolean startInstrumentation(ComponentName className, String profileFile,
27292742
data.writeInt(flags);
27302743
data.writeBundle(arguments);
27312744
data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
2745+
data.writeInt(userId);
27322746
mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
27332747
reply.readException();
27342748
boolean res = reply.readInt() != 0;
@@ -3366,13 +3380,13 @@ public void resumeAppSwitches() throws RemoteException {
33663380
data.recycle();
33673381
}
33683382

3369-
public void killApplicationWithUid(String pkg, int uid) throws RemoteException {
3383+
public void killApplicationWithAppId(String pkg, int appid) throws RemoteException {
33703384
Parcel data = Parcel.obtain();
33713385
Parcel reply = Parcel.obtain();
33723386
data.writeInterfaceToken(IActivityManager.descriptor);
33733387
data.writeString(pkg);
3374-
data.writeInt(uid);
3375-
mRemote.transact(KILL_APPLICATION_WITH_UID_TRANSACTION, data, reply, 0);
3388+
data.writeInt(appid);
3389+
mRemote.transact(KILL_APPLICATION_WITH_APPID_TRANSACTION, data, reply, 0);
33763390
reply.readException();
33773391
data.recycle();
33783392
reply.recycle();
@@ -3507,12 +3521,12 @@ public void crashApplication(int uid, int initialPid, String packageName,
35073521
reply.recycle();
35083522
}
35093523

3510-
public String getProviderMimeType(Uri uri)
3511-
throws RemoteException {
3524+
public String getProviderMimeType(Uri uri, int userId) throws RemoteException {
35123525
Parcel data = Parcel.obtain();
35133526
Parcel reply = Parcel.obtain();
35143527
data.writeInterfaceToken(IActivityManager.descriptor);
35153528
uri.writeToParcel(data, 0);
3529+
data.writeInt(userId);
35163530
mRemote.transact(GET_PROVIDER_MIME_TYPE_TRANSACTION, data, reply, 0);
35173531
reply.readException();
35183532
String res = reply.readString();
@@ -3747,6 +3761,19 @@ public UserInfo getCurrentUser() throws RemoteException {
37473761
return userInfo;
37483762
}
37493763

3764+
public boolean isUserRunning(int userid) throws RemoteException {
3765+
Parcel data = Parcel.obtain();
3766+
Parcel reply = Parcel.obtain();
3767+
data.writeInterfaceToken(IActivityManager.descriptor);
3768+
data.writeInt(userid);
3769+
mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
3770+
reply.readException();
3771+
boolean result = reply.readInt() != 0;
3772+
reply.recycle();
3773+
data.recycle();
3774+
return result;
3775+
}
3776+
37503777
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException {
37513778
Parcel data = Parcel.obtain();
37523779
Parcel reply = Parcel.obtain();

core/java/android/app/ContextImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,7 @@ public boolean startInstrumentation(ComponentName className,
14281428
arguments.setAllowFds(false);
14291429
}
14301430
return ActivityManagerNative.getDefault().startInstrumentation(
1431-
className, profileFile, 0, arguments, null);
1431+
className, profileFile, 0, arguments, null, UserHandle.myUserId());
14321432
} catch (RemoteException e) {
14331433
// System has crashed, nothing we can do.
14341434
}

0 commit comments

Comments
 (0)