Search in sources :

Example 1 with EphemeralResolveInfo

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;
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) IntentFilter(android.content.IntentFilter) ArrayList(java.util.ArrayList) UserInfo(android.content.pm.UserInfo) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo) ResolveInfo(android.content.pm.ResolveInfo) PackageParser(android.content.pm.PackageParser) ComponentName(android.content.ComponentName) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo) NonNull(android.annotation.NonNull)

Example 2 with EphemeralResolveInfo

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;
}
Also used : IntentFilter(android.content.IntentFilter) EphemeralDigest(android.content.pm.EphemeralResolveInfo.EphemeralDigest) EphemeralResolveIntentInfo(android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo)

Example 3 with EphemeralResolveInfo

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;
}
Also used : IntentFilter(android.content.IntentFilter) EphemeralDigest(android.content.pm.EphemeralResolveInfo.EphemeralDigest) EphemeralResolveIntentInfo(android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo)

Example 4 with EphemeralResolveInfo

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;
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) IntentFilter(android.content.IntentFilter) ArrayList(java.util.ArrayList) UserInfo(android.content.pm.UserInfo) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo) ResolveInfo(android.content.pm.ResolveInfo) PackageParser(android.content.pm.PackageParser) ComponentName(android.content.ComponentName) EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo) NonNull(android.annotation.NonNull)

Aggregations

IntentFilter (android.content.IntentFilter)4 EphemeralResolveInfo (android.content.pm.EphemeralResolveInfo)4 NonNull (android.annotation.NonNull)2 ComponentName (android.content.ComponentName)2 ActivityInfo (android.content.pm.ActivityInfo)2 EphemeralDigest (android.content.pm.EphemeralResolveInfo.EphemeralDigest)2 EphemeralResolveIntentInfo (android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo)2 PackageParser (android.content.pm.PackageParser)2 ResolveInfo (android.content.pm.ResolveInfo)2 UserInfo (android.content.pm.UserInfo)2 ArrayList (java.util.ArrayList)2