Skip to content

Commit 786b440

Browse files
author
Dianne Hackborn
committed
Fix installing applications from non-primary users.
We also now send the correct broadcasts to each user. You no longer need to be running the shell as root to be able to create/remove users. Also added some more man page material to the pm command, and got rid of a bunch of showUsage() calls that now make error messages completely buried because of how large the usage info has become. And the package manager now shows the user each historical broadcast was sent to. Change-Id: Iab42498e1352a0c023069139c80fc04d2d69ab4b
1 parent 9d9ea05 commit 786b440

File tree

6 files changed

+108
-88
lines changed

6 files changed

+108
-88
lines changed

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

Lines changed: 10 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,6 @@ public void run(String[] args) {
178178
return;
179179
}
180180

181-
if ("list-users".equals(op)) {
182-
runListUsers();
183-
return;
184-
}
185-
186181
try {
187182
if (args.length == 1) {
188183
if (args[0].equalsIgnoreCase("-l")) {
@@ -222,7 +217,6 @@ private void runList() {
222217
String type = nextArg();
223218
if (type == null) {
224219
System.err.println("Error: didn't specify type of data to list");
225-
showUsage();
226220
return;
227221
}
228222
if ("package".equals(type) || "packages".equals(type)) {
@@ -241,7 +235,6 @@ private void runList() {
241235
runListUsers();
242236
} else {
243237
System.err.println("Error: unknown list type '" + type + "'");
244-
showUsage();
245238
}
246239
}
247240

@@ -276,13 +269,11 @@ private void runListPackages(boolean showApplicationPackage) {
276269
getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
277270
} else {
278271
System.err.println("Error: Unknown option: " + opt);
279-
showUsage();
280272
return;
281273
}
282274
}
283275
} catch (RuntimeException ex) {
284276
System.err.println("Error: " + ex.toString());
285-
showUsage();
286277
return;
287278
}
288279

@@ -431,13 +422,11 @@ private void runListInstrumentation() {
431422
targetPackage = opt;
432423
} else {
433424
System.err.println("Error: Unknown option: " + opt);
434-
showUsage();
435425
return;
436426
}
437427
}
438428
} catch (RuntimeException ex) {
439429
System.err.println("Error: " + ex.toString());
440-
showUsage();
441430
return;
442431
}
443432

@@ -529,7 +518,6 @@ private void runListPermissions() {
529518
dangerousOnly = true;
530519
} else {
531520
System.err.println("Error: Unknown option: " + opt);
532-
showUsage();
533521
return;
534522
}
535523
}
@@ -678,7 +666,6 @@ private void runPath() {
678666
String pkg = nextArg();
679667
if (pkg == null) {
680668
System.err.println("Error: no package specified");
681-
showUsage();
682669
return;
683670
}
684671
displayPackageFilePath(pkg);
@@ -736,20 +723,17 @@ private void runSetInstallLocation() {
736723
String arg = nextArg();
737724
if (arg == null) {
738725
System.err.println("Error: no install location specified.");
739-
showUsage();
740726
return;
741727
}
742728
try {
743729
loc = Integer.parseInt(arg);
744730
} catch (NumberFormatException e) {
745731
System.err.println("Error: install location has to be a number.");
746-
showUsage();
747732
return;
748733
}
749734
try {
750735
if (!mPm.setInstallLocation(loc)) {
751736
System.err.println("Error: install location has to be a number.");
752-
showUsage();
753737
}
754738
} catch (RemoteException e) {
755739
System.err.println(e.toString());
@@ -800,7 +784,6 @@ private void runInstall() {
800784
installerPackageName = nextOptionData();
801785
if (installerPackageName == null) {
802786
System.err.println("Error: no value specified for -i");
803-
showUsage();
804787
return;
805788
}
806789
} else if (opt.equals("-t")) {
@@ -817,61 +800,52 @@ private void runInstall() {
817800
algo = nextOptionData();
818801
if (algo == null) {
819802
System.err.println("Error: must supply argument for --algo");
820-
showUsage();
821803
return;
822804
}
823805
} else if (opt.equals("--iv")) {
824806
iv = hexToBytes(nextOptionData());
825807
if (iv == null) {
826808
System.err.println("Error: must supply argument for --iv");
827-
showUsage();
828809
return;
829810
}
830811
} else if (opt.equals("--key")) {
831812
key = hexToBytes(nextOptionData());
832813
if (key == null) {
833814
System.err.println("Error: must supply argument for --key");
834-
showUsage();
835815
return;
836816
}
837817
} else if (opt.equals("--macalgo")) {
838818
macAlgo = nextOptionData();
839819
if (macAlgo == null) {
840820
System.err.println("Error: must supply argument for --macalgo");
841-
showUsage();
842821
return;
843822
}
844823
} else if (opt.equals("--mackey")) {
845824
macKey = hexToBytes(nextOptionData());
846825
if (macKey == null) {
847826
System.err.println("Error: must supply argument for --mackey");
848-
showUsage();
849827
return;
850828
}
851829
} else if (opt.equals("--tag")) {
852830
tag = hexToBytes(nextOptionData());
853831
if (tag == null) {
854832
System.err.println("Error: must supply argument for --tag");
855-
showUsage();
856833
return;
857834
}
858835
} else if (opt.equals("--originating-uri")) {
859836
originatingUriString = nextOptionData();
860837
if (originatingUriString == null) {
861838
System.err.println("Error: must supply argument for --originating-uri");
862-
showUsage();
863839
return;
864840
}
865841
} else if (opt.equals("--referrer")) {
866842
referrer = nextOptionData();
867843
if (referrer == null) {
868844
System.err.println("Error: must supply argument for --referrer");
869-
showUsage();
870845
return;
871846
}
872847
} else {
873848
System.err.println("Error: Unknown option: " + opt);
874-
showUsage();
875849
return;
876850
}
877851
}
@@ -881,15 +855,13 @@ private void runInstall() {
881855
|| tag != null) {
882856
if (algo == null || iv == null || key == null) {
883857
System.err.println("Error: all of --algo, --iv, and --key must be specified");
884-
showUsage();
885858
return;
886859
}
887860

888861
if (macAlgo != null || macKey != null || tag != null) {
889862
if (macAlgo == null || macKey == null || tag == null) {
890863
System.err.println("Error: all of --macalgo, --mackey, and --tag must "
891864
+ "be specified");
892-
showUsage();
893865
return;
894866
}
895867
}
@@ -938,7 +910,6 @@ private void runInstall() {
938910
apkURI = Uri.fromFile(new File(apkFilePath));
939911
} else {
940912
System.err.println("Error: no package specified");
941-
showUsage();
942913
return;
943914
}
944915

@@ -1012,23 +983,16 @@ private byte[] hexToBytes(String input) {
1012983
}
1013984

1014985
public void runCreateUser() {
1015-
// Need to be run as root
1016-
if (Process.myUid() != ROOT_UID) {
1017-
System.err.println("Error: create-user must be run as root");
1018-
return;
1019-
}
1020986
String name;
1021987
String arg = nextArg();
1022988
if (arg == null) {
1023989
System.err.println("Error: no user name specified.");
1024-
showUsage();
1025990
return;
1026991
}
1027992
name = arg;
1028993
try {
1029994
if (mUm.createUser(name, 0) == null) {
1030995
System.err.println("Error: couldn't create User.");
1031-
showUsage();
1032996
}
1033997
} catch (RemoteException e) {
1034998
System.err.println(e.toString());
@@ -1038,29 +1002,21 @@ public void runCreateUser() {
10381002
}
10391003

10401004
public void runRemoveUser() {
1041-
// Need to be run as root
1042-
if (Process.myUid() != ROOT_UID) {
1043-
System.err.println("Error: remove-user must be run as root");
1044-
return;
1045-
}
10461005
int userId;
10471006
String arg = nextArg();
10481007
if (arg == null) {
10491008
System.err.println("Error: no user id specified.");
1050-
showUsage();
10511009
return;
10521010
}
10531011
try {
10541012
userId = Integer.parseInt(arg);
10551013
} catch (NumberFormatException e) {
1056-
System.err.println("Error: user id has to be a number.");
1057-
showUsage();
1014+
System.err.println("Error: user id '" + arg + "' is not a number.");
10581015
return;
10591016
}
10601017
try {
10611018
if (!mUm.removeUser(userId)) {
1062-
System.err.println("Error: couldn't remove user.");
1063-
showUsage();
1019+
System.err.println("Error: couldn't remove user #" + userId + ".");
10641020
}
10651021
} catch (RemoteException e) {
10661022
System.err.println(e.toString());
@@ -1069,11 +1025,6 @@ public void runRemoveUser() {
10691025
}
10701026

10711027
public void runListUsers() {
1072-
// Need to be run as root
1073-
if (Process.myUid() != ROOT_UID) {
1074-
System.err.println("Error: list-users must be run as root");
1075-
return;
1076-
}
10771028
try {
10781029
List<UserInfo> users = mUm.getUsers();
10791030
if (users == null) {
@@ -1521,6 +1472,8 @@ private static void showUsage() {
15211472
System.err.println("");
15221473
System.err.println("pm list features: prints all features of the system.");
15231474
System.err.println("");
1475+
System.err.println("pm list users: prints all users on the system.");
1476+
System.err.println("");
15241477
System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
15251478
System.err.println("");
15261479
System.err.println("pm install: installs a package to the system. Options:");
@@ -1557,5 +1510,11 @@ private static void showUsage() {
15571510
System.err.println(" 2 [external]: Install on external media");
15581511
System.err.println("");
15591512
System.err.println("pm trim-caches: trim cache files to reach the given free space.");
1513+
System.err.println("");
1514+
System.err.println("pm create-user: create a new user with the given USER_NAME,");
1515+
System.err.println(" printing the new user identifier of the user.");
1516+
System.err.println("");
1517+
System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
1518+
System.err.println(" deleting all data associated with that user");
15601519
}
15611520
}

data/etc/platform.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@
173173
<assign-permission name="android.permission.SET_SCREEN_COMPATIBILITY" uid="shell" />
174174
<assign-permission name="android.permission.READ_EXTERNAL_STORAGE" uid="shell" />
175175
<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />
176-
176+
<assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="shell" />
177+
<assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="shell" />
178+
<assign-permission name="android.permission.MANAGE_USERS" uid="shell" />
179+
177180
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
178181
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
179182
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9404,9 +9404,15 @@ private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
94049404
boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
94059405
int opti, boolean dumpAll, String dumpPackage) {
94069406
boolean needSep = false;
9407-
9407+
boolean onlyHistory = false;
9408+
9409+
if ("history".equals(dumpPackage)) {
9410+
onlyHistory = true;
9411+
dumpPackage = null;
9412+
}
9413+
94089414
pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9409-
if (dumpAll) {
9415+
if (!onlyHistory && dumpAll) {
94109416
if (mRegisteredReceivers.size() > 0) {
94119417
boolean printed = false;
94129418
Iterator it = mRegisteredReceivers.values().iterator();
@@ -9439,7 +9445,7 @@ boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
94399445

94409446
needSep = true;
94419447

9442-
if (mStickyBroadcasts != null && dumpPackage == null) {
9448+
if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
94439449
if (needSep) {
94449450
pw.println();
94459451
}
@@ -9471,7 +9477,7 @@ boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
94719477
needSep = true;
94729478
}
94739479

9474-
if (dumpAll) {
9480+
if (!onlyHistory && dumpAll) {
94759481
pw.println();
94769482
for (BroadcastQueue queue : mBroadcastQueues) {
94779483
pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
@@ -10982,7 +10988,7 @@ public Intent registerReceiver(IApplicationThread caller, String callerPackage,
1098210988
BroadcastQueue queue = broadcastQueueForIntent(intent);
1098310989
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
1098410990
null, -1, -1, null, receivers, null, 0, null, null,
10985-
false, true, true, false);
10991+
false, true, true, false, -1);
1098610992
queue.enqueueParallelBroadcastLocked(r);
1098710993
queue.scheduleBroadcastsLocked();
1098810994
}
@@ -11288,7 +11294,7 @@ private final int broadcastIntentLocked(ProcessRecord callerApp,
1128811294
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
1128911295
callerPackage, callingPid, callingUid, requiredPermission,
1129011296
registeredReceivers, resultTo, resultCode, resultData, map,
11291-
ordered, sticky, false, onlySendToCaller);
11297+
ordered, sticky, false, onlySendToCaller, userId);
1129211298
if (DEBUG_BROADCAST) Slog.v(
1129311299
TAG, "Enqueueing parallel broadcast " + r);
1129411300
final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
@@ -11378,7 +11384,7 @@ private final int broadcastIntentLocked(ProcessRecord callerApp,
1137811384
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
1137911385
callerPackage, callingPid, callingUid, requiredPermission,
1138011386
receivers, resultTo, resultCode, resultData, map, ordered,
11381-
sticky, false, onlySendToCaller);
11387+
sticky, false, onlySendToCaller, userId);
1138211388
if (DEBUG_BROADCAST) Slog.v(
1138311389
TAG, "Enqueueing ordered broadcast " + r
1138411390
+ ": prev had " + queue.mOrderedBroadcasts.size());

0 commit comments

Comments
 (0)