Merge "Implement service filtering" into oc-dev

am: 35110948b7

Change-Id: Ie19ae7075e8fe35857a60306452fe19b06bb1848
This commit is contained in:
Todd Kennedy
2017-04-03 17:46:59 +00:00
committed by android-build-merger
5 changed files with 173 additions and 44 deletions

View File

@@ -310,11 +310,17 @@ public abstract class PackageManagerInternal {
List<String> overlayPackageNames);
/**
* Resolves an intent, allowing instant apps to be resolved.
* Resolves an activity intent, allowing instant apps to be resolved.
*/
public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId);
/**
* Resolves a service intent, allowing instant apps to be resolved.
*/
public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
int flags, int userId, int callingUid);
/**
* Track the creator of a new isolated uid.
* @param isolatedUid The newly created isolated uid.

View File

@@ -398,7 +398,7 @@ public final class ActiveServices {
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
service, neededGrants, callingUid));
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
@@ -1355,10 +1355,10 @@ public final class ActiveServices {
if (r == null) {
try {
// TODO: come back and remove this assumption to triage all services
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
resolvedType, ActivityManagerService.STOCK_PM_FLAGS
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
userId);
userId, callingUid);
ServiceInfo sInfo =
rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
@@ -1927,7 +1927,7 @@ public final class ActiveServices {
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
null, null, 0));
}
sendServiceArgsLocked(r, execInFg, true);
@@ -1979,7 +1979,8 @@ public final class ActiveServices {
mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
si.getUriPermissionsLocked());
}
// TODO b/34123112; Insert ephemeral grant here
mAm.grantEphemeralAccessLocked(r.userId, si.intent,
r.appInfo.uid, UserHandle.getAppId(si.callingId));
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
@@ -2591,7 +2592,7 @@ public final class ActiveServices {
stopServiceLocked(sr);
} else {
sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
sr.makeNextStartId(), baseIntent, null));
sr.makeNextStartId(), baseIntent, null, 0));
if (sr.app != null && sr.app.thread != null) {
// We always run in the foreground, since this is called as
// part of the "remove task" UI operation.

View File

@@ -124,6 +124,7 @@ final class ServiceRecord extends Binder {
final ServiceRecord sr;
final boolean taskRemoved;
final int id;
final int callingId;
final Intent intent;
final ActivityManagerService.NeededUriGrants neededGrants;
long deliveredTime;
@@ -134,12 +135,13 @@ final class ServiceRecord extends Binder {
String stringName; // caching of toString
StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent,
ActivityManagerService.NeededUriGrants _neededGrants) {
ActivityManagerService.NeededUriGrants _neededGrants, int _callingId) {
sr = _sr;
taskRemoved = _taskRemoved;
id = _id;
intent = _intent;
neededGrants = _neededGrants;
callingId = _callingId;
}
UriPermissionOwner getUriPermissionsLocked() {

View File

@@ -3036,13 +3036,14 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
final int callingUid = Binder.getCallingUid();
final int resolveFlags =
MATCH_DIRECT_BOOT_AWARE
| MATCH_DIRECT_BOOT_UNAWARE
| (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
resolveFlags, UserHandle.USER_SYSTEM);
resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
final int N = resolvers.size();
if (N == 0) {
@@ -4021,12 +4022,12 @@ public class PackageManagerService extends IPackageManager.Stub {
* action and a {@code android.intent.category.BROWSABLE} category</li>
* </ul>
*/
int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) {
int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
boolean includeInstantApps) {
// Safe mode means we shouldn't match any third-party components
if (mSafeMode) {
flags |= PackageManager.MATCH_SYSTEM_ONLY;
}
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
// But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
@@ -4038,7 +4039,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|| callingUid == Process.SHELL_UID
|| callingUid == 0;
final boolean allowMatchInstant =
(includeInstantApp
(includeInstantApps
&& Intent.ACTION_VIEW.equals(intent.getAction())
&& intent.hasCategory(Intent.CATEGORY_BROWSABLE)
&& hasWebURI(intent))
@@ -5588,22 +5589,23 @@ public class PackageManagerService extends IPackageManager.Stub {
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
return resolveIntentInternal(
intent, resolvedType, flags, userId, false /*includeInstantApp*/);
intent, resolvedType, flags, userId, false /*includeInstantApps*/);
}
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
int flags, int userId, boolean includeInstantApp) {
int flags, int userId, boolean includeInstantApps) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
flags, userId, includeInstantApp);
flags, userId, includeInstantApps);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
@@ -5623,9 +5625,11 @@ public class PackageManagerService extends IPackageManager.Stub {
if (!sUserManager.exists(userId)) {
return null;
}
final int callingUid = Binder.getCallingUid();
intent = updateIntentForResolve(intent);
final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
final int flags = updateFlagsForResolve(0, userId, intent, false);
final int flags = updateFlagsForResolve(
0, userId, intent, callingUid, false /*includeInstantApps*/);
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
synchronized (mPackages) {
@@ -5914,7 +5918,9 @@ public class PackageManagerService extends IPackageManager.Stub {
List<ResolveInfo> query, int priority, boolean always,
boolean removeMatches, boolean debug, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForResolve(flags, userId, intent, false);
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(
flags, userId, intent, callingUid, false /*includeInstantApps*/);
intent = updateIntentForResolve(intent);
// writer
synchronized (mPackages) {
@@ -6080,9 +6086,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (hasWebURI(intent)) {
// cross-profile app linking works only towards the parent.
final int callingUid = Binder.getCallingUid();
final UserInfo parent = getProfileParent(sourceUserId);
synchronized(mPackages) {
int flags = updateFlagsForResolve(0, parent.id, intent, false);
int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
false /*includeInstantApps*/);
CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
intent, resolvedType, flags, sourceUserId, parent.id);
return xpDomainInfo != null;
@@ -6149,11 +6157,12 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId, boolean includeInstantApp) {
String resolvedType, int flags, int userId, boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
final int callingUid = Binder.getCallingUid();
final String instantAppPkgName = getInstantAppPackageName(callingUid);
flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */,
"query intent activities");
ComponentName comp = intent.getComponent();
@@ -6783,9 +6792,11 @@ public class PackageManagerService extends IPackageManager.Stub {
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent, false);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */,
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(flags, userId, intent, callingUid,
false /*includeInstantApps*/);
enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/,
"query intent activity options");
final String resultsAction = intent.getAction();
@@ -6963,7 +6974,9 @@ public class PackageManagerService extends IPackageManager.Stub {
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent, false);
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(flags, userId, intent, callingUid,
false /*includeInstantApps*/);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -6999,9 +7012,17 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
final int callingUid = Binder.getCallingUid();
return resolveServiceInternal(
intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
}
private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
int userId, int callingUid, boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForResolve(flags, userId, intent, false);
List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
List<ResolveInfo> query = queryIntentServicesInternal(
intent, resolvedType, flags, userId, callingUid, includeInstantApps);
if (query != null) {
if (query.size() >= 1) {
// If there is more than one service with the same priority,
@@ -7015,14 +7036,17 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
String resolvedType, int flags, int userId) {
return new ParceledListSlice<>(
queryIntentServicesInternal(intent, resolvedType, flags, userId));
final int callingUid = Binder.getCallingUid();
return new ParceledListSlice<>(queryIntentServicesInternal(
intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
}
private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
String resolvedType, int flags, int userId) {
String resolvedType, int flags, int userId, int callingUid,
boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent, false);
final String instantAppPkgName = getInstantAppPackageName(callingUid);
flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -7034,9 +7058,27 @@ public class PackageManagerService extends IPackageManager.Stub {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ServiceInfo si = getServiceInfo(comp, flags, userId);
if (si != null) {
final ResolveInfo ri = new ResolveInfo();
ri.serviceInfo = si;
list.add(ri);
// When specifying an explicit component, we prevent the service from being
// used when either 1) the service is in an instant application and the
// caller is not the same instant application or 2) the calling package is
// ephemeral and the activity is not visible to ephemeral applications.
final boolean matchVisibleToInstantAppOnly =
(flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
final boolean isCallerInstantApp =
instantAppPkgName != null;
final boolean isTargetSameInstantApp =
comp.getPackageName().equals(instantAppPkgName);
final boolean isTargetHiddenFromInstantApp =
(si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
final boolean blockResolution =
!isTargetSameInstantApp
&& ((matchVisibleToInstantAppOnly && isCallerInstantApp
&& isTargetHiddenFromInstantApp));
if (!blockResolution) {
final ResolveInfo ri = new ResolveInfo();
ri.serviceInfo = si;
list.add(ri);
}
}
return list;
}
@@ -7045,17 +7087,67 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
return mServices.queryIntent(intent, resolvedType, flags, userId);
return applyPostServiceResolutionFilter(
mServices.queryIntent(intent, resolvedType, flags, userId),
instantAppPkgName);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
userId);
return applyPostServiceResolutionFilter(
mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
userId),
instantAppPkgName);
}
return Collections.emptyList();
}
}
private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
String instantAppPkgName) {
// TODO: When adding on-demand split support for non-instant apps, remove this check
// and always apply post filtering
if (instantAppPkgName == null) {
return resolveInfos;
}
for (int i = resolveInfos.size() - 1; i >= 0; i--) {
final ResolveInfo info = resolveInfos.get(i);
final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
// allow services that are defined in the provided package
if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
if (info.serviceInfo.splitName != null
&& !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
info.serviceInfo.splitName)) {
// requested service is defined in a split that hasn't been installed yet.
// add the installer to the resolve list
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.serviceInfo.packageName, info.serviceInfo.splitName,
info.serviceInfo.applicationInfo.versionCode);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
installerInfo.filter = new IntentFilter();
// load resources from the correct package
installerInfo.resolvePackageName = info.getComponentInfo().packageName;
resolveInfos.set(i, installerInfo);
}
continue;
}
// allow services that have been explicitly exposed to ephemeral apps
if (!isEphemeralApp
&& ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
continue;
}
resolveInfos.remove(i);
}
return resolveInfos;
}
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
String resolvedType, int flags, int userId) {
@@ -7066,7 +7158,9 @@ public class PackageManagerService extends IPackageManager.Stub {
private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent, false);
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForResolve(flags, userId, intent, callingUid,
false /*includeInstantApps*/);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -12401,11 +12495,29 @@ public class PackageManagerService extends IPackageManager.Stub {
if (ps == null) {
return null;
}
final PackageUserState userState = ps.readUserState(userId);
ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
ps.readUserState(userId), userId);
userState, userId);
if (si == null) {
return null;
}
final boolean matchVisibleToInstantApp =
(mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to ephemeral apps
if (matchVisibleToInstantApp
&& !(info.isVisibleToInstantApp() || userState.instantApp)) {
return null;
}
// throw out ephemeral filters if we're not explicitly requesting them
if (!isInstantApp && userState.instantApp) {
return null;
}
// throw out instant app filters if updates are available; will trigger
// instant app resolution
if (userState.instantApp && ps.isUpdateAvailable()) {
return null;
}
final ResolveInfo res = new ResolveInfo();
res.serviceInfo = si;
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
@@ -23135,10 +23247,18 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
}
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
return resolveIntentInternal(
intent, resolvedType, flags, userId, true /*includeInstantApp*/);
intent, resolvedType, flags, userId, true /*includeInstantApps*/);
}
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType,
int flags, int userId, int callingUid) {
return resolveServiceInternal(
intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
}

View File

@@ -3375,7 +3375,7 @@ final class Settings {
private void applyDefaultPreferredActivityLPw(PackageManagerService service,
Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
flags = service.updateFlagsForResolve(flags, userId, intent, false);
flags = service.updateFlagsForResolve(flags, userId, intent, Binder.getCallingUid(), false);
List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
intent.getType(), flags, 0);
if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent