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
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 @@
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 @@
ApplicationInfo info =
mSelf.mContext.getPackageManager().getApplicationInfo(
- "android", STOCK_PM_FLAGS);
+ "android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info);
synchronized (mSelf) {
@@ -2369,7 +2370,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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 @@
} 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 @@
// 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 @@
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 @@
}
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
};
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 @@
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 @@
// 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 @@
}
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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");