use of android.content.pm.EphemeralResolveInfo in project platform_frameworks_base by android.
the class PackageManagerService method queryIntentActivitiesInternal.
@NonNull
private List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId))
return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, /* requireFullPermission */
false, /* checkShell */
"query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
// reader
boolean sortResult = false;
boolean addEphemeral = false;
boolean matchEphemeralPackage = false;
List<ResolveInfo> result;
final String pkgName = intent.getPackage();
synchronized (mPackages) {
if (pkgName == null) {
List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
// Check for results that need to skip the current profile.
ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, resolvedType, flags, userId);
if (xpResolveInfo != null) {
List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
xpResult.add(xpResolveInfo);
return filterIfNotSystemUser(xpResult, userId);
}
// Check for results in the current profile.
result = filterIfNotSystemUser(mActivities.queryIntent(intent, resolvedType, flags, userId), userId);
addEphemeral = isEphemeralAllowed(intent, result, userId, false);
// Check for cross profile results.
boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents(matchingFilters, intent, resolvedType, flags, userId, hasNonNegativePriorityResult);
if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
boolean isVisibleToUser = filterIfNotSystemUser(Collections.singletonList(xpResolveInfo), userId).size() > 0;
if (isVisibleToUser) {
result.add(xpResolveInfo);
sortResult = true;
}
}
if (hasWebURI(intent)) {
CrossProfileDomainInfo xpDomainInfo = null;
final UserInfo parent = getProfileParent(userId);
if (parent != null) {
xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, flags, userId, parent.id);
}
if (xpDomainInfo != null) {
if (xpResolveInfo != null) {
// If we didn't remove it, the cross-profile ResolveInfo would be twice
// in the result.
result.remove(xpResolveInfo);
}
if (result.size() == 0 && !addEphemeral) {
result.add(xpDomainInfo.resolveInfo);
return result;
}
}
if (result.size() > 1 || addEphemeral) {
result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, xpDomainInfo, userId);
sortResult = true;
}
}
} else {
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
result = filterIfNotSystemUser(mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId), userId);
} else {
// the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result
addEphemeral = isEphemeralAllowed(intent, null, /*result*/
userId, true);
matchEphemeralPackage = true;
result = new ArrayList<ResolveInfo>();
}
}
}
if (addEphemeral) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
final EphemeralResolveInfo ai = getEphemeralResolveInfo(mContext, mEphemeralResolverConnection, intent, resolvedType, userId, matchEphemeralPackage ? pkgName : null);
if (ai != null) {
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
ephemeralInstaller.ephemeralResolveInfo = ai;
// make sure this resolver is the default
ephemeralInstaller.isDefault = true;
ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
ephemeralInstaller.filter = new IntentFilter(intent.getAction());
ephemeralInstaller.filter.addDataPath(intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
result.add(ephemeralInstaller);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
use of android.content.pm.EphemeralResolveInfo in project platform_frameworks_base by android.
the class PackageManagerService method getEphemeralResolveInfo.
private static EphemeralResolveInfo getEphemeralResolveInfo(Context context, EphemeralResolverConnection resolverConnection, Intent intent, String resolvedType, int userId, String packageName) {
final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, ephemeralPrefixCount);
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
final List<EphemeralResolveInfo> ephemeralResolveInfoList = resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
// No hash prefix match; there are no ephemeral apps for this domain.
return null;
}
// Go in reverse order so we match the narrowest scope first.
for (int i = shaPrefix.length - 1; i >= 0; --i) {
for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
continue;
}
final List<IntentFilter> filters = ephemeralApplication.getFilters();
// No filters; this should never happen.
if (filters.isEmpty()) {
continue;
}
if (packageName != null && !packageName.equals(ephemeralApplication.getPackageName())) {
continue;
}
// We have a domain match; resolve the filters to see if anything matches.
final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
for (int j = filters.size() - 1; j >= 0; --j) {
final EphemeralResolveIntentInfo intentInfo = new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
ephemeralResolver.addFilter(intentInfo);
}
List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(intent, resolvedType, false, /*defaultOnly*/
userId);
if (!matchedResolveInfoList.isEmpty()) {
return matchedResolveInfoList.get(0);
}
}
}
// Hash or filter mis-match; no ephemeral apps for this domain.
return null;
}
use of android.content.pm.EphemeralResolveInfo in project android_frameworks_base by DirtyUnicorns.
the class PackageManagerService method getEphemeralResolveInfo.
private static EphemeralResolveInfo getEphemeralResolveInfo(Context context, EphemeralResolverConnection resolverConnection, Intent intent, String resolvedType, int userId, String packageName) {
final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, ephemeralPrefixCount);
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
final List<EphemeralResolveInfo> ephemeralResolveInfoList = resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
// No hash prefix match; there are no ephemeral apps for this domain.
return null;
}
// Go in reverse order so we match the narrowest scope first.
for (int i = shaPrefix.length - 1; i >= 0; --i) {
for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
continue;
}
final List<IntentFilter> filters = ephemeralApplication.getFilters();
// No filters; this should never happen.
if (filters.isEmpty()) {
continue;
}
if (packageName != null && !packageName.equals(ephemeralApplication.getPackageName())) {
continue;
}
// We have a domain match; resolve the filters to see if anything matches.
final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
for (int j = filters.size() - 1; j >= 0; --j) {
final EphemeralResolveIntentInfo intentInfo = new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
ephemeralResolver.addFilter(intentInfo);
}
List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(intent, resolvedType, false, /*defaultOnly*/
userId);
if (!matchedResolveInfoList.isEmpty()) {
return matchedResolveInfoList.get(0);
}
}
}
// Hash or filter mis-match; no ephemeral apps for this domain.
return null;
}
use of android.content.pm.EphemeralResolveInfo in project android_frameworks_base by DirtyUnicorns.
the class PackageManagerService method queryIntentActivitiesInternal.
@NonNull
private List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId))
return Collections.emptyList();
flags = updateFlagsForResolve(flags, userId, intent);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, /* requireFullPermission */
false, /* checkShell */
"query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
// reader
boolean sortResult = false;
boolean addEphemeral = false;
boolean matchEphemeralPackage = false;
List<ResolveInfo> result;
final String pkgName = intent.getPackage();
synchronized (mPackages) {
if (pkgName == null) {
List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
// Check for results that need to skip the current profile.
ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, resolvedType, flags, userId);
if (xpResolveInfo != null) {
List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
xpResult.add(xpResolveInfo);
return filterIfNotSystemUser(xpResult, userId);
}
// Check for results in the current profile.
result = filterIfNotSystemUser(mActivities.queryIntent(intent, resolvedType, flags, userId), userId);
addEphemeral = isEphemeralAllowed(intent, result, userId, false);
// Check for cross profile results.
boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents(matchingFilters, intent, resolvedType, flags, userId, hasNonNegativePriorityResult);
if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
boolean isVisibleToUser = filterIfNotSystemUser(Collections.singletonList(xpResolveInfo), userId).size() > 0;
if (isVisibleToUser) {
result.add(xpResolveInfo);
sortResult = true;
}
}
if (hasWebURI(intent)) {
CrossProfileDomainInfo xpDomainInfo = null;
final UserInfo parent = getProfileParent(userId);
if (parent != null) {
xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, flags, userId, parent.id);
}
if (xpDomainInfo != null) {
if (xpResolveInfo != null) {
// If we didn't remove it, the cross-profile ResolveInfo would be twice
// in the result.
result.remove(xpResolveInfo);
}
if (result.size() == 0 && !addEphemeral) {
// No result in current profile, but found candidate in parent user.
// And we are not going to add emphemeral app, so we can return the
// result straight away.
result.add(xpDomainInfo.resolveInfo);
return result;
}
} else if (result.size() <= 1 && !addEphemeral) {
// further processing.
return result;
}
// We have more than one candidate (combining results from current and parent
// profile), so we need filtering and sorting.
result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, xpDomainInfo, userId);
sortResult = true;
}
} else {
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
result = filterIfNotSystemUser(mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId), userId);
} else {
// the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result
addEphemeral = isEphemeralAllowed(intent, null, /*result*/
userId, true);
matchEphemeralPackage = true;
result = new ArrayList<ResolveInfo>();
}
}
}
if (addEphemeral) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
final EphemeralResolveInfo ai = getEphemeralResolveInfo(mContext, mEphemeralResolverConnection, intent, resolvedType, userId, matchEphemeralPackage ? pkgName : null);
if (ai != null) {
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
ephemeralInstaller.ephemeralResolveInfo = ai;
// make sure this resolver is the default
ephemeralInstaller.isDefault = true;
ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
ephemeralInstaller.filter = new IntentFilter(intent.getAction());
ephemeralInstaller.filter.addDataPath(intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
result.add(ephemeralInstaller);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
Aggregations