From 5e03e2ca7d25b899b129baad2dd5eca6bf99d88a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 6 Sep 2012 14:21:19 -0700 Subject: More multi-user stuff: - New (hidden) isUserRunning() API. - Maintain LRU list of visited users. - New FLAG_IS_DATA_ONLY for ApplicationInfo. - Clean up pending intent records when force-stopping a user (or package). (Also fixes bug #6880627: PendingIntent.getService() returns stale intent of force stopped app) - Fix force-stopping when installing an app to do the force-stop across all users for that app. - When selecting which processes to kill during a force stop, do this based on the actual packages loaded in the process, not just process name matching. - You can now use --user option in am when starting activities, services, and instrumentation. - The am --user option accepts "current" and "all" as arguments. - The pm uninstall command now uninstalls for all users, so it matches the semantics of the install command. - PhoneWindowManager now explicitly says to start home in the current user. - Activity manager call to retrieve the MIME type from a content provider now takes a user argument, so it will direct this to the proper user. - The package manager uninstall paths are now implemented around PackageSetting, not PackageParser.Package. This allows them to work even if the application's apk has been removed (in which case it only exists as a PackageSetting, not the PackageParser.Package parsed from the apk). Change-Id: I3522f6fcf32603090bd6e01cc90ce70b6c5aae40 --- cmds/am/src/com/android/commands/am/Am.java | 47 ++++++++++++++++++++++++----- cmds/pm/src/com/android/commands/pm/Pm.java | 18 +++++------ 2 files changed, 49 insertions(+), 16 deletions(-) (limited to 'cmds') diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index bcd4588..f4dcc3a 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -36,6 +36,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.UserHandle; import android.util.AndroidException; import android.view.Display; import android.view.IWindowManager; @@ -147,6 +148,18 @@ public class Am { } } + int parseUserArg(String arg) { + int userId; + if ("all".equals(arg)) { + userId = UserHandle.USER_ALL; + } else if ("current".equals(arg) || "cur".equals(arg)) { + userId = UserHandle.USER_CURRENT; + } else { + userId = Integer.parseInt(arg); + } + return userId; + } + private Intent makeIntent() throws URISyntaxException { Intent intent = new Intent(); Intent baseIntent = intent; @@ -321,7 +334,7 @@ public class Am { } else if (opt.equals("--opengl-trace")) { mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES; } else if (opt.equals("--user")) { - mUserId = Integer.parseInt(nextArgRequired()); + mUserId = parseUserArg(nextArgRequired()); } else { System.err.println("Error: Unknown option: " + opt); return null; @@ -392,8 +405,12 @@ public class Am { private void runStartService() throws Exception { Intent intent = makeIntent(); + if (mUserId == UserHandle.USER_ALL) { + System.err.println("Error: Can't start activity with user 'all'"); + return; + } System.out.println("Starting service: " + intent); - ComponentName cn = mAm.startService(null, intent, intent.getType(), 0); + ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId); if (cn == null) { System.err.println("Error: Not found; no service started."); } @@ -402,10 +419,15 @@ public class Am { private void runStart() throws Exception { Intent intent = makeIntent(); + if (mUserId == UserHandle.USER_ALL) { + System.err.println("Error: Can't start service with user 'all'"); + return; + } + String mimeType = intent.getType(); if (mimeType == null && intent.getData() != null && "content".equals(intent.getData().getScheme())) { - mimeType = mAm.getProviderMimeType(intent.getData()); + mimeType = mAm.getProviderMimeType(intent.getData(), mUserId); } do { @@ -460,11 +482,11 @@ public class Am { int res; if (mWaitOption) { result = mAm.startActivityAndWait(null, intent, mimeType, - null, null, 0, mStartFlags, mProfileFile, fd, null); + null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId); res = result.result; } else { - res = mAm.startActivity(null, intent, mimeType, - null, null, 0, mStartFlags, mProfileFile, fd, null); + res = mAm.startActivityAsUser(null, intent, mimeType, + null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId); } PrintStream out = mWaitOption ? System.out : System.err; boolean launched = false; @@ -573,6 +595,7 @@ public class Am { boolean wait = false; boolean rawMode = false; boolean no_window_animation = false; + int userId = 0; Bundle args = new Bundle(); String argKey = null, argValue = null; IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); @@ -592,12 +615,19 @@ public class Am { } else if (opt.equals("--no_window_animation") || opt.equals("--no-window-animation")) { no_window_animation = true; + } else if (opt.equals("--user")) { + userId = parseUserArg(nextArgRequired()); } else { System.err.println("Error: Unknown option: " + opt); return; } } + if (userId == UserHandle.USER_ALL) { + System.err.println("Error: Can't start instrumentation with user 'all'"); + return; + } + String cnArg = nextArgRequired(); ComponentName cn = ComponentName.unflattenFromString(cnArg); if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg); @@ -614,7 +644,7 @@ public class Am { wm.setAnimationScale(1, 0.0f); } - if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher)) { + if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, userId)) { throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); } @@ -1338,6 +1368,7 @@ public class Am { " am kill-all\n" + " am broadcast \n" + " am instrument [-r] [-e ] [-p ] [-w]\n" + + " [--user | all | current]\n" + " [--no-window-animation] \n" + " am profile start \n" + " am profile stop []\n" + @@ -1384,6 +1415,7 @@ public class Am { " -p : write profiling data to \n" + " -w: wait for instrumentation to finish before returning. Required for\n" + " test runners.\n" + + " --user [ | all | current]: Specify user instrumentation runs in.\n" + " --no-window-animation: turn off window animations will running.\n" + "\n" + "am profile: start and stop profiler on a process.\n" + @@ -1431,6 +1463,7 @@ public class Am { " [--ela [, [,] [-f ]\n" + + " [--user [ | all | current]\n" + " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" + " [--debug-log-resolution] [--exclude-stopped-packages]\n" + " [--include-stopped-packages]\n" + diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 36bf38a..8570f27 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -20,7 +20,6 @@ import com.android.internal.content.PackageHelper; import android.app.ActivityManagerNative; import android.content.ComponentName; -import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ContainerEncryptionParams; import android.content.pm.FeatureInfo; @@ -40,12 +39,9 @@ import android.content.pm.VerificationParams; import android.content.res.AssetManager; import android.content.res.Resources; import android.net.Uri; -import android.os.Binder; import android.os.IUserManager; -import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserManager; import java.io.File; import java.lang.reflect.Field; @@ -74,7 +70,6 @@ public final class Pm { private static final String PM_NOT_RUNNING_ERR = "Error: Could not access the Package Manager. Is the system running?"; - private static final int ROOT_UID = 0; public static void main(String[] args) { new Pm().run(args); @@ -1054,11 +1049,16 @@ public final class Pm { } private void runUninstall() { - int unInstallFlags = 0; + int unInstallFlags = PackageManager.DELETE_ALL_USERS; - String opt = nextOption(); - if (opt != null && opt.equals("-k")) { - unInstallFlags = PackageManager.DELETE_KEEP_DATA; + String opt; + while ((opt=nextOption()) != null) { + if (opt.equals("-k")) { + unInstallFlags |= PackageManager.DELETE_KEEP_DATA; + } else { + System.err.println("Error: Unknown option: " + opt); + return; + } } String pkg = nextArg(); -- cgit v1.1