diff options
author | Amith Yamasani <yamasani@google.com> | 2012-03-13 16:08:00 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2012-03-22 10:08:24 -0700 |
commit | 483f3b06ea84440a082e21b68ec2c2e54046f5a6 (patch) | |
tree | cc0dff8ea3d133a4dc910bc1e90c85380cea2064 | |
parent | 8fca15f1f2273fa429e58f783d0970251d0942e5 (diff) | |
download | frameworks_base-483f3b06ea84440a082e21b68ec2c2e54046f5a6.zip frameworks_base-483f3b06ea84440a082e21b68ec2c2e54046f5a6.tar.gz frameworks_base-483f3b06ea84440a082e21b68ec2c2e54046f5a6.tar.bz2 |
Package restrictions per user
Packages can be enabled/disabled per user.
This requires maintaining stopped/launched states and
enabled / disabled components and packages per user.
Refactored pm.Settings and PackageSettingsBase to keep
track of states per user.
Migrated the stopped-packages.xml to users/<u>/package-restrictions.xml
Changed intent resolution to handle individual user restrictions.
Bunch of IPackageManager calls now have a userId argument.
Make AppWidgetService handle removals of packages.
Added some tests for pm.Settings and PackageManager.
Change-Id: Ia83b529e1df88dbcb3bd55ebfc952a6e9b20e861
25 files changed, 1245 insertions, 562 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index c15c49f..53a0186 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -62,6 +62,7 @@ public class Am { private boolean mStopOption = false; private int mRepeat = 0; + private int mUserId = 0; private String mProfileFile; @@ -135,7 +136,7 @@ public class Am { runToUri(false); } else if (op.equals("to-intent-uri")) { runToUri(true); - } else if (op.equals("switch-profile")) { + } else if (op.equals("switch-user")) { runSwitchUser(); } else { throw new IllegalArgumentException("Unknown command: " + op); @@ -152,6 +153,7 @@ public class Am { mStopOption = false; mRepeat = 0; mProfileFile = null; + mUserId = 0; Uri data = null; String type = null; @@ -308,6 +310,8 @@ public class Am { mStopOption = true; } else if (opt.equals("--opengl-trace")) { mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES; + } else if (opt.equals("--user")) { + mUserId = Integer.parseInt(nextArgRequired()); } else { System.err.println("Error: Unknown option: " + opt); showUsage(); @@ -407,7 +411,8 @@ public class Am { System.err.println("Error: Package manager not running; aborting"); return; } - List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0); + List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0, + mUserId); if (activities == null || activities.size() <= 0) { System.err.println("Error: Intent does not match any activities: " + intent); @@ -550,7 +555,7 @@ public class Am { IntentReceiver receiver = new IntentReceiver(); System.out.println("Broadcasting: " + intent); mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false, - Binder.getOrigCallingUser()); + mUserId); receiver.waitForFinish(); } @@ -1294,6 +1299,7 @@ public class Am { " am display-size [reset|MxN]\n" + " am to-uri [INTENT]\n" + " am to-intent-uri [INTENT]\n" + + " am switch-user <USER_ID>\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index ac5bffe..4d638d0 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -146,18 +146,18 @@ public final class Pm { return; } - if ("create-profile".equals(op)) { - runCreateProfile(); + if ("create-user".equals(op)) { + runCreateUser(); return; } - if ("remove-profile".equals(op)) { - runRemoveProfile(); + if ("remove-user".equals(op)) { + runRemoveUser(); return; } - if ("list-profiles".equals(op)) { - runListProfiles(); + if ("list-users".equals(op)) { + runListUsers(); return; } @@ -215,6 +215,8 @@ public final class Pm { runListLibraries(); } else if ("instrumentation".equals(type)) { runListInstrumentation(); + } else if ("users".equals(type)) { + runListUsers(); } else { System.err.println("Error: unknown list type '" + type + "'"); showUsage(); @@ -832,10 +834,10 @@ public final class Pm { } } - public void runCreateProfile() { + public void runCreateUser() { // Need to be run as root if (Process.myUid() != ROOT_UID) { - System.err.println("Error: create-profile must be run as root"); + System.err.println("Error: create-user must be run as root"); return; } String name; @@ -848,7 +850,7 @@ public final class Pm { name = arg; try { if (mPm.createUser(name, 0) == null) { - System.err.println("Error: couldn't create profile."); + System.err.println("Error: couldn't create User."); showUsage(); } } catch (RemoteException e) { @@ -858,10 +860,10 @@ public final class Pm { } - public void runRemoveProfile() { + public void runRemoveUser() { // Need to be run as root if (Process.myUid() != ROOT_UID) { - System.err.println("Error: remove-profile must be run as root"); + System.err.println("Error: remove-user must be run as root"); return; } int userId; @@ -880,7 +882,7 @@ public final class Pm { } try { if (!mPm.removeUser(userId)) { - System.err.println("Error: couldn't remove profile."); + System.err.println("Error: couldn't remove user."); showUsage(); } } catch (RemoteException e) { @@ -889,10 +891,10 @@ public final class Pm { } } - public void runListProfiles() { + public void runListUsers() { // Need to be run as root if (Process.myUid() != ROOT_UID) { - System.err.println("Error: list-profiles must be run as root"); + System.err.println("Error: list-users must be run as root"); return; } try { @@ -1029,7 +1031,29 @@ public final class Pm { return "unknown"; } + private boolean isNumber(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } + private void runSetEnabledSetting(int state) { + int userId = 0; + String option = nextOption(); + if (option != null && option.equals("--user")) { + String optionData = nextOptionData(); + if (optionData == null || !isNumber(optionData)) { + System.err.println("Error: no USER_ID specified"); + showUsage(); + return; + } else { + userId = Integer.parseInt(optionData); + } + } + String pkg = nextArg(); if (pkg == null) { System.err.println("Error: no package or component specified"); @@ -1039,20 +1063,20 @@ public final class Pm { ComponentName cn = ComponentName.unflattenFromString(pkg); if (cn == null) { try { - mPm.setApplicationEnabledSetting(pkg, state, 0); + mPm.setApplicationEnabledSetting(pkg, state, 0, userId); System.err.println("Package " + pkg + " new state: " + enabledSettingToString( - mPm.getApplicationEnabledSetting(pkg))); + mPm.getApplicationEnabledSetting(pkg, userId))); } catch (RemoteException e) { System.err.println(e.toString()); System.err.println(PM_NOT_RUNNING_ERR); } } else { try { - mPm.setComponentEnabledSetting(cn, state, 0); + mPm.setComponentEnabledSetting(cn, state, 0, userId); System.err.println("Component " + cn.toShortString() + " new state: " + enabledSettingToString( - mPm.getComponentEnabledSetting(cn))); + mPm.getComponentEnabledSetting(cn, userId))); } catch (RemoteException e) { System.err.println(e.toString()); System.err.println(PM_NOT_RUNNING_ERR); @@ -1096,7 +1120,7 @@ public final class Pm { */ private void displayPackageFilePath(String pckg) { try { - PackageInfo info = mPm.getPackageInfo(pckg, 0); + PackageInfo info = mPm.getPackageInfo(pckg, 0, 0); if (info != null && info.applicationInfo != null) { System.out.print("package:"); System.out.println(info.applicationInfo.sourceDir); @@ -1112,7 +1136,7 @@ public final class Pm { if (res != null) return res; try { - ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0); + ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0); AssetManager am = new AssetManager(); am.addAssetPath(ai.publicSourceDir); res = new Resources(am, null, null); @@ -1178,19 +1202,20 @@ public final class Pm { System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); System.err.println(" pm list features"); System.err.println(" pm list libraries"); + System.err.println(" pm list users"); System.err.println(" pm path PACKAGE"); System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH"); System.err.println(" pm uninstall [-k] PACKAGE"); System.err.println(" pm clear PACKAGE"); - System.err.println(" pm enable PACKAGE_OR_COMPONENT"); - System.err.println(" pm disable PACKAGE_OR_COMPONENT"); - System.err.println(" pm disable-user PACKAGE_OR_COMPONENT"); + System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); + System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); + System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT"); System.err.println(" pm grant PACKAGE PERMISSION"); System.err.println(" pm revoke PACKAGE PERMISSION"); System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]"); System.err.println(" pm get-install-location"); - System.err.println(" pm create-profile USER_NAME"); - System.err.println(" pm remove-profile USER_ID"); + System.err.println(" pm create-user USER_NAME"); + System.err.println(" pm remove-user USER_ID"); System.err.println(""); System.err.println("pm list packages: prints all packages, optionally only"); System.err.println(" those whose package name contains the text in FILTER. Options:"); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2a3e213..0860890 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1586,7 +1586,7 @@ public final class ActivityThread { ApplicationInfo ai = null; try { ai = getPackageManager().getApplicationInfo(packageName, - PackageManager.GET_SHARED_LIBRARY_FILES); + PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId()); } catch (RemoteException e) { // Ignore } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 758ce09..f38540c 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -49,6 +49,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Process; import android.os.RemoteException; +import android.os.UserId; import android.util.Log; import java.lang.ref.WeakReference; @@ -67,7 +68,7 @@ final class ApplicationPackageManager extends PackageManager { public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException { try { - PackageInfo pi = mPM.getPackageInfo(packageName, flags); + PackageInfo pi = mPM.getPackageInfo(packageName, flags, UserId.myUserId()); if (pi != null) { return pi; } @@ -197,7 +198,7 @@ final class ApplicationPackageManager extends PackageManager { public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException { try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags); + ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, UserId.myUserId()); if (ai != null) { return ai; } @@ -212,7 +213,7 @@ final class ApplicationPackageManager extends PackageManager { public ActivityInfo getActivityInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ActivityInfo ai = mPM.getActivityInfo(className, flags); + ActivityInfo ai = mPM.getActivityInfo(className, flags, UserId.myUserId()); if (ai != null) { return ai; } @@ -227,7 +228,7 @@ final class ApplicationPackageManager extends PackageManager { public ActivityInfo getReceiverInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ActivityInfo ai = mPM.getReceiverInfo(className, flags); + ActivityInfo ai = mPM.getReceiverInfo(className, flags, UserId.myUserId()); if (ai != null) { return ai; } @@ -242,7 +243,7 @@ final class ApplicationPackageManager extends PackageManager { public ServiceInfo getServiceInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ServiceInfo si = mPM.getServiceInfo(className, flags); + ServiceInfo si = mPM.getServiceInfo(className, flags, UserId.myUserId()); if (si != null) { return si; } @@ -257,7 +258,7 @@ final class ApplicationPackageManager extends PackageManager { public ProviderInfo getProviderInfo(ComponentName className, int flags) throws NameNotFoundException { try { - ProviderInfo pi = mPM.getProviderInfo(className, flags); + ProviderInfo pi = mPM.getProviderInfo(className, flags, UserId.myUserId()); if (pi != null) { return pi; } @@ -422,6 +423,7 @@ final class ApplicationPackageManager extends PackageManager { @SuppressWarnings("unchecked") @Override public List<ApplicationInfo> getInstalledApplications(int flags) { + int userId = UserId.getUserId(Process.myUid()); try { final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); ApplicationInfo lastItem = null; @@ -429,7 +431,7 @@ final class ApplicationPackageManager extends PackageManager { do { final String lastKey = lastItem != null ? lastItem.packageName : null; - slice = mPM.getInstalledApplications(flags, lastKey); + slice = mPM.getInstalledApplications(flags, lastKey, userId); lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); } while (!slice.isLastSlice()); @@ -445,7 +447,7 @@ final class ApplicationPackageManager extends PackageManager { return mPM.resolveIntent( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags); + flags, UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -458,7 +460,8 @@ final class ApplicationPackageManager extends PackageManager { return mPM.queryIntentActivities( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags); + flags, + UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -490,7 +493,7 @@ final class ApplicationPackageManager extends PackageManager { try { return mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent, intent.resolveTypeIfNeeded(resolver), - flags); + flags, UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -502,7 +505,8 @@ final class ApplicationPackageManager extends PackageManager { return mPM.queryIntentReceivers( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags); + flags, + UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -514,7 +518,8 @@ final class ApplicationPackageManager extends PackageManager { return mPM.resolveService( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags); + flags, + UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -526,7 +531,8 @@ final class ApplicationPackageManager extends PackageManager { return mPM.queryIntentServices( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags); + flags, + UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -536,7 +542,7 @@ final class ApplicationPackageManager extends PackageManager { public ProviderInfo resolveContentProvider(String name, int flags) { try { - return mPM.resolveContentProvider(name, flags); + return mPM.resolveContentProvider(name, flags, UserId.myUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } @@ -1026,7 +1032,7 @@ final class ApplicationPackageManager extends PackageManager { public void clearApplicationUserData(String packageName, IPackageDataObserver observer) { try { - mPM.clearApplicationUserData(packageName, observer); + mPM.clearApplicationUserData(packageName, observer, UserId.myUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1139,7 +1145,7 @@ final class ApplicationPackageManager extends PackageManager { public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) { try { - mPM.setComponentEnabledSetting(componentName, newState, flags); + mPM.setComponentEnabledSetting(componentName, newState, flags, UserId.myUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1148,7 +1154,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public int getComponentEnabledSetting(ComponentName componentName) { try { - return mPM.getComponentEnabledSetting(componentName); + return mPM.getComponentEnabledSetting(componentName, UserId.myUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1159,7 +1165,7 @@ final class ApplicationPackageManager extends PackageManager { public void setApplicationEnabledSetting(String packageName, int newState, int flags) { try { - mPM.setApplicationEnabledSetting(packageName, newState, flags); + mPM.setApplicationEnabledSetting(packageName, newState, flags, UserId.myUserId()); } catch (RemoteException e) { // Should never happen! } @@ -1168,7 +1174,7 @@ final class ApplicationPackageManager extends PackageManager { @Override public int getApplicationEnabledSetting(String packageName) { try { - return mPM.getApplicationEnabledSetting(packageName); + return mPM.getApplicationEnabledSetting(packageName, UserId.myUserId()); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index de9470e..5340fbb 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -194,7 +194,7 @@ public final class LoadedApk { ApplicationInfo ai = null; try { ai = ActivityThread.getPackageManager().getApplicationInfo(packageName, - PackageManager.GET_SHARED_LIBRARY_FILES); + PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId()); } catch (RemoteException e) { throw new AssertionError(e); } @@ -351,7 +351,7 @@ public final class LoadedApk { IPackageManager pm = ActivityThread.getPackageManager(); android.content.pm.PackageInfo pi; try { - pi = pm.getPackageInfo(mPackageName, 0); + pi = pm.getPackageInfo(mPackageName, 0, UserId.myUserId()); } catch (RemoteException e) { throw new AssertionError(e); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 9bd1940..d89d2de 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -49,8 +49,8 @@ import android.content.IntentSender; * {@hide} */ interface IPackageManager { - PackageInfo getPackageInfo(String packageName, int flags); - int getPackageUid(String packageName); + PackageInfo getPackageInfo(String packageName, int flags, int userId); + int getPackageUid(String packageName, int userId); int[] getPackageGids(String packageName); String[] currentToCanonicalPackageNames(in String[] names); @@ -64,15 +64,15 @@ interface IPackageManager { List<PermissionGroupInfo> getAllPermissionGroups(int flags); - ApplicationInfo getApplicationInfo(String packageName, int flags); + ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId); - ActivityInfo getActivityInfo(in ComponentName className, int flags); + ActivityInfo getActivityInfo(in ComponentName className, int flags, int userId); - ActivityInfo getReceiverInfo(in ComponentName className, int flags); + ActivityInfo getReceiverInfo(in ComponentName className, int flags, int userId); - ServiceInfo getServiceInfo(in ComponentName className, int flags); + ServiceInfo getServiceInfo(in ComponentName className, int flags, int userId); - ProviderInfo getProviderInfo(in ComponentName className, int flags); + ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId); int checkPermission(String permName, String pkgName); @@ -98,24 +98,24 @@ interface IPackageManager { int getUidForSharedUser(String sharedUserName); - ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags); + ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId); List<ResolveInfo> queryIntentActivities(in Intent intent, - String resolvedType, int flags); + String resolvedType, int flags, int userId); List<ResolveInfo> queryIntentActivityOptions( in ComponentName caller, in Intent[] specifics, in String[] specificTypes, in Intent intent, - String resolvedType, int flags); + String resolvedType, int flags, int userId); List<ResolveInfo> queryIntentReceivers(in Intent intent, - String resolvedType, int flags); + String resolvedType, int flags, int userId); ResolveInfo resolveService(in Intent intent, - String resolvedType, int flags); + String resolvedType, int flags, int userId); List<ResolveInfo> queryIntentServices(in Intent intent, - String resolvedType, int flags); + String resolvedType, int flags, int userId); /** * This implements getInstalledPackages via a "last returned row" @@ -131,7 +131,7 @@ interface IPackageManager { * limit that kicks in when flags are included that bloat up the data * returned. */ - ParceledListSlice getInstalledApplications(int flags, in String lastRead); + ParceledListSlice getInstalledApplications(int flags, in String lastRead, int userId); /** * Retrieve all applications that are marked as persistent. @@ -141,7 +141,7 @@ interface IPackageManager { */ List<ApplicationInfo> getPersistentApplications(int flags); - ProviderInfo resolveContentProvider(String name, int flags); + ProviderInfo resolveContentProvider(String name, int flags, int userId); /** * Retrieve sync information for all content providers. @@ -212,28 +212,28 @@ interface IPackageManager { * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}. */ void setComponentEnabledSetting(in ComponentName componentName, - in int newState, in int flags); + in int newState, in int flags, int userId); /** * As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}. */ - int getComponentEnabledSetting(in ComponentName componentName); + int getComponentEnabledSetting(in ComponentName componentName, int userId); /** * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}. */ - void setApplicationEnabledSetting(in String packageName, in int newState, int flags); + void setApplicationEnabledSetting(in String packageName, in int newState, int flags, int userId); /** * As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}. */ - int getApplicationEnabledSetting(in String packageName); + int getApplicationEnabledSetting(in String packageName, int userId); /** * Set whether the given package should be considered stopped, making * it not visible to implicit intents that filter out stopped packages. */ - void setPackageStoppedState(String packageName, boolean stopped); + void setPackageStoppedState(String packageName, boolean stopped, int userId); /** * Free storage by deleting LRU sorted list of cache files across @@ -296,7 +296,7 @@ interface IPackageManager { * files need to be deleted * @param observer a callback used to notify when the operation is completed. */ - void clearApplicationUserData(in String packageName, IPackageDataObserver observer); + void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId); /** * Get package statistics including the code, data and cache size for diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 207f077..07d231a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -240,7 +240,13 @@ public class PackageParser { int gids[], int flags, long firstInstallTime, long lastUpdateTime, HashSet<String> grantedPermissions) { - final int userId = Binder.getOrigCallingUser(); + return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, + grantedPermissions, UserId.getCallingUserId()); + } + + static PackageInfo generatePackageInfo(PackageParser.Package p, + int gids[], int flags, long firstInstallTime, long lastUpdateTime, + HashSet<String> grantedPermissions, int userId) { PackageInfo pi = new PackageInfo(); pi.packageName = p.packageName; @@ -3350,7 +3356,7 @@ public class PackageParser { } public static ApplicationInfo generateApplicationInfo(Package p, int flags) { - return generateApplicationInfo(p, flags, UserId.getUserId(Binder.getCallingUid())); + return generateApplicationInfo(p, flags, UserId.getCallingUserId()); } public static ApplicationInfo generateApplicationInfo(Package p, int flags, int userId) { @@ -3366,6 +3372,13 @@ public class PackageParser { } else { p.applicationInfo.flags &= ~ApplicationInfo.FLAG_STOPPED; } + if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { + p.applicationInfo.enabled = true; + } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED + || p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { + p.applicationInfo.enabled = false; + } + p.applicationInfo.enabledSetting = p.mSetEnabled; return p.applicationInfo; } diff --git a/core/java/android/os/UserId.java b/core/java/android/os/UserId.java index 0da67d6..2d06ef9 100644 --- a/core/java/android/os/UserId.java +++ b/core/java/android/os/UserId.java @@ -96,4 +96,12 @@ public final class UserId { public static final int getAppId(int uid) { return uid % PER_USER_RANGE; } + + /** + * Returns the user id of the current process + * @return user id of the current process + */ + public static final int myUserId() { + return getUserId(Process.myUid()); + } } diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml index 7fa7658..49c8893 100644 --- a/core/res/res/values-sw600dp/config.xml +++ b/core/res/res/values-sw600dp/config.xml @@ -21,7 +21,7 @@ for different hardware and product builds. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- see comment in values/config.xml --> - <integer name="config_longPressOnPowerBehavior">2</integer> + <integer name="config_longPressOnPowerBehavior">1</integer> <!-- Enable lockscreen rotation --> <bool name="config_enableLockScreenRotation">true</bool> diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java index 2982816..0c31e2d 100755 --- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java +++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; +import android.os.UserId; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; @@ -674,7 +675,7 @@ public class AppCacheTest extends AndroidTestCase { PackageDataObserver observer = new PackageDataObserver(); //wait on observer synchronized(observer) { - getPm().clearApplicationUserData(packageName, observer); + getPm().clearApplicationUserData(packageName, observer, 0 /* TODO: Other users */); long waitTime = 0; while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) { observer.wait(WAIT_TIME_INCR); @@ -717,7 +718,8 @@ public class AppCacheTest extends AndroidTestCase { File getDataDir() { try { - ApplicationInfo appInfo = getPm().getApplicationInfo(mContext.getPackageName(), 0); + ApplicationInfo appInfo = getPm().getApplicationInfo(mContext.getPackageName(), 0, + UserId.myUserId()); return new File(appInfo.dataDir); } catch (RemoteException e) { throw new RuntimeException("Pacakge manager dead", e); @@ -746,7 +748,7 @@ public class AppCacheTest extends AndroidTestCase { @LargeTest public void testClearApplicationUserDataNoObserver() throws Exception { - getPm().clearApplicationUserData(mContext.getPackageName(), null); + getPm().clearApplicationUserData(mContext.getPackageName(), null, UserId.myUserId()); //sleep for 1 minute Thread.sleep(60*1000); //confirm files dont exist diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java index 090c0cb..07f9e91 100644 --- a/opengl/java/com/google/android/gles_jni/GLImpl.java +++ b/opengl/java/com/google/android/gles_jni/GLImpl.java @@ -23,6 +23,7 @@ import android.app.AppGlobals; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.os.Build; +import android.os.UserId; import android.util.Log; import java.nio.Buffer; @@ -67,7 +68,7 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack { int version = 0; IPackageManager pm = AppGlobals.getPackageManager(); try { - ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0); + ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserId.myUserId()); if (applicationInfo != null) { version = applicationInfo.targetSdkVersion; } diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 081f1f4..a85b605 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -325,9 +325,10 @@ class AppWidgetService extends IAppWidgetService.Stub service.onConfigurationChanged(); } } else { - // TODO: Verify that this only needs to be delivered for the related user and not - // all the users - getImplForUser().onBroadcastReceived(intent); + for (int i = 0; i < mAppWidgetServices.size(); i++) { + AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); + service.onBroadcastReceived(intent); + } } } }; diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index 9c408c4..182a884 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -17,6 +17,7 @@ package com.android.server; import android.app.AlarmManager; +import android.app.AppGlobals; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; @@ -27,6 +28,7 @@ import android.content.ServiceConnection; import android.content.Intent.FilterComparison; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -158,7 +160,7 @@ class AppWidgetServiceImpl { Context mContext; Locale mLocale; - PackageManager mPackageManager; + IPackageManager mPm; AlarmManager mAlarmManager; ArrayList<Provider> mInstalledProviders = new ArrayList<Provider>(); int mNextAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID + 1; @@ -174,7 +176,7 @@ class AppWidgetServiceImpl { AppWidgetServiceImpl(Context context, int userId) { mContext = context; - mPackageManager = context.getPackageManager(); + mPm = AppGlobals.getPackageManager(); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mUserId = userId; } @@ -1009,16 +1011,19 @@ class AppWidgetServiceImpl { } void loadAppWidgetList() { - PackageManager pm = mPackageManager; - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); - List<ResolveInfo> broadcastReceivers = pm.queryBroadcastReceivers(intent, - PackageManager.GET_META_DATA); + try { + List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent, + intent.resolveTypeIfNeeded(mContext.getContentResolver()), + PackageManager.GET_META_DATA, mUserId); - final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); - for (int i = 0; i < N; i++) { - ResolveInfo ri = broadcastReceivers.get(i); - addProviderLocked(ri); + final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); + for (int i = 0; i < N; i++) { + ResolveInfo ri = broadcastReceivers.get(i); + addProviderLocked(ri); + } + } catch (RemoteException re) { + // Shouldn't happen, local call } } @@ -1131,7 +1136,7 @@ class AppWidgetServiceImpl { ActivityInfo activityInfo = ri.activityInfo; XmlResourceParser parser = null; try { - parser = activityInfo.loadXmlMetaData(mPackageManager, + parser = activityInfo.loadXmlMetaData(mContext.getPackageManager(), AppWidgetManager.META_DATA_APPWIDGET_PROVIDER); if (parser == null) { Slog.w(TAG, "No " + AppWidgetManager.META_DATA_APPWIDGET_PROVIDER @@ -1159,7 +1164,7 @@ class AppWidgetServiceImpl { info.provider = component; p.uid = activityInfo.applicationInfo.uid; - Resources res = mPackageManager + Resources res = mContext.getPackageManager() .getResourcesForApplication(activityInfo.applicationInfo); TypedArray sa = res.obtainAttributes(attrs, @@ -1188,7 +1193,7 @@ class AppWidgetServiceImpl { if (className != null) { info.configure = new ComponentName(component.getPackageName(), className); } - info.label = activityInfo.loadLabel(mPackageManager).toString(); + info.label = activityInfo.loadLabel(mContext.getPackageManager()).toString(); info.icon = ri.getIconResource(); info.previewImage = sa.getResourceId( com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, 0); @@ -1213,7 +1218,12 @@ class AppWidgetServiceImpl { } int getUidForPackage(String packageName) throws PackageManager.NameNotFoundException { - PackageInfo pkgInfo = mPackageManager.getPackageInfo(packageName, 0); + PackageInfo pkgInfo = null; + try { + pkgInfo = mPm.getPackageInfo(packageName, 0, mUserId); + } catch (RemoteException re) { + // Shouldn't happen, local call + } if (pkgInfo == null || pkgInfo.applicationInfo == null) { throw new PackageManager.NameNotFoundException(); } @@ -1493,9 +1503,15 @@ class AppWidgetServiceImpl { void addProvidersForPackageLocked(String pkgName) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); - List<ResolveInfo> broadcastReceivers = mPackageManager.queryBroadcastReceivers(intent, - PackageManager.GET_META_DATA); - + List<ResolveInfo> broadcastReceivers; + try { + broadcastReceivers = mPm.queryIntentReceivers(intent, + intent.resolveTypeIfNeeded(mContext.getContentResolver()), + PackageManager.GET_META_DATA, mUserId); + } catch (RemoteException re) { + // Shouldn't happen, local call + return; + } final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); for (int i = 0; i < N; i++) { ResolveInfo ri = broadcastReceivers.get(i); @@ -1513,8 +1529,15 @@ class AppWidgetServiceImpl { HashSet<String> keep = new HashSet<String>(); Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); - List<ResolveInfo> broadcastReceivers = mPackageManager.queryBroadcastReceivers(intent, - PackageManager.GET_META_DATA); + List<ResolveInfo> broadcastReceivers; + try { + broadcastReceivers = mPm.queryIntentReceivers(intent, + intent.resolveTypeIfNeeded(mContext.getContentResolver()), + PackageManager.GET_META_DATA, mUserId); + } catch (RemoteException re) { + // Shouldn't happen, local call + return; + } // add the missing ones and collect which ones to keep int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java index b3d7220..f7e841e 100644 --- a/services/java/com/android/server/IntentResolver.java +++ b/services/java/com/android/server/IntentResolver.java @@ -201,7 +201,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } public List<R> queryIntentFromList(Intent intent, String resolvedType, - boolean defaultOnly, ArrayList<ArrayList<F>> listCut) { + boolean defaultOnly, ArrayList<ArrayList<F>> listCut, int userId) { ArrayList<R> resultList = new ArrayList<R>(); final boolean debug = localLOGV || @@ -212,13 +212,14 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { int N = listCut.size(); for (int i = 0; i < N; ++i) { buildResolveList(intent, categories, debug, defaultOnly, - resolvedType, scheme, listCut.get(i), resultList); + resolvedType, scheme, listCut.get(i), resultList, userId); } sortResults(resultList); return resultList; } - public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { + public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, + int userId) { String scheme = intent.getScheme(); ArrayList<R> finalList = new ArrayList<R>(); @@ -290,19 +291,19 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { FastImmutableArraySet<String> categories = getFastIntentCategories(intent); if (firstTypeCut != null) { buildResolveList(intent, categories, debug, defaultOnly, - resolvedType, scheme, firstTypeCut, finalList); + resolvedType, scheme, firstTypeCut, finalList, userId); } if (secondTypeCut != null) { buildResolveList(intent, categories, debug, defaultOnly, - resolvedType, scheme, secondTypeCut, finalList); + resolvedType, scheme, secondTypeCut, finalList, userId); } if (thirdTypeCut != null) { buildResolveList(intent, categories, debug, defaultOnly, - resolvedType, scheme, thirdTypeCut, finalList); + resolvedType, scheme, thirdTypeCut, finalList, userId); } if (schemeCut != null) { buildResolveList(intent, categories, debug, defaultOnly, - resolvedType, scheme, schemeCut, finalList); + resolvedType, scheme, schemeCut, finalList, userId); } sortResults(finalList); @@ -329,7 +330,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { * "stopped," that is whether it should not be included in the result * if the intent requests to excluded stopped objects. */ - protected boolean isFilterStopped(F filter) { + protected boolean isFilterStopped(F filter, int userId) { return false; } @@ -341,7 +342,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { protected abstract String packageForFilter(F filter); @SuppressWarnings("unchecked") - protected R newResult(F filter, int match) { + protected R newResult(F filter, int match, int userId) { return (R)filter; } @@ -504,7 +505,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, boolean debug, boolean defaultOnly, - String resolvedType, String scheme, List<F> src, List<R> dest) { + String resolvedType, String scheme, List<F> src, List<R> dest, int userId) { final String action = intent.getAction(); final Uri data = intent.getData(); final String packageName = intent.getPackage(); @@ -519,7 +520,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { int match; if (debug) Slog.v(TAG, "Matching against filter " + filter); - if (excludingStopped && isFilterStopped(filter)) { + if (excludingStopped && isFilterStopped(filter, userId)) { if (debug) { Slog.v(TAG, " Filter's target is stopped; skipping"); } @@ -547,7 +548,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { if (debug) Slog.v(TAG, " Filter matched! match=0x" + Integer.toHexString(match)); if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { - final R oneResult = newResult(filter, match); + final R oneResult = newResult(filter, match, userId); if (oneResult != null) { dest.add(oneResult); } diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 366160b..510bdb2 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -48,6 +48,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.UserId; import android.os.storage.IMountService; import android.os.storage.IMountServiceListener; import android.os.storage.IMountShutdownObserver; @@ -1674,7 +1675,7 @@ class MountService extends IMountService.Stub return false; } - final int packageUid = mPms.getPackageUid(packageName); + final int packageUid = mPms.getPackageUid(packageName, UserId.getUserId(callerUid)); if (DEBUG_OBB) { Slog.d(TAG, "packageName = " + packageName + ", packageUid = " + diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d21212f..8b159d0 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1079,7 +1079,8 @@ public final class ActivityManagerService extends ActivityManagerNative int uid = msg.arg1; boolean restart = (msg.arg2 == 1); String pkg = (String) msg.obj; - forceStopPackageLocked(pkg, uid, restart, false, true, false); + forceStopPackageLocked(pkg, uid, restart, false, true, false, + UserId.getUserId(uid)); } } break; case FINALIZE_PENDING_INTENT_MSG: { @@ -1289,7 +1290,7 @@ public final class ActivityManagerService extends ActivityManagerNative ApplicationInfo info = mSelf.mContext.getPackageManager().getApplicationInfo( - "android", STOCK_PM_FLAGS); + "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info); synchronized (mSelf) { @@ -2369,7 +2370,8 @@ public final class ActivityManagerService extends ActivityManagerNative List<ResolveInfo> resolves = AppGlobals.getPackageManager().queryIntentActivities( intent, r.resolvedType, - PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); + PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, + UserId.getCallingUserId()); // Look for the original activity in the list... final int N = resolves != null ? resolves.size() : 0; @@ -3291,7 +3293,7 @@ public final class ActivityManagerService extends ActivityManagerNative int pkgUid = -1; synchronized(this) { try { - pkgUid = pm.getPackageUid(packageName); + pkgUid = pm.getPackageUid(packageName, userId); } catch (RemoteException e) { } if (pkgUid == -1) { @@ -3312,7 +3314,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { //clear application user data - pm.clearApplicationUserData(packageName, observer); + pm.clearApplicationUserData(packageName, observer, userId); Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, Uri.fromParts("package", packageName, null)); intent.putExtra(Intent.EXTRA_UID, pkgUid); @@ -3339,13 +3341,14 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } + int userId = UserId.getCallingUserId(); long callingId = Binder.clearCallingIdentity(); try { IPackageManager pm = AppGlobals.getPackageManager(); int pkgUid = -1; synchronized(this) { try { - pkgUid = pm.getPackageUid(packageName); + pkgUid = pm.getPackageUid(packageName, userId); } catch (RemoteException e) { } if (pkgUid == -1) { @@ -3412,16 +3415,14 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, msg); throw new SecurityException(msg); } - final int userId = Binder.getOrigCallingUser(); + final int userId = UserId.getCallingUserId(); long callingId = Binder.clearCallingIdentity(); try { IPackageManager pm = AppGlobals.getPackageManager(); int pkgUid = -1; synchronized(this) { try { - pkgUid = pm.getPackageUid(packageName); - // Convert the uid to the one for the calling user - pkgUid = UserId.getUid(userId, pkgUid); + pkgUid = pm.getPackageUid(packageName, userId); } catch (RemoteException e) { } if (pkgUid == -1) { @@ -3430,7 +3431,7 @@ public final class ActivityManagerService extends ActivityManagerNative } forceStopPackageLocked(packageName, pkgUid); try { - pm.setPackageStoppedState(packageName, true); + pm.setPackageStoppedState(packageName, true, userId); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -3545,7 +3546,7 @@ public final class ActivityManagerService extends ActivityManagerNative } private void forceStopPackageLocked(final String packageName, int uid) { - forceStopPackageLocked(packageName, uid, false, false, true, false); + forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, Uri.fromParts("package", packageName, null)); if (!mProcessesReady) { @@ -3602,13 +3603,13 @@ public final class ActivityManagerService extends ActivityManagerNative private final boolean forceStopPackageLocked(String name, int uid, boolean callerWillRestart, boolean purgeCache, boolean doit, - boolean evenPersistent) { + boolean evenPersistent, int userId) { int i; int N; if (uid < 0) { try { - uid = AppGlobals.getPackageManager().getPackageUid(name); + uid = AppGlobals.getPackageManager().getPackageUid(name, userId); } catch (RemoteException e) { } } @@ -3659,7 +3660,6 @@ public final class ActivityManagerService extends ActivityManagerNative } ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); - int userId = UserId.getUserId(uid); for (ServiceRecord service : mServiceMap.getAllServices(userId)) { if (service.packageName.equals(name) && (service.app == null || evenPersistent || !service.app.persistent)) { @@ -4107,11 +4107,11 @@ public final class ActivityManagerService extends ActivityManagerNative if (pkgs != null) { for (String pkg : pkgs) { synchronized (ActivityManagerService.this) { - if (forceStopPackageLocked(pkg, -1, false, false, false, false)) { - setResultCode(Activity.RESULT_OK); - return; - } - } + if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { + setResultCode(Activity.RESULT_OK); + return; + } + } } } } @@ -4290,8 +4290,8 @@ public final class ActivityManagerService extends ActivityManagerNative try { if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { int uid = AppGlobals.getPackageManager() - .getPackageUid(packageName); - if (UserId.getAppId(callingUid) != uid) { + .getPackageUid(packageName, UserId.getUserId(callingUid)); + if (!UserId.isSameApp(callingUid, uid)) { String msg = "Permission Denial: getIntentSender() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() @@ -4386,7 +4386,7 @@ public final class ActivityManagerService extends ActivityManagerNative PendingIntentRecord rec = (PendingIntentRecord)sender; try { int uid = AppGlobals.getPackageManager() - .getPackageUid(rec.key.packageName); + .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); if (!UserId.isSameApp(uid, Binder.getCallingUid())) { String msg = "Permission Denial: cancelIntentSender() from pid=" + Binder.getCallingPid() @@ -4796,7 +4796,7 @@ public final class ActivityManagerService extends ActivityManagerNative } else { try { pi = pm.resolveContentProvider(name, - PackageManager.GET_URI_PERMISSION_PATTERNS); + PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); } catch (RemoteException ex) { } } @@ -4808,7 +4808,7 @@ public final class ActivityManagerService extends ActivityManagerNative int targetUid = lastTargetUid; if (targetUid < 0 && targetPkg != null) { try { - targetUid = pm.getPackageUid(targetPkg); + targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); if (targetUid < 0) { if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg); @@ -5100,14 +5100,14 @@ public final class ActivityManagerService extends ActivityManagerNative final String authority = uri.getAuthority(); ProviderInfo pi = null; - ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, - UserId.getUserId(callingUid)); + int userId = UserId.getUserId(callingUid); + ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); if (cpr != null) { pi = cpr.info; } else { try { pi = pm.resolveContentProvider(authority, - PackageManager.GET_URI_PERMISSION_PATTERNS); + PackageManager.GET_URI_PERMISSION_PATTERNS, userId); } catch (RemoteException ex) { } } @@ -5202,7 +5202,7 @@ public final class ActivityManagerService extends ActivityManagerNative } else { try { pi = pm.resolveContentProvider(authority, - PackageManager.GET_URI_PERMISSION_PATTERNS); + PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); } catch (RemoteException ex) { } } @@ -5480,12 +5480,13 @@ public final class ActivityManagerService extends ActivityManagerNative // Check whether this activity is currently available. try { if (rti.origActivity != null) { - if (pm.getActivityInfo(rti.origActivity, 0) == null) { + if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) + == null) { continue; } } else if (rti.baseIntent != null) { if (pm.queryIntentActivities(rti.baseIntent, - null, 0) == null) { + null, 0, callingUserId) == null) { continue; } } @@ -6132,15 +6133,14 @@ public final class ActivityManagerService extends ActivityManagerNative try { cpi = AppGlobals.getPackageManager(). resolveContentProvider(name, - STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); + STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); } catch (RemoteException ex) { } if (cpi == null) { return null; } - cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, - Binder.getOrigCallingUser()); + cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); String msg; if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { @@ -6157,7 +6157,7 @@ public final class ActivityManagerService extends ActivityManagerNative } ComponentName comp = new ComponentName(cpi.packageName, cpi.name); - cpr = mProviderMap.getProviderByClass(comp, Binder.getOrigCallingUser()); + cpr = mProviderMap.getProviderByClass(comp, userId); final boolean firstClass = cpr == null; if (firstClass) { try { @@ -6165,13 +6165,13 @@ public final class ActivityManagerService extends ActivityManagerNative AppGlobals.getPackageManager(). getApplicationInfo( cpi.applicationInfo.packageName, - STOCK_PM_FLAGS); + STOCK_PM_FLAGS, userId); if (ai == null) { Slog.w(TAG, "No package info for content provider " + cpi.name); return null; } - ai = getAppInfoForUser(ai, Binder.getOrigCallingUser()); + ai = getAppInfoForUser(ai, userId); cpr = new ContentProviderRecord(this, cpi, ai, comp); } catch (RemoteException ex) { // pm is in same process, this will never happen. @@ -6212,7 +6212,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Content provider is now in use, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( - cpr.appInfo.packageName, false); + cpr.appInfo.packageName, false, userId); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -6546,7 +6546,7 @@ public final class ActivityManagerService extends ActivityManagerNative // This package really, really can not be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( - info.packageName, false); + info.packageName, false, UserId.getUserId(app.uid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -6778,7 +6778,7 @@ public final class ActivityManagerService extends ActivityManagerNative mDebugTransient = !persistent; if (packageName != null) { final long origId = Binder.clearCallingIdentity(); - forceStopPackageLocked(packageName, -1, false, false, true, true); + forceStopPackageLocked(packageName, -1, false, false, true, true, 0); Binder.restoreCallingIdentity(origId); } } @@ -7137,7 +7137,7 @@ public final class ActivityManagerService extends ActivityManagerNative List<ResolveInfo> ris = null; try { ris = AppGlobals.getPackageManager().queryIntentReceivers( - intent, null, 0); + intent, null, 0, 0); } catch (RemoteException e) { } if (ris != null) { @@ -7803,7 +7803,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (String pkg : process.pkgList) { sb.append("Package: ").append(pkg); try { - PackageInfo pi = pm.getPackageInfo(pkg, 0); + PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); if (pi != null) { sb.append(" v").append(pi.versionCode); if (pi.versionName != null) { @@ -8201,7 +8201,7 @@ public final class ActivityManagerService extends ActivityManagerNative IPackageManager pm = AppGlobals.getPackageManager(); for (String pkg : extList) { try { - ApplicationInfo info = pm.getApplicationInfo(pkg, 0); + ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { retList.add(info); } @@ -10682,21 +10682,21 @@ public final class ActivityManagerService extends ActivityManagerNative }; private ServiceLookupResult findServiceLocked(Intent service, - String resolvedType) { + String resolvedType, int userId) { ServiceRecord r = null; if (service.getComponent() != null) { - r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser()); + r = mServiceMap.getServiceByName(service.getComponent(), userId); } if (r == null) { Intent.FilterComparison filter = new Intent.FilterComparison(service); - r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser()); + r = mServiceMap.getServiceByIntent(filter, userId); } if (r == null) { try { ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService( - service, resolvedType, 0); + service, resolvedType, 0, userId); ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { @@ -10767,7 +10767,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService( - service, resolvedType, STOCK_PM_FLAGS); + service, resolvedType, STOCK_PM_FLAGS, userId); ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { @@ -11132,7 +11132,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Service is now being launched, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( - r.packageName, false); + r.packageName, false, r.userId); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -11437,7 +11437,8 @@ public final class ActivityManagerService extends ActivityManagerNative } // If this service is active, make sure it is stopped. - ServiceLookupResult r = findServiceLocked(service, resolvedType); + ServiceLookupResult r = findServiceLocked(service, resolvedType, + callerApp == null ? UserId.getCallingUserId() : callerApp.userId); if (r != null) { if (r.record != null) { final long origId = Binder.clearCallingIdentity(); @@ -11465,7 +11466,8 @@ public final class ActivityManagerService extends ActivityManagerNative IBinder ret = null; synchronized(this) { - ServiceLookupResult r = findServiceLocked(service, resolvedType); + ServiceLookupResult r = findServiceLocked(service, resolvedType, + UserId.getCallingUserId()); if (r != null) { // r.record is null if findServiceLocked() failed the caller permission check @@ -12094,7 +12096,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Backup agent is now in use, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( - app.packageName, false); + app.packageName, false, UserId.getUserId(app.uid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -12458,7 +12460,7 @@ public final class ActivityManagerService extends ActivityManagerNative String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); if (list != null && (list.length > 0)) { for (String pkg : list) { - forceStopPackageLocked(pkg, -1, false, true, true, false); + forceStopPackageLocked(pkg, -1, false, true, true, false, userId); } sendPackageBroadcastLocked( IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); @@ -12469,7 +12471,8 @@ public final class ActivityManagerService extends ActivityManagerNative if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { forceStopPackageLocked(ssp, - intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false); + intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, + false, userId); } if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, @@ -12586,7 +12589,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (intent.getComponent() != null) { // Broadcast is going to one specific receiver class... ActivityInfo ai = AppGlobals.getPackageManager(). - getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); + getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId); if (ai != null) { receivers = new ArrayList(); ResolveInfo ri = new ResolveInfo(); @@ -12594,15 +12597,15 @@ public final class ActivityManagerService extends ActivityManagerNative receivers.add(ri); } } else { - // TODO: Apply userId // Need to resolve the intent to interested receivers... if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { receivers = AppGlobals.getPackageManager().queryIntentReceivers( - intent, resolvedType, STOCK_PM_FLAGS); + intent, resolvedType, STOCK_PM_FLAGS, userId); } - registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); + registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, + userId); } } catch (RemoteException ex) { // pm is in same process, this will never happen. @@ -12893,7 +12896,7 @@ public final class ActivityManagerService extends ActivityManagerNative ii = mContext.getPackageManager().getInstrumentationInfo( className, STOCK_PM_FLAGS); ai = mContext.getPackageManager().getApplicationInfo( - ii.targetPackage, STOCK_PM_FLAGS); + ii.targetPackage, STOCK_PM_FLAGS); } catch (PackageManager.NameNotFoundException e) { } if (ii == null) { @@ -12921,9 +12924,10 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } + int userId = UserId.getCallingUserId(); final long origId = Binder.clearCallingIdentity(); // Instrumentation can kill and relaunch even persistent processes - forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true); + forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); ProcessRecord app = addAppLocked(ai, false); app.instrumentationClass = className; app.instrumentationInfo = ai; @@ -12978,11 +12982,12 @@ public final class ActivityManagerService extends ActivityManagerNative app.instrumentationProfileFile = null; app.instrumentationArguments = null; - forceStopPackageLocked(app.processName, -1, false, false, true, true); + forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); } public void finishInstrumentation(IApplicationThread target, int resultCode, Bundle results) { + int userId = UserId.getCallingUserId(); // Refuse possible leaked file descriptors if (results != null && results.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 7e8df35..48b4f4f 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1445,9 +1445,8 @@ final class ActivityStack { // Launching this app's activity, make sure the app is no longer // considered stopped. try { - // TODO: Apply to the correct userId AppGlobals.getPackageManager().setPackageStoppedState( - next.packageName, false); + next.packageName, false, next.userId); /* TODO: Verify if correct userid */ } catch (RemoteException e1) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " @@ -2847,7 +2846,7 @@ final class ActivityStack { } ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, - String profileFile, ParcelFileDescriptor profileFd) { + String profileFile, ParcelFileDescriptor profileFd, int userId) { // Collect information about the target of the Intent. ActivityInfo aInfo; try { @@ -2855,7 +2854,7 @@ final class ActivityStack { AppGlobals.getPackageManager().resolveIntent( intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY - | ActivityManagerService.STOCK_PM_FLAGS); + | ActivityManagerService.STOCK_PM_FLAGS, userId); aInfo = rInfo != null ? rInfo.activityInfo : null; } catch (RemoteException e) { aInfo = null; @@ -2909,7 +2908,7 @@ final class ActivityStack { // Collect information about the target of the Intent. ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, - profileFile, profileFd); + profileFile, profileFd, userId); aInfo = mService.getActivityInfoForUser(aInfo, userId); synchronized (mService) { @@ -2989,7 +2988,7 @@ final class ActivityStack { AppGlobals.getPackageManager().resolveIntent( intent, null, PackageManager.MATCH_DEFAULT_ONLY - | ActivityManagerService.STOCK_PM_FLAGS); + | ActivityManagerService.STOCK_PM_FLAGS, userId); aInfo = rInfo != null ? rInfo.activityInfo : null; aInfo = mService.getActivityInfoForUser(aInfo, userId); } catch (RemoteException e) { @@ -3098,7 +3097,7 @@ final class ActivityStack { // Collect information about the target of the Intent. ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], - 0, null, null); + 0, null, null, userId); // TODO: New, check if this is correct aInfo = mService.getActivityInfoForUser(aInfo, userId); diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index 39b63db..1b83e0b 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -732,7 +732,7 @@ public class BroadcastQueue { // Broadcast is being executed, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( - r.curComponent.getPackageName(), false); + r.curComponent.getPackageName(), false, UserId.getUserId(r.callingUid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index cd72202..3ba3fbb 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -121,7 +121,7 @@ public class CompatModePackages { public void handlePackageAddedLocked(String packageName, boolean updated) { ApplicationInfo ai = null; try { - ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0); + ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); } catch (RemoteException e) { } if (ai == null) { @@ -220,7 +220,7 @@ public class CompatModePackages { public int getPackageScreenCompatModeLocked(String packageName) { ApplicationInfo ai = null; try { - ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0); + ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); } catch (RemoteException e) { } if (ai == null) { @@ -232,7 +232,7 @@ public class CompatModePackages { public void setPackageScreenCompatModeLocked(String packageName, int mode) { ApplicationInfo ai = null; try { - ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0); + ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); } catch (RemoteException e) { } if (ai == null) { @@ -365,7 +365,7 @@ public class CompatModePackages { } ApplicationInfo ai = null; try { - ai = pm.getApplicationInfo(pkg, 0); + ai = pm.getApplicationInfo(pkg, 0, 0); } catch (RemoteException e) { } if (ai == null) { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index bc98f86..95666c0 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -395,7 +395,7 @@ public class PackageManagerService extends IPackageManager.Stub { static final int MCS_GIVE_UP = 11; static final int UPDATED_MEDIA_STATUS = 12; static final int WRITE_SETTINGS = 13; - static final int WRITE_STOPPED_PACKAGES = 14; + static final int WRITE_PACKAGE_RESTRICTIONS = 14; static final int PACKAGE_VERIFIED = 15; static final int CHECK_PENDING_VERIFICATION = 16; @@ -406,6 +406,9 @@ public class PackageManagerService extends IPackageManager.Stub { final UserManager mUserManager; + // Stores a list of users whose package restrictions file needs to be updated + private HashSet<Integer> mDirtyUsers = new HashSet<Integer>(); + final private DefaultContainerConnection mDefContainerConn = new DefaultContainerConnection(); class DefaultContainerConnection implements ServiceConnection { @@ -629,7 +632,7 @@ public class PackageManagerService extends IPackageManager.Stub { packages[i] = ent.getKey(); components[i] = ent.getValue(); PackageSetting ps = mSettings.mPackages.get(ent.getKey()); - uids[i] = (ps != null) ? ps.userId : -1; + uids[i] = (ps != null) ? ps.uid : -1; i++; } size = i; @@ -735,16 +738,20 @@ public class PackageManagerService extends IPackageManager.Stub { Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); synchronized (mPackages) { removeMessages(WRITE_SETTINGS); - removeMessages(WRITE_STOPPED_PACKAGES); + removeMessages(WRITE_PACKAGE_RESTRICTIONS); mSettings.writeLPr(); + mDirtyUsers.clear(); } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } break; - case WRITE_STOPPED_PACKAGES: { + case WRITE_PACKAGE_RESTRICTIONS: { Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); synchronized (mPackages) { - removeMessages(WRITE_STOPPED_PACKAGES); - mSettings.writeStoppedLPr(); + removeMessages(WRITE_PACKAGE_RESTRICTIONS); + for (int userId : mDirtyUsers) { + mSettings.writePackageRestrictionsLPr(userId); + } + mDirtyUsers.clear(); } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } break; @@ -811,10 +818,11 @@ public class PackageManagerService extends IPackageManager.Stub { mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); } } - - void scheduleWriteStoppedPackagesLocked() { - if (!mHandler.hasMessages(WRITE_STOPPED_PACKAGES)) { - mHandler.sendEmptyMessageDelayed(WRITE_STOPPED_PACKAGES, WRITE_SETTINGS_DELAY); + + void scheduleWritePackageRestrictionsLocked(int userId) { + mDirtyUsers.add(userId); + if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { + mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); } } @@ -916,7 +924,7 @@ public class PackageManagerService extends IPackageManager.Stub { readPermissions(); - mRestoredSettings = mSettings.readLPw(); + mRestoredSettings = mSettings.readLPw(getUsers()); long startTime = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, @@ -1180,7 +1188,7 @@ public class PackageManagerService extends IPackageManager.Stub { private String getRequiredVerifierLPr() { final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, - PackageManager.GET_DISABLED_COMPONENTS); + PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); String requiredVerifier = null; @@ -1512,7 +1520,8 @@ public class PackageManagerService extends IPackageManager.Stub { ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions); } - public PackageInfo getPackageInfo(String packageName, int flags) { + @Override + public PackageInfo getPackageInfo(String packageName, int flags, int userId) { // reader synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -1522,7 +1531,7 @@ public class PackageManagerService extends IPackageManager.Stub { return generatePackageInfo(p, flags); } if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { - return generatePackageInfoFromSettingsLPw(packageName, flags); + return generatePackageInfoFromSettingsLPw(packageName, flags, userId); } } return null; @@ -1551,20 +1560,21 @@ public class PackageManagerService extends IPackageManager.Stub { } return out; } - - public int getPackageUid(String packageName) { + + @Override + public int getPackageUid(String packageName, int userId) { // reader synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); if(p != null) { - return p.applicationInfo.uid; + return UserId.getUid(userId, p.applicationInfo.uid); } PackageSetting ps = mSettings.mPackages.get(packageName); if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { return -1; } p = ps.pkg; - return p != null ? p.applicationInfo.uid : -1; + return p != null ? UserId.getUid(userId, p.applicationInfo.uid) : -1; } } @@ -1652,11 +1662,12 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags) { + private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, + int userId) { PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null) { if (ps.pkg == null) { - PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, flags); + PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, flags, userId); if (pInfo != null) { return pInfo.applicationInfo; } @@ -1667,7 +1678,8 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags) { + private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, + int userId) { PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null) { if (ps.pkg == null) { @@ -1679,15 +1691,16 @@ public class PackageManagerService extends IPackageManager.Stub { ps.pkg.applicationInfo.dataDir = getDataPathForPackage(ps.pkg.packageName, 0).getPath(); ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString; - ps.pkg.mSetEnabled = ps.enabled; - ps.pkg.mSetStopped = ps.stopped; } + ps.pkg.mSetEnabled = ps.getEnabled(userId); + ps.pkg.mSetStopped = ps.getStopped(userId); return generatePackageInfo(ps.pkg, flags); } return null; } - public ApplicationInfo getApplicationInfo(String packageName, int flags) { + @Override + public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { // writer synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -1702,7 +1715,7 @@ public class PackageManagerService extends IPackageManager.Stub { return mAndroidApplication; } if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { - return generateApplicationInfoFromSettingsLPw(packageName, flags); + return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); } } return null; @@ -1758,16 +1771,13 @@ public class PackageManagerService extends IPackageManager.Stub { }); } - public ActivityInfo getActivityInfo(ComponentName component, int flags) { - return getActivityInfo(component, flags, Binder.getOrigCallingUser()); - } - - ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { + @Override + public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { synchronized (mPackages) { PackageParser.Activity a = mActivities.mActivities.get(component); if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); - if (a != null && mSettings.isEnabledLPr(a.info, flags)) { + if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { return PackageParser.generateActivityInfo(a, flags, userId); } if (mResolveComponentName.equals(component)) { @@ -1777,48 +1787,39 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - public ActivityInfo getReceiverInfo(ComponentName component, int flags) { - return getReceiverInfo(component, flags, Binder.getOrigCallingUser()); - } - - ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { + @Override + public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { synchronized (mPackages) { PackageParser.Activity a = mReceivers.mActivities.get(component); if (DEBUG_PACKAGE_INFO) Log.v( TAG, "getReceiverInfo " + component + ": " + a); - if (a != null && mSettings.isEnabledLPr(a.info, flags)) { + if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { return PackageParser.generateActivityInfo(a, flags, userId); } } return null; } - public ServiceInfo getServiceInfo(ComponentName component, int flags) { - return getServiceInfo(component, flags, Binder.getOrigCallingUser()); - } - - ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { + @Override + public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { synchronized (mPackages) { PackageParser.Service s = mServices.mServices.get(component); if (DEBUG_PACKAGE_INFO) Log.v( TAG, "getServiceInfo " + component + ": " + s); - if (s != null && mSettings.isEnabledLPr(s.info, flags)) { + if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { return PackageParser.generateServiceInfo(s, flags, userId); } } return null; } - public ProviderInfo getProviderInfo(ComponentName component, int flags) { - return getProviderInfo(component, flags, UserId.getUserId(Binder.getCallingUid())); - } - - ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { + @Override + public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { synchronized (mPackages) { PackageParser.Provider p = mProvidersByComponent.get(component); if (DEBUG_PACKAGE_INFO) Log.v( TAG, "getProviderInfo " + component + ": " + p); - if (p != null && mSettings.isEnabledLPr(p.info, flags)) { + if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { return PackageParser.generateProviderInfo(p, flags, userId); } } @@ -1863,6 +1864,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private void checkValidCaller(int uid, int userId) { + if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) + return; + + throw new SecurityException("Caller uid=" + uid + + " is not privileged to communicate with user=" + userId); + } + public int checkPermission(String permName, String pkgName) { synchronized (mPackages) { PackageParser.Package p = mPackages.get(pkgName); @@ -1997,7 +2006,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (!async) { mSettings.writeLPr(); } else { - scheduleWriteSettingsLocked(); + scheduleWriteSettingsLocked(); } } return added; @@ -2232,14 +2241,15 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public ResolveInfo resolveIntent(Intent intent, String resolvedType, - int flags) { - List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags); - return chooseBestActivity(intent, resolvedType, flags, query); + int flags, int userId) { + List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); + return chooseBestActivity(intent, resolvedType, flags, query, userId); } private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, - int flags, List<ResolveInfo> query) { + int flags, List<ResolveInfo> query, int userId) { if (query != null) { final int N = query.size(); if (N == 1) { @@ -2263,7 +2273,7 @@ public class PackageManagerService extends IPackageManager.Stub { // If we have saved a preference for a preferred activity for // this Intent, use that. ResolveInfo ri = findPreferredActivity(intent, resolvedType, - flags, query, r0.priority); + flags, query, r0.priority, userId); if (ri != null) { return ri; } @@ -2274,7 +2284,7 @@ public class PackageManagerService extends IPackageManager.Stub { } ResolveInfo findPreferredActivity(Intent intent, String resolvedType, - int flags, List<ResolveInfo> query, int priority) { + int flags, List<ResolveInfo> query, int priority, int userId) { // writer synchronized (mPackages) { if (intent.getSelector() != null) { @@ -2283,7 +2293,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); List<PreferredActivity> prefs = mSettings.mPreferredActivities.queryIntent(intent, resolvedType, - (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); + (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); if (prefs != null && prefs.size() > 0) { // First figure out how good the original match set is. // We will only allow preferred activities that came @@ -2317,7 +2327,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (pa.mPref.mMatch != match) { continue; } - final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags); + final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags, userId); if (DEBUG_PREFERRED) { Log.v(TAG, "Got preferred activity:"); if (ai != null) { @@ -2367,8 +2377,9 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public List<ResolveInfo> queryIntentActivities(Intent intent, - String resolvedType, int flags) { + String resolvedType, int flags, int userId) { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -2379,7 +2390,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (comp != null) { final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); - final ActivityInfo ai = getActivityInfo(comp, flags); + final ActivityInfo ai = getActivityInfo(comp, flags, userId); if (ai != null) { final ResolveInfo ri = new ResolveInfo(); ri.activityInfo = ai; @@ -2392,24 +2403,25 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { final String pkgName = intent.getPackage(); if (pkgName == null) { - return mActivities.queryIntent(intent, resolvedType, flags); + return mActivities.queryIntent(intent, resolvedType, flags, userId); } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { return mActivities.queryIntentForPackage(intent, resolvedType, flags, - pkg.activities); + pkg.activities, userId); } return new ArrayList<ResolveInfo>(); } } + @Override public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, - String resolvedType, int flags) { + String resolvedType, int flags, int userId) { final String resultsAction = intent.getAction(); List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags - | PackageManager.GET_RESOLVED_FILTER); + | PackageManager.GET_RESOLVED_FILTER, userId); if (DEBUG_INTENT_MATCHING) { Log.v(TAG, "Query " + intent + ": " + results); @@ -2452,7 +2464,7 @@ public class PackageManagerService extends IPackageManager.Stub { ri = resolveIntent( sintent, specificTypes != null ? specificTypes[i] : null, - flags); + flags, userId); if (ri == null) { continue; } @@ -2463,7 +2475,7 @@ public class PackageManagerService extends IPackageManager.Stub { comp = new ComponentName(ai.applicationInfo.packageName, ai.name); } else { - ai = getActivityInfo(comp, flags); + ai = getActivityInfo(comp, flags, userId); if (ai == null) { continue; } @@ -2572,7 +2584,9 @@ public class PackageManagerService extends IPackageManager.Stub { return results; } - public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) { + @Override + public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, + int userId) { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -2582,7 +2596,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (comp != null) { List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); - ActivityInfo ai = getReceiverInfo(comp, flags); + ActivityInfo ai = getReceiverInfo(comp, flags, userId); if (ai != null) { ResolveInfo ri = new ResolveInfo(); ri.activityInfo = ai; @@ -2595,18 +2609,20 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { String pkgName = intent.getPackage(); if (pkgName == null) { - return mReceivers.queryIntent(intent, resolvedType, flags); + return mReceivers.queryIntent(intent, resolvedType, flags, userId); } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { - return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers); + return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, + userId); } return null; } } - public ResolveInfo resolveService(Intent intent, String resolvedType, int flags) { - List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags); + @Override + public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { + List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); if (query != null) { if (query.size() >= 1) { // If there is more than one service with the same priority, @@ -2617,7 +2633,9 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags) { + @Override + public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, + int userId) { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -2627,7 +2645,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (comp != null) { final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); - final ServiceInfo si = getServiceInfo(comp, flags); + final ServiceInfo si = getServiceInfo(comp, flags, userId); if (si != null) { final ResolveInfo ri = new ResolveInfo(); ri.serviceInfo = si; @@ -2640,11 +2658,12 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { String pkgName = intent.getPackage(); if (pkgName == null) { - return mServices.queryIntent(intent, resolvedType, flags); + return mServices.queryIntent(intent, resolvedType, flags, userId); } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { - return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services); + return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, + userId); } return null; } @@ -2669,6 +2688,7 @@ public class PackageManagerService extends IPackageManager.Stub { final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>(); final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; final String[] keys; + int userId = UserId.getCallingUserId(); // writer synchronized (mPackages) { @@ -2689,7 +2709,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (listUninstalled) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null) { - pi = generatePackageInfoFromSettingsLPw(ps.name, flags); + pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); } } else { final PackageParser.Package p = mPackages.get(packageName); @@ -2711,8 +2731,9 @@ public class PackageManagerService extends IPackageManager.Stub { return list; } + @Override public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, - String lastRead) { + String lastRead, int userId) { final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>(); final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; final String[] keys; @@ -2728,7 +2749,6 @@ public class PackageManagerService extends IPackageManager.Stub { Arrays.sort(keys); int i = getContinuationPoint(keys, lastRead); final int N = keys.length; - final int userId = UserId.getUserId(Binder.getCallingUid()); while (i < N) { final String packageName = keys[i++]; @@ -2737,7 +2757,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (listUninstalled) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null) { - ai = generateApplicationInfoFromSettingsLPw(ps.name, flags); + ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); } } else { final PackageParser.Package p = mPackages.get(packageName); @@ -2779,16 +2799,16 @@ public class PackageManagerService extends IPackageManager.Stub { return finalList; } - public ProviderInfo resolveContentProvider(String name, int flags) { + @Override + public ProviderInfo resolveContentProvider(String name, int flags, int userId) { // reader synchronized (mPackages) { final PackageParser.Provider provider = mProviders.get(name); return provider != null - && mSettings.isEnabledLPr(provider.info, flags) + && mSettings.isEnabledLPr(provider.info, flags, userId) && (!mSafeMode || (provider.info.applicationInfo.flags &ApplicationInfo.FLAG_SYSTEM) != 0) - ? PackageParser.generateProviderInfo(provider, flags, - UserId.getUserId(Binder.getCallingUid())) + ? PackageParser.generateProviderInfo(provider, flags, userId) : null; } } @@ -2824,15 +2844,15 @@ public class PackageManagerService extends IPackageManager.Stub { // reader synchronized (mPackages) { final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator(); - final int userId = UserId.getUserId(Binder.getCallingUid()); + final int userId = processName != null ? + UserId.getUserId(uid) : UserId.getCallingUserId(); while (i.hasNext()) { final PackageParser.Provider p = i.next(); if (p.info.authority != null && (processName == null || (p.info.processName.equals(processName) - && UserId.getAppId(p.info.applicationInfo.uid) - == UserId.getAppId(uid))) - && mSettings.isEnabledLPr(p.info, flags) + && UserId.isSameApp(p.info.applicationInfo.uid, uid))) + && mSettings.isEnabledLPr(p.info, flags, userId) && (!mSafeMode || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { if (finalList == null) { @@ -3482,7 +3502,7 @@ public class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } - pkg.applicationInfo.uid = pkgSetting.userId; + pkg.applicationInfo.uid = pkgSetting.uid; pkg.mExtras = pkgSetting; if (!verifySignaturesLP(pkgSetting, pkg)) { @@ -4480,19 +4500,20 @@ public class PackageManagerService extends IPackageManager.Stub { private final class ActivityIntentResolver extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, - boolean defaultOnly) { + boolean defaultOnly, int userId) { mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; - return super.queryIntent(intent, resolvedType, defaultOnly); + return super.queryIntent(intent, resolvedType, defaultOnly, userId); } - public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) { + public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, + int userId) { mFlags = flags; return super.queryIntent(intent, resolvedType, - (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); + (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, - int flags, ArrayList<PackageParser.Activity> packageActivities) { + int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { if (packageActivities == null) { return null; } @@ -4509,7 +4530,7 @@ public class PackageManagerService extends IPackageManager.Stub { listCut.add(intentFilters); } } - return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); + return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } public final void addActivity(PackageParser.Activity a, String type) { @@ -4574,7 +4595,7 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter) { + protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { PackageParser.Package p = filter.activity.owner; if (p != null) { PackageSetting ps = (PackageSetting)p.mExtras; @@ -4582,7 +4603,7 @@ public class PackageManagerService extends IPackageManager.Stub { // System apps are never considered stopped for purposes of // filtering, because there may be no way for the user to // actually re-launch them. - return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; + return ps.getStopped(userId) && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; } } return false; @@ -4595,8 +4616,8 @@ public class PackageManagerService extends IPackageManager.Stub { @Override protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, - int match) { - if (!mSettings.isEnabledLPr(info.activity.info, mFlags)) { + int match, int userId) { + if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { return null; } final PackageParser.Activity activity = info.activity; @@ -4605,8 +4626,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } final ResolveInfo res = new ResolveInfo(); - res.activityInfo = PackageParser.generateActivityInfo(activity, mFlags, - Binder.getOrigCallingUser()); + res.activityInfo = PackageParser.generateActivityInfo(activity, mFlags, userId); if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { res.filter = info; } @@ -4660,19 +4680,20 @@ public class PackageManagerService extends IPackageManager.Stub { private final class ServiceIntentResolver extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, - boolean defaultOnly) { + boolean defaultOnly, int userId) { mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; - return super.queryIntent(intent, resolvedType, defaultOnly); + return super.queryIntent(intent, resolvedType, defaultOnly, userId); } - public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) { + public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, + int userId) { mFlags = flags; return super.queryIntent(intent, resolvedType, - (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); + (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, - int flags, ArrayList<PackageParser.Service> packageServices) { + int flags, ArrayList<PackageParser.Service> packageServices, int userId) { if (packageServices == null) { return null; } @@ -4689,7 +4710,7 @@ public class PackageManagerService extends IPackageManager.Stub { listCut.add(intentFilters); } } - return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); + return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } public final void addService(PackageParser.Service s) { @@ -4749,7 +4770,7 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter) { + protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { PackageParser.Package p = filter.service.owner; if (p != null) { PackageSetting ps = (PackageSetting)p.mExtras; @@ -4757,7 +4778,8 @@ public class PackageManagerService extends IPackageManager.Stub { // System apps are never considered stopped for purposes of // filtering, because there may be no way for the user to // actually re-launch them. - return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; + return ps.getStopped(userId) + && (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0; } } return false; @@ -4770,9 +4792,9 @@ public class PackageManagerService extends IPackageManager.Stub { @Override protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, - int match) { + int match, int userId) { final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; - if (!mSettings.isEnabledLPr(info.service.info, mFlags)) { + if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { return null; } final PackageParser.Service service = info.service; @@ -4781,8 +4803,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } final ResolveInfo res = new ResolveInfo(); - res.serviceInfo = PackageParser.generateServiceInfo(service, mFlags, - Binder.getOrigCallingUser()); + res.serviceInfo = PackageParser.generateServiceInfo(service, mFlags, userId); if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { res.filter = filter; } @@ -5635,14 +5656,14 @@ public class PackageManagerService extends IPackageManager.Stub { * do, then we'll defer to them to verify the packages. */ final int requiredUid = mRequiredVerifierPackage == null ? -1 - : getPackageUid(mRequiredVerifierPackage); + : getPackageUid(mRequiredVerifierPackage, 0); if (requiredUid != -1 && isVerificationEnabled()) { final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE); verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); final List<ResolveInfo> receivers = queryIntentReceivers(verification, null, - PackageManager.GET_DISABLED_COMPONENTS); + PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); if (DEBUG_VERIFY) { Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " @@ -7316,17 +7337,19 @@ public class PackageManagerService extends IPackageManager.Stub { return ret; } + @Override public void clearApplicationUserData(final String packageName, - final IPackageDataObserver observer) { + final IPackageDataObserver observer, final int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_USER_DATA, null); + checkValidCaller(Binder.getCallingUid(), userId); // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); final boolean succeeded; synchronized (mInstallLock) { - succeeded = clearApplicationUserDataLI(packageName); + succeeded = clearApplicationUserDataLI(packageName, userId); } if (succeeded) { // invoke DeviceStorageMonitor's update method to clear any notifications @@ -7347,7 +7370,7 @@ public class PackageManagerService extends IPackageManager.Stub { }); } - private boolean clearApplicationUserDataLI(String packageName) { + private boolean clearApplicationUserDataLI(String packageName, int userId) { if (packageName == null) { Slog.w(TAG, "Attempt to delete null packageName."); return false; @@ -7379,7 +7402,7 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } } - int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId + int retCode = mInstaller.clearUserData(packageName, userId); if (retCode < 0) { Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); @@ -7393,12 +7416,13 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DELETE_CACHE_FILES, null); // Queue up an async operation since the package deletion may take a little while. + final int userId = UserId.getCallingUserId(); mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); final boolean succeded; synchronized (mInstallLock) { - succeded = deleteApplicationCacheFilesLI(packageName); + succeded = deleteApplicationCacheFilesLI(packageName, userId); } if(observer != null) { try { @@ -7411,7 +7435,7 @@ public class PackageManagerService extends IPackageManager.Stub { }); } - private boolean deleteApplicationCacheFilesLI(String packageName) { + private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { if (packageName == null) { Slog.w(TAG, "Attempt to delete null packageName."); return false; @@ -7429,6 +7453,7 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); return false; } + // TODO: Pass userId to deleteCacheFiles int retCode = mInstaller.deleteCacheFiles(packageName); if (retCode < 0) { Slog.w(TAG, "Couldn't remove cache files for package: " @@ -7695,19 +7720,21 @@ public class PackageManagerService extends IPackageManager.Stub { return num; } + @Override public void setApplicationEnabledSetting(String appPackageName, - int newState, int flags) { - setEnabledSetting(appPackageName, null, newState, flags); + int newState, int flags, int userId) { + setEnabledSetting(appPackageName, null, newState, flags, userId); } + @Override public void setComponentEnabledSetting(ComponentName componentName, - int newState, int flags) { + int newState, int flags, int userId) { setEnabledSetting(componentName.getPackageName(), - componentName.getClassName(), newState, flags); + componentName.getClassName(), newState, flags, userId); } private void setEnabledSetting( - final String packageName, String className, int newState, final int flags) { + final String packageName, String className, int newState, final int flags, int userId) { if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT || newState == COMPONENT_ENABLED_STATE_ENABLED || newState == COMPONENT_ENABLED_STATE_DISABLED @@ -7719,6 +7746,7 @@ public class PackageManagerService extends IPackageManager.Stub { final int uid = Binder.getCallingUid(); final int permission = mContext.checkCallingPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); + checkValidCaller(uid, userId); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); boolean sendNow = false; boolean isApp = (className == null); @@ -7738,19 +7766,20 @@ public class PackageManagerService extends IPackageManager.Stub { "Unknown component: " + packageName + "/" + className); } - if (!allowedByPermission && (!UserId.isSameApp(uid, pkgSetting.userId))) { + // Allow root and verify that userId is not being specified by a different user + if (!allowedByPermission && !UserId.isSameApp(uid, pkgSetting.uid)) { throw new SecurityException( "Permission Denial: attempt to change component state from pid=" + Binder.getCallingPid() - + ", uid=" + uid + ", package uid=" + pkgSetting.userId); + + ", uid=" + uid + ", package uid=" + pkgSetting.uid); } if (className == null) { // We're dealing with an application/package level state change - if (pkgSetting.enabled == newState) { + if (pkgSetting.getEnabled(userId) == newState) { // Nothing to do return; } - pkgSetting.enabled = newState; + pkgSetting.setEnabled(newState, userId); pkgSetting.pkg.mSetEnabled = newState; } else { // We're dealing with a component level state change @@ -7767,17 +7796,17 @@ public class PackageManagerService extends IPackageManager.Stub { } switch (newState) { case COMPONENT_ENABLED_STATE_ENABLED: - if (!pkgSetting.enableComponentLPw(className)) { + if (!pkgSetting.enableComponentLPw(className, userId)) { return; } break; case COMPONENT_ENABLED_STATE_DISABLED: - if (!pkgSetting.disableComponentLPw(className)) { + if (!pkgSetting.disableComponentLPw(className, userId)) { return; } break; case COMPONENT_ENABLED_STATE_DEFAULT: - if (!pkgSetting.restoreComponentLPw(className)) { + if (!pkgSetting.restoreComponentLPw(className, userId)) { return; } break; @@ -7786,8 +7815,8 @@ public class PackageManagerService extends IPackageManager.Stub { return; } } - mSettings.writeLPr(); - packageUid = pkgSetting.userId; + mSettings.writePackageRestrictionsLPr(userId); + packageUid = pkgSetting.uid; components = mPendingBroadcasts.get(packageName); final boolean newPackage = components == null; if (newPackage) { @@ -7838,16 +7867,17 @@ public class PackageManagerService extends IPackageManager.Stub { sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null); } - public void setPackageStoppedState(String packageName, boolean stopped) { + public void setPackageStoppedState(String packageName, boolean stopped, int userId) { final int uid = Binder.getCallingUid(); final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); + checkValidCaller(uid, userId); // writer synchronized (mPackages) { if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, - uid)) { - scheduleWriteStoppedPackagesLocked(); + uid, userId)) { + scheduleWritePackageRestrictionsLocked(userId); } } } @@ -7859,17 +7889,23 @@ public class PackageManagerService extends IPackageManager.Stub { } } - public int getApplicationEnabledSetting(String packageName) { + @Override + public int getApplicationEnabledSetting(String packageName, int userId) { + int uid = Binder.getCallingUid(); + checkValidCaller(uid, userId); // reader synchronized (mPackages) { - return mSettings.getApplicationEnabledSettingLPr(packageName); + return mSettings.getApplicationEnabledSettingLPr(packageName, userId); } } - public int getComponentEnabledSetting(ComponentName componentName) { + @Override + public int getComponentEnabledSetting(ComponentName componentName, int userId) { + int uid = Binder.getCallingUid(); + checkValidCaller(uid, userId); // reader synchronized (mPackages) { - return mSettings.getComponentEnabledSettingLPr(componentName); + return mSettings.getComponentEnabledSettingLPr(componentName, userId); } } @@ -8073,7 +8109,7 @@ public class PackageManagerService extends IPackageManager.Stub { pw.print(" Required: "); pw.print(mRequiredVerifierPackage); pw.print(" (uid="); - pw.print(getPackageUid(mRequiredVerifierPackage)); + pw.print(getPackageUid(mRequiredVerifierPackage, 0)); pw.println(")"); } @@ -8338,7 +8374,7 @@ public class PackageManagerService extends IPackageManager.Stub { + " at code path: " + ps.codePathString); // We do have a valid package installed on sdcard processCids.put(args, ps.codePathString); - int uid = ps.userId; + int uid = ps.uid; if (uid != -1) { uidList[num++] = uid; } diff --git a/services/java/com/android/server/pm/PackageSetting.java b/services/java/com/android/server/pm/PackageSetting.java index efdc2b3..48ed9bf 100644 --- a/services/java/com/android/server/pm/PackageSetting.java +++ b/services/java/com/android/server/pm/PackageSetting.java @@ -24,7 +24,7 @@ import java.io.File; * Settings data for a particular package we know about. */ final class PackageSetting extends PackageSettingBase { - int userId; + int uid; PackageParser.Package pkg; SharedUserSetting sharedUser; @@ -41,7 +41,7 @@ final class PackageSetting extends PackageSettingBase { PackageSetting(PackageSetting orig) { super(orig); - userId = orig.userId; + uid = orig.uid; pkg = orig.pkg; sharedUser = orig.sharedUser; } @@ -50,6 +50,6 @@ final class PackageSetting extends PackageSettingBase { public String toString() { return "PackageSetting{" + Integer.toHexString(System.identityHashCode(this)) - + " " + name + "/" + userId + "}"; + + " " + name + "/" + uid + "}"; } }
\ No newline at end of file diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java index e2f83ad..b7cf8d6 100644 --- a/services/java/com/android/server/pm/PackageSettingBase.java +++ b/services/java/com/android/server/pm/PackageSettingBase.java @@ -20,6 +20,8 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import android.util.SparseArray; +import android.util.SparseIntArray; import java.io.File; import java.util.HashSet; @@ -62,20 +64,22 @@ class PackageSettingBase extends GrantedPermissions { // Whether this package is currently stopped, thus can not be // started until explicitly launched by the user. - public boolean stopped; + private SparseArray<Boolean> stopped = new SparseArray<Boolean>(); // Set to true if we have never launched this app. - public boolean notLaunched; + private SparseArray<Boolean> notLaunched = new SparseArray<Boolean>(); /* Explicitly disabled components */ - HashSet<String> disabledComponents = new HashSet<String>(0); + private SparseArray<HashSet<String>> disabledComponents = new SparseArray<HashSet<String>>(); /* Explicitly enabled components */ - HashSet<String> enabledComponents = new HashSet<String>(0); - int enabled = COMPONENT_ENABLED_STATE_DEFAULT; + private SparseArray<HashSet<String>> enabledComponents = new SparseArray<HashSet<String>>(); + /* Enabled state */ + private SparseIntArray enabled = new SparseIntArray(); + int installStatus = PKG_INSTALL_COMPLETE; PackageSettingBase origPackage; - + /* package name of the app that installed this package */ String installerPackageName; PackageSettingBase(String name, String realName, File codePath, File resourcePath, @@ -111,14 +115,12 @@ class PackageSettingBase extends GrantedPermissions { permissionsFixed = base.permissionsFixed; haveGids = base.haveGids; - stopped = base.stopped; notLaunched = base.notLaunched; - disabledComponents = (HashSet<String>) base.disabledComponents.clone(); - - enabledComponents = (HashSet<String>) base.enabledComponents.clone(); - - enabled = base.enabled; + disabledComponents = (SparseArray<HashSet<String>>) base.disabledComponents.clone(); + enabledComponents = (SparseArray<HashSet<String>>) base.enabledComponents.clone(); + enabled = (SparseIntArray) base.enabled.clone(); + stopped = (SparseArray<Boolean>) base.stopped.clone(); installStatus = base.installStatus; origPackage = base.origPackage; @@ -177,31 +179,98 @@ class PackageSettingBase extends GrantedPermissions { installStatus = base.installStatus; } - boolean enableComponentLPw(String componentClassName) { - boolean changed = disabledComponents.remove(componentClassName); - changed |= enabledComponents.add(componentClassName); + void setEnabled(int state, int userId) { + enabled.put(userId, state); + } + + int getEnabled(int userId) { + return enabled.get(userId, COMPONENT_ENABLED_STATE_DEFAULT); + } + + boolean getStopped(int userId) { + return stopped.get(userId, false); + } + + void setStopped(boolean stop, int userId) { + stopped.put(userId, stop); + } + + boolean getNotLaunched(int userId) { + return notLaunched.get(userId, false); + } + + void setNotLaunched(boolean stop, int userId) { + notLaunched.put(userId, stop); + } + + HashSet<String> getEnabledComponents(int userId) { + return getComponentHashSet(enabledComponents, userId); + } + + HashSet<String> getDisabledComponents(int userId) { + return getComponentHashSet(disabledComponents, userId); + } + + void setEnabledComponents(HashSet<String> components, int userId) { + enabledComponents.put(userId, components); + } + + void setDisabledComponents(HashSet<String> components, int userId) { + disabledComponents.put(userId, components); + } + + private HashSet<String> getComponentHashSet(SparseArray<HashSet<String>> setArray, int userId) { + HashSet<String> set = setArray.get(userId); + if (set == null) { + set = new HashSet<String>(1); + setArray.put(userId, set); + } + return set; + } + + void addDisabledComponent(String componentClassName, int userId) { + HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); + disabled.add(componentClassName); + } + + void addEnabledComponent(String componentClassName, int userId) { + HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); + enabled.add(componentClassName); + } + + boolean enableComponentLPw(String componentClassName, int userId) { + HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); + HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); + boolean changed = disabled.remove(componentClassName); + changed |= enabled.add(componentClassName); return changed; } - boolean disableComponentLPw(String componentClassName) { - boolean changed = enabledComponents.remove(componentClassName); - changed |= disabledComponents.add(componentClassName); + boolean disableComponentLPw(String componentClassName, int userId) { + HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); + HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); + boolean changed = enabled.remove(componentClassName); + changed |= disabled.add(componentClassName); return changed; } - boolean restoreComponentLPw(String componentClassName) { - boolean changed = enabledComponents.remove(componentClassName); - changed |= disabledComponents.remove(componentClassName); + boolean restoreComponentLPw(String componentClassName, int userId) { + HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); + HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); + boolean changed = enabled.remove(componentClassName); + changed |= disabled.remove(componentClassName); return changed; } - int getCurrentEnabledStateLPr(String componentName) { - if (enabledComponents.contains(componentName)) { + int getCurrentEnabledStateLPr(String componentName, int userId) { + HashSet<String> disabled = getComponentHashSet(disabledComponents, userId); + HashSet<String> enabled = getComponentHashSet(enabledComponents, userId); + if (enabled.contains(componentName)) { return COMPONENT_ENABLED_STATE_ENABLED; - } else if (disabledComponents.contains(componentName)) { + } else if (disabled.contains(componentName)) { return COMPONENT_ENABLED_STATE_DISABLED; } else { return COMPONENT_ENABLED_STATE_DEFAULT; } } -}
\ No newline at end of file +} diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index 363d020..b541c8c 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -32,6 +32,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.app.AppGlobals; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -40,11 +41,14 @@ import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PermissionInfo; import android.content.pm.Signature; +import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; import android.os.Binder; import android.os.Environment; import android.os.FileUtils; import android.os.Process; +import android.os.RemoteException; +import android.os.UserId; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -63,6 +67,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import libcore.io.IoUtils; @@ -78,6 +83,17 @@ final class Settings { private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage"; private static final String ATTR_ENFORCEMENT = "enforcement"; + private static final String TAG_ITEM = "item"; + private static final String TAG_DISABLED_COMPONENTS = "disabled-components"; + private static final String TAG_ENABLED_COMPONENTS = "enabled-components"; + private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions"; + private static final String TAG_PACKAGE = "pkg"; + + private static final String ATTR_NAME = "name"; + private static final String ATTR_NOT_LAUNCHED = "nl"; + private static final String ATTR_ENABLED = "enabled"; + private static final String ATTR_STOPPED = "stopped"; + private final File mSettingsFilename; private final File mBackupSettingsFilename; private final File mPackageListFilename; @@ -153,19 +169,24 @@ final class Settings { */ private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>(); + private final File mSystemDir; Settings() { - File dataDir = Environment.getDataDirectory(); - File systemDir = new File(dataDir, "system"); - systemDir.mkdirs(); - FileUtils.setPermissions(systemDir.toString(), + this(Environment.getDataDirectory()); + } + + Settings(File dataDir) { + mSystemDir = new File(dataDir, "system"); + mSystemDir.mkdirs(); + FileUtils.setPermissions(mSystemDir.toString(), FileUtils.S_IRWXU|FileUtils.S_IRWXG |FileUtils.S_IROTH|FileUtils.S_IXOTH, -1, -1); - mSettingsFilename = new File(systemDir, "packages.xml"); - mBackupSettingsFilename = new File(systemDir, "packages-backup.xml"); - mPackageListFilename = new File(systemDir, "packages.list"); - mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml"); - mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml"); + mSettingsFilename = new File(mSystemDir, "packages.xml"); + mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); + mPackageListFilename = new File(mSystemDir, "packages.list"); + // Deprecated: Needed for migration + mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); + mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); } PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, @@ -254,7 +275,7 @@ final class Settings { p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath, - p.nativeLibraryPathString, p.userId, p.versionCode, p.pkgFlags); + p.nativeLibraryPathString, p.uid, p.versionCode, p.pkgFlags); mDisabledSysPackages.remove(name); return ret; } @@ -263,7 +284,7 @@ final class Settings { String nativeLibraryPathString, int uid, int vc, int pkgFlags) { PackageSetting p = mPackages.get(name); if (p != null) { - if (p.userId == uid) { + if (p.uid == uid) { return p; } PackageManagerService.reportSettingsProblem(Log.ERROR, @@ -272,7 +293,7 @@ final class Settings { } p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, vc, pkgFlags); - p.userId = uid; + p.uid = uid; if (addUserIdLPw(uid, p, name)) { mPackages.put(name, p); return p; @@ -323,7 +344,7 @@ final class Settings { } } } - + private PackageSetting getPackageLPw(String name, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) { @@ -335,13 +356,13 @@ final class Settings { // This is an updated system app with versions in both system // and data partition. Just let the most recent version // take precedence. - Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " + - p.codePathString + " to " + codePath.toString()); + Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " + + p.codePathString + " to " + codePath.toString()); } else { // Just a change in the code path is not an issue, but // let's log a message about it. - Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " + p.codePath - + " to " + codePath + "; Retaining data and using new"); + Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " + + p.codePath + " to " + codePath + "; Retaining data and using new"); /* * Since we've changed paths, we need to prefer the new * native library path over the one stored in the @@ -378,15 +399,15 @@ final class Settings { // We are consuming the data from an existing package. p = new PackageSetting(origPackage.name, name, codePath, resourcePath, nativeLibraryPathString, vc, pkgFlags); - if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + name - + " is adopting original package " + origPackage.name); + if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + + name + " is adopting original package " + origPackage.name); // Note that we will retain the new package's signature so // that we can keep its data. PackageSignatures s = p.signatures; p.copyFrom(origPackage); p.signatures = s; p.sharedUser = origPackage.sharedUser; - p.userId = origPackage.userId; + p.uid = origPackage.uid; p.origPackage = origPackage; mRenamedPackages.put(name, origPackage.name); name = origPackage.name; @@ -404,11 +425,17 @@ final class Settings { e.fillInStackTrace(); Slog.i(PackageManagerService.TAG, "Stopping package " + name, e); } - p.stopped = true; - p.notLaunched = true; + List<UserInfo> users = getAllUsers(); + if (users != null) { + for (UserInfo user : users) { + p.setStopped(true, user.id); + p.setNotLaunched(true, user.id); + writePackageRestrictionsLPr(user.id); + } + } } if (sharedUser != null) { - p.userId = sharedUser.userId; + p.uid = sharedUser.userId; } else { // Clone the setting here for disabled system packages PackageSetting dis = mDisabledSysPackages.get(name); @@ -420,21 +447,31 @@ final class Settings { if (dis.signatures.mSignatures != null) { p.signatures.mSignatures = dis.signatures.mSignatures.clone(); } - p.userId = dis.userId; + p.uid = dis.uid; // Clone permissions p.grantedPermissions = new HashSet<String>(dis.grantedPermissions); // Clone component info - p.disabledComponents = new HashSet<String>(dis.disabledComponents); - p.enabledComponents = new HashSet<String>(dis.enabledComponents); + List<UserInfo> users = getAllUsers(); + if (users != null) { + for (UserInfo user : users) { + int userId = user.id; + p.setDisabledComponents( + new HashSet<String>(dis.getDisabledComponents(userId)), + userId); + p.setEnabledComponents( + new HashSet<String>(dis.getEnabledComponents(userId)), + userId); + } + } // Add new setting to list of user ids - addUserIdLPw(p.userId, p, name); + addUserIdLPw(p.uid, p, name); } else { // Assign new user id - p.userId = newUserIdLPw(p); + p.uid = newUserIdLPw(p); } } } - if (p.userId < 0) { + if (p.uid < 0) { PackageManagerService.reportSettingsProblem(Log.WARN, "Package " + name + " could not be assigned a valid uid"); return null; @@ -450,8 +487,8 @@ final class Settings { void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { p.pkg = pkg; - pkg.mSetEnabled = p.enabled; - pkg.mSetStopped = p.stopped; + // pkg.mSetEnabled = p.getEnabled(userId); + // pkg.mSetStopped = p.getStopped(userId); final String codePath = pkg.applicationInfo.sourceDir; final String resourcePath = pkg.applicationInfo.publicSourceDir; // Update code path if needed @@ -475,18 +512,18 @@ final class Settings { p.nativeLibraryPathString = nativeLibraryPath; } // Update version code if needed - if (pkg.mVersionCode != p.versionCode) { + if (pkg.mVersionCode != p.versionCode) { p.versionCode = pkg.mVersionCode; } - // Update signatures if needed. - if (p.signatures.mSignatures == null) { - p.signatures.assignSignatures(pkg.mSignatures); - } - // If this app defines a shared user id initialize - // the shared user signatures as well. - if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) { - p.sharedUser.signatures.assignSignatures(pkg.mSignatures); - } + // Update signatures if needed. + if (p.signatures.mSignatures == null) { + p.signatures.assignSignatures(pkg.mSignatures); + } + // If this app defines a shared user id initialize + // the shared user signatures as well. + if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) { + p.sharedUser.signatures.assignSignatures(pkg.mSignatures); + } addPackageSettingLPw(p, pkg.packageName, p.sharedUser); } @@ -502,9 +539,9 @@ final class Settings { + p.sharedUser + " but is now " + sharedUser + "; I am not changing its files so it will probably fail!"); p.sharedUser.packages.remove(p); - } else if (p.userId != sharedUser.userId) { + } else if (p.uid != sharedUser.userId) { PackageManagerService.reportSettingsProblem(Log.ERROR, - "Package " + p.name + " was user id " + p.userId + "Package " + p.name + " was user id " + p.uid + " but is now user " + sharedUser + " with id " + sharedUser.userId + "; I am not changing its files so it will probably fail!"); @@ -512,7 +549,7 @@ final class Settings { sharedUser.packages.add(p); p.sharedUser = sharedUser; - p.userId = sharedUser.userId; + p.uid = sharedUser.userId; } } @@ -577,8 +614,8 @@ final class Settings { return p.sharedUser.userId; } } else { - removeUserIdLPw(p.userId); - return p.userId; + removeUserIdLPw(p.uid); + return p.uid; } } return -1; @@ -591,7 +628,7 @@ final class Settings { p.sharedUser.packages.remove(p); p.sharedUser.packages.add(newp); } else { - replaceUserIdLPw(p.userId, newp); + replaceUserIdLPw(p.uid, newp); } } mPackages.put(name, newp); @@ -658,50 +695,269 @@ final class Settings { } } - void writeStoppedLPr() { + private File getUserPackagesStateFile(int userId) { + return new File(mSystemDir, + "users/" + userId + "/package-restrictions.xml"); + } + + private File getUserPackagesStateBackupFile(int userId) { + return new File(mSystemDir, + "users/" + userId + "/package-restrictions-backup.xml"); + } + + void writeAllUsersPackageRestrictionsLPr() { + List<UserInfo> users = getAllUsers(); + if (users == null) return; + + for (UserInfo user : users) { + writePackageRestrictionsLPr(user.id); + } + } + + void readAllUsersPackageRestrictionsLPr() { + List<UserInfo> users = getAllUsers(); + if (users == null) { + readPackageRestrictionsLPr(0); + return; + } + + for (UserInfo user : users) { + readPackageRestrictionsLPr(user.id); + } + } + + void readPackageRestrictionsLPr(int userId) { + FileInputStream str = null; + File userPackagesStateFile = getUserPackagesStateFile(userId); + File backupFile = getUserPackagesStateBackupFile(userId); + if (backupFile.exists()) { + try { + str = new FileInputStream(backupFile); + mReadMessages.append("Reading from backup stopped packages file\n"); + PackageManagerService.reportSettingsProblem(Log.INFO, + "Need to read from backup stopped packages file"); + if (userPackagesStateFile.exists()) { + // If both the backup and normal file exist, we + // ignore the normal one since it might have been + // corrupted. + Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file " + + userPackagesStateFile); + userPackagesStateFile.delete(); + } + } catch (java.io.IOException e) { + // We'll try for the normal settings file. + } + } + + try { + if (str == null) { + if (!userPackagesStateFile.exists()) { + mReadMessages.append("No stopped packages file found\n"); + PackageManagerService.reportSettingsProblem(Log.INFO, + "No stopped packages file; " + + "assuming all started"); + // At first boot, make sure no packages are stopped. + // We usually want to have third party apps initialize + // in the stopped state, but not at first boot. + for (PackageSetting pkg : mPackages.values()) { + pkg.setStopped(false, userId); + pkg.setNotLaunched(false, userId); + } + return; + } + str = new FileInputStream(userPackagesStateFile); + } + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(str, null); + + int type; + while ((type=parser.next()) != XmlPullParser.START_TAG + && type != XmlPullParser.END_DOCUMENT) { + ; + } + + if (type != XmlPullParser.START_TAG) { + mReadMessages.append("No start tag found in package restrictions file\n"); + PackageManagerService.reportSettingsProblem(Log.WARN, + "No start tag found in package manager stopped packages"); + return; + } + + int outerDepth = parser.getDepth(); + PackageSetting ps = null; + while ((type=parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG + || type == XmlPullParser.TEXT) { + continue; + } + + String tagName = parser.getName(); + if (tagName.equals(TAG_PACKAGE)) { + String name = parser.getAttributeValue(null, ATTR_NAME); + ps = mPackages.get(name); + if (ps == null) { + Slog.w(PackageManagerService.TAG, "No package known for stopped package: " + + name); + XmlUtils.skipCurrentTag(parser); + continue; + } + String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); + int enabled = enabledStr == null ? COMPONENT_ENABLED_STATE_DEFAULT + : Integer.parseInt(enabledStr); + ps.setEnabled(enabled, userId); + String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED); + boolean stopped = stoppedStr == null ? false : Boolean.parseBoolean(stoppedStr); + ps.setStopped(stopped, userId); + String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED); + boolean notLaunched = stoppedStr == null ? false + : Boolean.parseBoolean(notLaunchedStr); + ps.setNotLaunched(notLaunched, userId); + + int packageDepth = parser.getDepth(); + while ((type=parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > packageDepth)) { + if (type == XmlPullParser.END_TAG + || type == XmlPullParser.TEXT) { + continue; + } + tagName = parser.getName(); + if (tagName.equals(TAG_ENABLED_COMPONENTS)) { + HashSet<String> components = readComponentsLPr(parser); + ps.setEnabledComponents(components, userId); + } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) { + HashSet<String> components = readComponentsLPr(parser); + ps.setDisabledComponents(components, userId); + } + } + } else { + Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " + + parser.getName()); + XmlUtils.skipCurrentTag(parser); + } + } + + str.close(); + + } catch (XmlPullParserException e) { + mReadMessages.append("Error reading: " + e.toString()); + PackageManagerService.reportSettingsProblem(Log.ERROR, + "Error reading stopped packages: " + e); + Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + + } catch (java.io.IOException e) { + mReadMessages.append("Error reading: " + e.toString()); + PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); + Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + } + } + + private HashSet<String> readComponentsLPr(XmlPullParser parser) + throws IOException, XmlPullParserException { + HashSet<String> components = new HashSet<String>(); + int type; + int outerDepth = parser.getDepth(); + String tagName; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG + || type == XmlPullParser.TEXT) { + continue; + } + tagName = parser.getName(); + if (tagName.equals(TAG_ITEM)) { + String componentName = parser.getAttributeValue(null, ATTR_NAME); + if (componentName != null) { + components.add(componentName); + } + } + } + return components; + } + + void writePackageRestrictionsLPr(int userId) { // Keep the old stopped packages around until we know the new ones have // been successfully written. - if (mStoppedPackagesFilename.exists()) { + File userPackagesStateFile = getUserPackagesStateFile(userId); + File backupFile = getUserPackagesStateBackupFile(userId); + new File(userPackagesStateFile.getParent()).mkdirs(); + if (userPackagesStateFile.exists()) { // Presence of backup settings file indicates that we failed // to persist packages earlier. So preserve the older // backup for future reference since the current packages // might have been corrupted. - if (!mBackupStoppedPackagesFilename.exists()) { - if (!mStoppedPackagesFilename.renameTo(mBackupStoppedPackagesFilename)) { - Log.wtf(PackageManagerService.TAG, "Unable to backup package manager stopped packages, " + if (!backupFile.exists()) { + if (!userPackagesStateFile.renameTo(backupFile)) { + Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, " + "current changes will be lost at reboot"); return; } } else { - mStoppedPackagesFilename.delete(); + userPackagesStateFile.delete(); Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup"); } } try { - final FileOutputStream fstr = new FileOutputStream(mStoppedPackagesFilename); + final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); final BufferedOutputStream str = new BufferedOutputStream(fstr); - //XmlSerializer serializer = XmlUtils.serializerInstance(); final XmlSerializer serializer = new FastXmlSerializer(); serializer.setOutput(str, "utf-8"); serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - serializer.startTag(null, "stopped-packages"); + serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); for (final PackageSetting pkg : mPackages.values()) { - if (pkg.stopped) { - serializer.startTag(null, "pkg"); - serializer.attribute(null, "name", pkg.name); - if (pkg.notLaunched) { - serializer.attribute(null, "nl", "1"); + if (pkg.getStopped(userId) + || pkg.getNotLaunched(userId) + || pkg.getEnabled(userId) != COMPONENT_ENABLED_STATE_DEFAULT + || pkg.getEnabledComponents(userId).size() > 0 + || pkg.getDisabledComponents(userId).size() > 0) { + serializer.startTag(null, TAG_PACKAGE); + serializer.attribute(null, ATTR_NAME, pkg.name); + boolean stopped = pkg.getStopped(userId); + boolean notLaunched = pkg.getNotLaunched(userId); + int enabled = pkg.getEnabled(userId); + HashSet<String> enabledComponents = pkg.getEnabledComponents(userId); + HashSet<String> disabledComponents = pkg.getDisabledComponents(userId); + + if (stopped) { + serializer.attribute(null, ATTR_STOPPED, "true"); + } + if (notLaunched) { + serializer.attribute(null, ATTR_NOT_LAUNCHED, "true"); + } + if (enabled != COMPONENT_ENABLED_STATE_DEFAULT) { + serializer.attribute(null, ATTR_ENABLED, Integer.toString(enabled)); + } + if (enabledComponents.size() > 0) { + serializer.startTag(null, TAG_ENABLED_COMPONENTS); + for (final String name : enabledComponents) { + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); + } + serializer.endTag(null, TAG_ENABLED_COMPONENTS); + } + if (disabledComponents.size() > 0) { + serializer.startTag(null, TAG_DISABLED_COMPONENTS); + for (final String name : disabledComponents) { + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); + } + serializer.endTag(null, TAG_DISABLED_COMPONENTS); } - serializer.endTag(null, "pkg"); + serializer.endTag(null, TAG_PACKAGE); } } - serializer.endTag(null, "stopped-packages"); + serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); @@ -711,8 +967,8 @@ final class Settings { // New settings successfully written, old ones are no longer // needed. - mBackupStoppedPackagesFilename.delete(); - FileUtils.setPermissions(mStoppedPackagesFilename.toString(), + backupFile.delete(); + FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR|FileUtils.S_IWUSR |FileUtils.S_IRGRP|FileUtils.S_IWGRP, -1, -1); @@ -720,26 +976,30 @@ final class Settings { // Done, all is good! return; } catch(java.io.IOException e) { - Log.wtf(PackageManagerService.TAG, "Unable to write package manager stopped packages, " + Log.wtf(PackageManagerService.TAG, + "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); } // Clean up partially written files - if (mStoppedPackagesFilename.exists()) { - if (!mStoppedPackagesFilename.delete()) { - Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " + mStoppedPackagesFilename); + if (userPackagesStateFile.exists()) { + if (!userPackagesStateFile.delete()) { + Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " + + mStoppedPackagesFilename); } } } // Note: assumed "stopped" field is already cleared in all packages. + // Legacy reader, used to read in the old file format after an upgrade. Not used after that. void readStoppedLPw() { FileInputStream str = null; if (mBackupStoppedPackagesFilename.exists()) { try { str = new FileInputStream(mBackupStoppedPackagesFilename); mReadMessages.append("Reading from backup stopped packages file\n"); - PackageManagerService.reportSettingsProblem(Log.INFO, "Need to read from backup stopped packages file"); + PackageManagerService.reportSettingsProblem(Log.INFO, + "Need to read from backup stopped packages file"); if (mSettingsFilename.exists()) { // If both the backup and normal file exist, we // ignore the normal one since it might have been @@ -757,14 +1017,14 @@ final class Settings { if (str == null) { if (!mStoppedPackagesFilename.exists()) { mReadMessages.append("No stopped packages file found\n"); - PackageManagerService.reportSettingsProblem(Log.INFO, "No stopped packages file file; " - + "assuming all started"); + PackageManagerService.reportSettingsProblem(Log.INFO, + "No stopped packages file file; assuming all started"); // At first boot, make sure no packages are stopped. // We usually want to have third party apps initialize // in the stopped state, but not at first boot. for (PackageSetting pkg : mPackages.values()) { - pkg.stopped = false; - pkg.notLaunched = false; + pkg.setStopped(false, 0); + pkg.setNotLaunched(false, 0); } return; } @@ -796,16 +1056,17 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("pkg")) { - String name = parser.getAttributeValue(null, "name"); + if (tagName.equals(TAG_PACKAGE)) { + String name = parser.getAttributeValue(null, ATTR_NAME); PackageSetting ps = mPackages.get(name); if (ps != null) { - ps.stopped = true; - if ("1".equals(parser.getAttributeValue(null, "nl"))) { - ps.notLaunched = true; + ps.setStopped(true, 0); + if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) { + ps.setNotLaunched(true, 0); } } else { - Slog.w(PackageManagerService.TAG, "No package known for stopped package: " + name); + Slog.w(PackageManagerService.TAG, + "No package known for stopped package: " + name); } XmlUtils.skipCurrentTag(parser); } else { @@ -817,12 +1078,13 @@ final class Settings { str.close(); - } catch(XmlPullParserException e) { + } catch (XmlPullParserException e) { mReadMessages.append("Error reading: " + e.toString()); - PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e); + PackageManagerService.reportSettingsProblem(Log.ERROR, + "Error reading stopped packages: " + e); Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); - } catch(java.io.IOException e) { + } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); @@ -906,23 +1168,23 @@ final class Settings { serializer.startTag(null, "preferred-activities"); for (final PreferredActivity pa : mPreferredActivities.filterSet()) { - serializer.startTag(null, "item"); + serializer.startTag(null, TAG_ITEM); pa.writeToXml(serializer); - serializer.endTag(null, "item"); + serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, "preferred-activities"); for (final SharedUserSetting usr : mSharedUsers.values()) { serializer.startTag(null, "shared-user"); - serializer.attribute(null, "name", usr.name); + serializer.attribute(null, ATTR_NAME, usr.name); serializer.attribute(null, "userId", Integer.toString(usr.userId)); usr.signatures.writeXml(serializer, "sigs", mPastSignatures); serializer.startTag(null, "perms"); for (String name : usr.grantedPermissions) { - serializer.startTag(null, "item"); - serializer.attribute(null, "name", name); - serializer.endTag(null, "item"); + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, "perms"); serializer.endTag(null, "shared-user"); @@ -931,7 +1193,7 @@ final class Settings { if (mPackagesToBeCleaned.size() > 0) { for (int i=0; i<mPackagesToBeCleaned.size(); i++) { serializer.startTag(null, "cleaning-package"); - serializer.attribute(null, "name", mPackagesToBeCleaned.get(i)); + serializer.attribute(null, ATTR_NAME, mPackagesToBeCleaned.get(i)); serializer.endTag(null, "cleaning-package"); } } @@ -1016,8 +1278,7 @@ final class Settings { |FileUtils.S_IRGRP|FileUtils.S_IWGRP, -1, -1); - writeStoppedLPr(); - + writeAllUsersPackageRestrictionsLPr(); return; } catch(XmlPullParserException e) { @@ -1030,7 +1291,8 @@ final class Settings { // Clean up partially written files if (mSettingsFilename.exists()) { if (!mSettingsFilename.delete()) { - Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename); + Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + + mSettingsFilename); } } //Debug.stopMethodTracing(); @@ -1039,7 +1301,7 @@ final class Settings { void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg) throws java.io.IOException { serializer.startTag(null, "updated-package"); - serializer.attribute(null, "name", pkg.name); + serializer.attribute(null, ATTR_NAME, pkg.name); if (pkg.realName != null) { serializer.attribute(null, "realName", pkg.realName); } @@ -1055,9 +1317,9 @@ final class Settings { serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString); } if (pkg.sharedUser == null) { - serializer.attribute(null, "userId", Integer.toString(pkg.userId)); + serializer.attribute(null, "userId", Integer.toString(pkg.uid)); } else { - serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId)); + serializer.attribute(null, "sharedUserId", Integer.toString(pkg.uid)); } serializer.startTag(null, "perms"); if (pkg.sharedUser == null) { @@ -1072,9 +1334,9 @@ final class Settings { // this wont // match the semantics of grantedPermissions. So write all // permissions. - serializer.startTag(null, "item"); - serializer.attribute(null, "name", name); - serializer.endTag(null, "item"); + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); } } } @@ -1085,7 +1347,7 @@ final class Settings { void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg) throws java.io.IOException { serializer.startTag(null, "package"); - serializer.attribute(null, "name", pkg.name); + serializer.attribute(null, ATTR_NAME, pkg.name); if (pkg.realName != null) { serializer.attribute(null, "realName", pkg.realName); } @@ -1102,16 +1364,13 @@ final class Settings { serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); if (pkg.sharedUser == null) { - serializer.attribute(null, "userId", Integer.toString(pkg.userId)); + serializer.attribute(null, "userId", Integer.toString(pkg.uid)); } else { - serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId)); + serializer.attribute(null, "sharedUserId", Integer.toString(pkg.uid)); } if (pkg.uidError) { serializer.attribute(null, "uidError", "true"); } - if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { - serializer.attribute(null, "enabled", Integer.toString(pkg.enabled)); - } if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { serializer.attribute(null, "installStatus", "false"); } @@ -1127,31 +1386,13 @@ final class Settings { // empty permissions list so permissionsFixed will // be set. for (final String name : pkg.grantedPermissions) { - serializer.startTag(null, "item"); - serializer.attribute(null, "name", name); - serializer.endTag(null, "item"); + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); } } serializer.endTag(null, "perms"); } - if (pkg.disabledComponents.size() > 0) { - serializer.startTag(null, "disabled-components"); - for (final String name : pkg.disabledComponents) { - serializer.startTag(null, "item"); - serializer.attribute(null, "name", name); - serializer.endTag(null, "item"); - } - serializer.endTag(null, "disabled-components"); - } - if (pkg.enabledComponents.size() > 0) { - serializer.startTag(null, "enabled-components"); - for (final String name : pkg.enabledComponents) { - serializer.startTag(null, "item"); - serializer.attribute(null, "name", name); - serializer.endTag(null, "item"); - } - serializer.endTag(null, "enabled-components"); - } serializer.endTag(null, "package"); } @@ -1159,8 +1400,8 @@ final class Settings { void writePermissionLPr(XmlSerializer serializer, BasePermission bp) throws XmlPullParserException, java.io.IOException { if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) { - serializer.startTag(null, "item"); - serializer.attribute(null, "name", bp.name); + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, bp.name); serializer.attribute(null, "package", bp.sourcePackage); if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) { serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel)); @@ -1180,7 +1421,7 @@ final class Settings { } } } - serializer.endTag(null, "item"); + serializer.endTag(null, TAG_ITEM); } } @@ -1198,7 +1439,7 @@ final class Settings { return ret; } - boolean readLPw() { + boolean readLPw(List<UserInfo> users) { FileInputStream str = null; if (mBackupSettingsFilename.exists()) { try { @@ -1273,7 +1514,7 @@ final class Settings { } else if (tagName.equals("updated-package")) { readDisabledSysPackageLPw(parser); } else if (tagName.equals("cleaning-package")) { - String name = parser.getAttributeValue(null, "name"); + String name = parser.getAttributeValue(null, ATTR_NAME); if (name != null) { mPackagesToBeCleaned.add(name); } @@ -1366,14 +1607,29 @@ final class Settings { final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator(); while (disabledIt.hasNext()) { final PackageSetting disabledPs = disabledIt.next(); - final Object id = getUserIdLPr(disabledPs.userId); + final Object id = getUserIdLPr(disabledPs.uid); if (id != null && id instanceof SharedUserSetting) { disabledPs.sharedUser = (SharedUserSetting) id; } } - readStoppedLPw(); - + if (mBackupStoppedPackagesFilename.exists() + || mStoppedPackagesFilename.exists()) { + // Read old file + readStoppedLPw(); + mBackupStoppedPackagesFilename.delete(); + mStoppedPackagesFilename.delete(); + // Migrate to new file format + writePackageRestrictionsLPr(0); + } else { + if (users == null) { + readPackageRestrictionsLPr(0); + } else { + for (UserInfo user : users) { + readPackageRestrictionsLPr(user.id); + } + } + } mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " + mSharedUsers.size() + " shared uids\n"); @@ -1407,8 +1663,8 @@ final class Settings { } final String tagName = parser.getName(); - if (tagName.equals("item")) { - final String name = parser.getAttributeValue(null, "name"); + if (tagName.equals(TAG_ITEM)) { + final String name = parser.getAttributeValue(null, ATTR_NAME); final String sourcePackage = parser.getAttributeValue(null, "package"); final String ptype = parser.getAttributeValue(null, "type"); if (name != null && sourcePackage != null) { @@ -1444,7 +1700,7 @@ final class Settings { private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException { - String name = parser.getAttributeValue(null, "name"); + String name = parser.getAttributeValue(null, ATTR_NAME); String realName = parser.getAttributeValue(null, "realName"); String codePathStr = parser.getAttributeValue(null, "codePath"); String resourcePathStr = parser.getAttributeValue(null, "resourcePath"); @@ -1497,10 +1753,10 @@ final class Settings { } } String idStr = parser.getAttributeValue(null, "userId"); - ps.userId = idStr != null ? Integer.parseInt(idStr) : 0; - if (ps.userId <= 0) { + ps.uid = idStr != null ? Integer.parseInt(idStr) : 0; + if (ps.uid <= 0) { String sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); - ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; + ps.uid = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; } int outerDepth = parser.getDepth(); int type; @@ -1541,7 +1797,7 @@ final class Settings { String version = null; int versionCode = 0; try { - name = parser.getAttributeValue(null, "name"); + name = parser.getAttributeValue(null, ATTR_NAME); realName = parser.getAttributeValue(null, "realName"); idStr = parser.getAttributeValue(null, "userId"); uidError = parser.getAttributeValue(null, "uidError"); @@ -1672,17 +1928,18 @@ final class Settings { packageSetting.uidError = "true".equals(uidError); packageSetting.installerPackageName = installerPackageName; packageSetting.nativeLibraryPathString = nativeLibraryPathStr; - final String enabledStr = parser.getAttributeValue(null, "enabled"); + // Handle legacy string here for single-user mode + final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); if (enabledStr != null) { try { - packageSetting.enabled = Integer.parseInt(enabledStr); + packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */); } catch (NumberFormatException e) { if (enabledStr.equalsIgnoreCase("true")) { - packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED; + packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0); } else if (enabledStr.equalsIgnoreCase("false")) { - packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED; + packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0); } else if (enabledStr.equalsIgnoreCase("default")) { - packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT; + packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Error in package manager settings: package " + name @@ -1691,8 +1948,9 @@ final class Settings { } } } else { - packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT; + packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0); } + final String installStatusStr = parser.getAttributeValue(null, "installStatus"); if (installStatusStr != null) { if (installStatusStr.equalsIgnoreCase("false")) { @@ -1711,10 +1969,11 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("disabled-components")) { - readDisabledComponentsLPw(packageSetting, parser); - } else if (tagName.equals("enabled-components")) { - readEnabledComponentsLPw(packageSetting, parser); + // Legacy + if (tagName.equals(TAG_DISABLED_COMPONENTS)) { + readDisabledComponentsLPw(packageSetting, parser, 0); + } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) { + readEnabledComponentsLPw(packageSetting, parser, 0); } else if (tagName.equals("sigs")) { packageSetting.signatures.readXml(parser, mPastSignatures); } else if (tagName.equals("perms")) { @@ -1731,8 +1990,8 @@ final class Settings { } } - private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser) - throws IOException, XmlPullParserException { + private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, + int userId) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -1742,10 +2001,10 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("item")) { - String name = parser.getAttributeValue(null, "name"); + if (tagName.equals(TAG_ITEM)) { + String name = parser.getAttributeValue(null, ATTR_NAME); if (name != null) { - packageSetting.disabledComponents.add(name.intern()); + packageSetting.addDisabledComponent(name.intern(), userId); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Error in package manager settings: <disabled-components> has" @@ -1759,8 +2018,8 @@ final class Settings { } } - private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser) - throws IOException, XmlPullParserException { + private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, + int userId) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -1770,10 +2029,10 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("item")) { - String name = parser.getAttributeValue(null, "name"); + if (tagName.equals(TAG_ITEM)) { + String name = parser.getAttributeValue(null, ATTR_NAME); if (name != null) { - packageSetting.enabledComponents.add(name.intern()); + packageSetting.addEnabledComponent(name.intern(), userId); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Error in package manager settings: <enabled-components> has" @@ -1787,13 +2046,13 @@ final class Settings { } } - private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException, IOException { + private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException { String name = null; String idStr = null; int pkgFlags = 0; SharedUserSetting su = null; try { - name = parser.getAttributeValue(null, "name"); + name = parser.getAttributeValue(null, ATTR_NAME); idStr = parser.getAttributeValue(null, "userId"); int userId = idStr != null ? Integer.parseInt(idStr) : 0; if ("true".equals(parser.getAttributeValue(null, "system"))) { @@ -1859,8 +2118,8 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("item")) { - String name = parser.getAttributeValue(null, "name"); + if (tagName.equals(TAG_ITEM)) { + String name = parser.getAttributeValue(null, ATTR_NAME); if (name != null) { outPerms.add(name.intern()); } else { @@ -1887,7 +2146,7 @@ final class Settings { } String tagName = parser.getName(); - if (tagName.equals("item")) { + if (tagName.equals(TAG_ITEM)) { PreferredActivity pa = new PreferredActivity(parser); if (pa.mPref.getParseError() == null) { mPreferredActivities.addFilter(pa); @@ -1940,32 +2199,34 @@ final class Settings { return ps; } - boolean isEnabledLPr(ComponentInfo componentInfo, int flags) { + boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) { if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) { return true; } - final PackageSetting packageSettings = mPackages.get(componentInfo.packageName); + final String pkgName = componentInfo.packageName; + final PackageSetting packageSettings = mPackages.get(pkgName); if (PackageManagerService.DEBUG_SETTINGS) { - Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = " + componentInfo.packageName - + " componentName = " + componentInfo.name); + Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = " + + componentInfo.packageName + " componentName = " + componentInfo.name); Log.v(PackageManagerService.TAG, "enabledComponents: " - + Arrays.toString(packageSettings.enabledComponents.toArray())); + + Arrays.toString(packageSettings.getEnabledComponents(userId).toArray())); Log.v(PackageManagerService.TAG, "disabledComponents: " - + Arrays.toString(packageSettings.disabledComponents.toArray())); + + Arrays.toString(packageSettings.getDisabledComponents(userId).toArray())); } if (packageSettings == null) { return false; } - if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED - || packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER + final int enabled = packageSettings.getEnabled(userId); + if (enabled == COMPONENT_ENABLED_STATE_DISABLED + || enabled == COMPONENT_ENABLED_STATE_DISABLED_USER || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled - && packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) { + && enabled == COMPONENT_ENABLED_STATE_DEFAULT)) { return false; } - if (packageSettings.enabledComponents.contains(componentInfo.name)) { + if (packageSettings.getEnabledComponents(userId).contains(componentInfo.name)) { return true; } - if (packageSettings.disabledComponents.contains(componentInfo.name)) { + if (packageSettings.getDisabledComponents(userId).contains(componentInfo.name)) { return false; } return componentInfo.enabled; @@ -1979,35 +2240,36 @@ final class Settings { return pkg.installerPackageName; } - int getApplicationEnabledSettingLPr(String packageName) { + int getApplicationEnabledSettingLPr(String packageName, int userId) { final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { throw new IllegalArgumentException("Unknown package: " + packageName); } - return pkg.enabled; + return pkg.getEnabled(userId); } - int getComponentEnabledSettingLPr(ComponentName componentName) { + int getComponentEnabledSettingLPr(ComponentName componentName, int userId) { final String packageName = componentName.getPackageName(); final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { throw new IllegalArgumentException("Unknown component: " + componentName); } final String classNameStr = componentName.getClassName(); - return pkg.getCurrentEnabledStateLPr(classNameStr); + return pkg.getCurrentEnabledStateLPr(classNameStr, userId); } - + boolean setPackageStoppedStateLPw(String packageName, boolean stopped, - boolean allowedByPermission, int uid) { + boolean allowedByPermission, int uid, int userId) { + int appId = UserId.getAppId(uid); final PackageSetting pkgSetting = mPackages.get(packageName); if (pkgSetting == null) { throw new IllegalArgumentException("Unknown package: " + packageName); } - if (!allowedByPermission && (uid != pkgSetting.userId)) { + if (!allowedByPermission && (appId != pkgSetting.uid)) { throw new SecurityException( "Permission Denial: attempt to change stopped state from pid=" + Binder.getCallingPid() - + ", uid=" + uid + ", package uid=" + pkgSetting.userId); + + ", uid=" + uid + ", package uid=" + pkgSetting.uid); } if (DEBUG_STOPPED) { if (stopped) { @@ -2016,22 +2278,33 @@ final class Settings { Slog.i(TAG, "Stopping package " + packageName, e); } } - if (pkgSetting.stopped != stopped) { - pkgSetting.stopped = stopped; - pkgSetting.pkg.mSetStopped = stopped; - if (pkgSetting.notLaunched) { + if (pkgSetting.getStopped(userId) != stopped) { + pkgSetting.setStopped(stopped, userId); + // pkgSetting.pkg.mSetStopped = stopped; + if (pkgSetting.getNotLaunched(userId)) { if (pkgSetting.installerPackageName != null) { PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgSetting.name, null, pkgSetting.installerPackageName, null); } - pkgSetting.notLaunched = false; + pkgSetting.setNotLaunched(false, userId); } return true; } return false; } + private List<UserInfo> getAllUsers() { + try { + return AppGlobals.getPackageManager().getUsers(); + } catch (RemoteException re) { + // Local to system process, shouldn't happen + } catch (NullPointerException npe) { + // packagemanager not yet initialized + } + return null; + } + static final void printFlags(PrintWriter pw, int val, Object[] spec) { pw.print("[ "); for (int i=0; i<spec.length; i+=2) { @@ -2096,7 +2369,7 @@ final class Settings { pw.println(ps.name); } - pw.print(" userId="); pw.print(ps.userId); + pw.print(" userId="); pw.print(ps.uid); pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids)); pw.print(" sharedUser="); pw.println(ps.sharedUser); pw.print(" pkg="); pw.println(ps.pkg); @@ -2169,18 +2442,24 @@ final class Settings { pw.print(" haveGids="); pw.println(ps.haveGids); pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags)); pw.print(" installStatus="); pw.print(ps.installStatus); - pw.print(" stopped="); pw.print(ps.stopped); - pw.print(" enabled="); pw.println(ps.enabled); - if (ps.disabledComponents.size() > 0) { - pw.println(" disabledComponents:"); - for (String s : ps.disabledComponents) { - pw.print(" "); pw.println(s); + List<UserInfo> users = getAllUsers(); + for (UserInfo user : users) { + pw.print(" User "); pw.print(user.id); pw.print(": "); + pw.print(" stopped="); + pw.print(ps.getStopped(user.id)); + pw.print(" enabled="); + pw.println(ps.getEnabled(user.id)); + if (ps.getDisabledComponents(user.id).size() > 0) { + pw.println(" disabledComponents:"); + for (String s : ps.getDisabledComponents(user.id)) { + pw.print(" "); pw.println(s); + } } - } - if (ps.enabledComponents.size() > 0) { - pw.println(" enabledComponents:"); - for (String s : ps.enabledComponents) { - pw.print(" "); pw.println(s); + if (ps.getEnabledComponents(user.id).size() > 0) { + pw.println(" enabledComponents:"); + for (String s : ps.getEnabledComponents(user.id)) { + pw.print(" "); pw.println(s); + } } } if (ps.grantedPermissions.size() > 0) { @@ -2234,7 +2513,7 @@ final class Settings { pw.println(ps.name); } pw.print(" userId="); - pw.println(ps.userId); + pw.println(ps.uid); pw.print(" sharedUser="); pw.println(ps.sharedUser); pw.print(" codePath="); @@ -2244,7 +2523,7 @@ final class Settings { } } } - + void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) { boolean printedSomething = false; for (BasePermission p : mPermissions.values()) { diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java index 5eacf4a..959e570 100644 --- a/services/java/com/android/server/pm/UserManager.java +++ b/services/java/com/android/server/pm/UserManager.java @@ -73,6 +73,9 @@ public class UserManager { UserManager(File dataDir, File baseUserPath) { mUsersDir = new File(dataDir, USER_INFO_DIR); mUsersDir.mkdirs(); + // Make zeroth user directory, for services to migrate their files to that location + File userZeroDir = new File(mUsersDir, "0"); + userZeroDir.mkdirs(); mBaseUserPath = baseUserPath; FileUtils.setPermissions(mUsersDir.toString(), FileUtils.S_IRWXU|FileUtils.S_IRWXG diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java new file mode 100644 index 0000000..796372d --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm; + +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + +import com.android.internal.content.PackageHelper; +import com.android.internal.os.AtomicFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashSet; + +import android.os.Debug; +import android.os.Environment; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.storage.IMountService; +import android.test.AndroidTestCase; +import android.util.Log; + +public class PackageManagerSettingsTests extends AndroidTestCase { + + private static final String PACKAGE_NAME_2 = "com.google.app2"; + private static final String PACKAGE_NAME_3 = "com.android.app3"; + private static final String PACKAGE_NAME_1 = "com.google.app1"; + private static final boolean localLOGV = true; + public static final String TAG = "PackageManagerSettingsTests"; + protected final String PREFIX = "android.content.pm"; + + private void writeFile(File file, byte[] data) { + file.mkdirs(); + try { + AtomicFile aFile = new AtomicFile(file); + FileOutputStream fos = aFile.startWrite(); + fos.write(data); + aFile.finishWrite(fos); + } catch (IOException ioe) { + Log.e(TAG, "Cannot write file " + file.getPath()); + } + } + + private void writePackagesXml() { + writeFile(new File(getContext().getFilesDir(), "system/packages.xml"), + ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + + "<packages>" + + "<last-platform-version internal=\"15\" external=\"0\" />" + + "<permission-trees>" + + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />" + + "</permission-trees>" + + "<permissions>" + + "<item name=\"android.permission.WRITE_CALL_LOG\" package=\"android\" protection=\"1\" />" + + "<item name=\"android.permission.ASEC_ACCESS\" package=\"android\" protection=\"2\" />" + + "<item name=\"android.permission.ACCESS_WIMAX_STATE\" package=\"android\" />" + + "<item name=\"android.permission.REBOOT\" package=\"android\" protection=\"18\" />" + + "</permissions>" + + "<package name=\"com.google.app1\" codePath=\"/system/app/app1.apk\" nativeLibraryPath=\"/data/data/com.google.app1/lib\" flags=\"1\" ft=\"1360e2caa70\" it=\"135f2f80d08\" ut=\"1360e2caa70\" version=\"1109\" sharedUserId=\"11000\">" + + "<sigs count=\"1\">" + + "<cert index=\"0\" key=\"308886\" />" + + "</sigs>" + + "</package>" + + "<package name=\"com.google.app2\" codePath=\"/system/app/app2.apk\" nativeLibraryPath=\"/data/data/com.google.app2/lib\" flags=\"1\" ft=\"1360e578718\" it=\"135f2f80d08\" ut=\"1360e578718\" version=\"15\" enabled=\"3\" userId=\"11001\">" + + "<sigs count=\"1\">" + + "<cert index=\"0\" />" + + "</sigs>" + + "</package>" + + "<package name=\"com.android.app3\" codePath=\"/system/app/app3.apk\" nativeLibraryPath=\"/data/data/com.android.app3/lib\" flags=\"1\" ft=\"1360e577b60\" it=\"135f2f80d08\" ut=\"1360e577b60\" version=\"15\" userId=\"11030\">" + + "<sigs count=\"1\">" + + "<cert index=\"1\" key=\"308366\" />" + + "</sigs>" + + "</package>" + + "<shared-user name=\"com.android.shared1\" userId=\"11000\">" + + "<sigs count=\"1\">" + + "<cert index=\"1\" />" + + "</sigs>" + + "<perms>" + + "<item name=\"android.permission.REBOOT\" />" + + "</perms>" + + "</shared-user>" + + "</packages>").getBytes()); + } + + private void writeStoppedPackagesXml() { + writeFile(new File(getContext().getFilesDir(), "system/packages-stopped.xml"), + ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + + "<stopped-packages>" + + "<pkg name=\"com.google.app1\" nl=\"1\" />" + + "<pkg name=\"com.android.app3\" nl=\"1\" />" + + "</stopped-packages>") + .getBytes()); + } + + private void writePackagesList() { + writeFile(new File(getContext().getFilesDir(), "system/packages.list"), + ( "com.google.app1 11000 0 /data/data/com.google.app1" + + "com.google.app2 11001 0 /data/data/com.google.app2" + + "com.android.app3 11030 0 /data/data/com.android.app3") + .getBytes()); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + private void writeOldFiles() { + writePackagesXml(); + writeStoppedPackagesXml(); + writePackagesList(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testSettingsReadOld() { + // Debug.waitForDebugger(); + + // Write the package files and make sure they're parsed properly the first time + writeOldFiles(); + Settings settings = new Settings(getContext().getFilesDir()); + assertEquals(true, settings.readLPw(null)); + assertNotNull(settings.peekPackageLPr(PACKAGE_NAME_3)); + assertNotNull(settings.peekPackageLPr(PACKAGE_NAME_1)); + + PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_1); + assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, ps.getEnabled(0)); + assertEquals(true, ps.getNotLaunched(0)); + + ps = settings.peekPackageLPr(PACKAGE_NAME_2); + assertEquals(false, ps.getStopped(0)); + assertEquals(COMPONENT_ENABLED_STATE_DISABLED_USER, ps.getEnabled(0)); + assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, ps.getEnabled(1)); + } + + public void testNewPackageRestrictionsFile() { + // Write the package files and make sure they're parsed properly the first time + writeOldFiles(); + Settings settings = new Settings(getContext().getFilesDir()); + assertEquals(true, settings.readLPw(null)); + + // Create Settings again to make it read from the new files + settings = new Settings(getContext().getFilesDir()); + assertEquals(true, settings.readLPw(null)); + + PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_2); + assertEquals(COMPONENT_ENABLED_STATE_DISABLED_USER, ps.getEnabled(0)); + assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, ps.getEnabled(1)); + } + + public void testEnableDisable() { + // Write the package files and make sure they're parsed properly the first time + writeOldFiles(); + Settings settings = new Settings(getContext().getFilesDir()); + assertEquals(true, settings.readLPw(null)); + + // Enable/Disable a package + PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_1); + ps.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0); + ps.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 1); + assertEquals(COMPONENT_ENABLED_STATE_DISABLED, ps.getEnabled(0)); + assertEquals(COMPONENT_ENABLED_STATE_ENABLED, ps.getEnabled(1)); + + // Enable/Disable a component + HashSet<String> components = new HashSet<String>(); + String component1 = PACKAGE_NAME_1 + "/.Component1"; + components.add(component1); + ps.setDisabledComponents(components, 0); + HashSet<String> componentsDisabled = ps.getDisabledComponents(0); + assertEquals(1, componentsDisabled.size()); + assertEquals(component1, componentsDisabled.toArray()[0]); + boolean hasEnabled = + ps.getEnabledComponents(0) != null && ps.getEnabledComponents(1).size() > 0; + assertEquals(false, hasEnabled); + + // User 1 should not have any disabled components + boolean hasDisabled = + ps.getDisabledComponents(1) != null && ps.getDisabledComponents(1).size() > 0; + assertEquals(false, hasDisabled); + ps.setEnabledComponents(components, 1); + assertEquals(1, ps.getEnabledComponents(1).size()); + hasEnabled = ps.getEnabledComponents(0) != null && ps.getEnabledComponents(0).size() > 0; + assertEquals(false, hasEnabled); + } +} |