Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de659b3b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Only grant visibility of protected broadcasts to system" into rvc-dev

parents efc98fc7 40cb0205
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.content;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.Uri;
@@ -40,6 +41,7 @@ import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -766,17 +768,31 @@ public class IntentFilter implements Parcelable {
     * @return True if the action is listed in the filter.
     */
    public final boolean matchAction(String action) {
        return matchAction(action, false);
        return matchAction(action, false /*wildcardSupported*/, null /*ignoreActions*/);
    }

    /**
     * Variant of {@link #matchAction(String)} that allows a wildcard for the provided action.
     * @param wildcardSupported if true, will allow action to use wildcards
     * @param ignoreActions if not null, the set of actions to should not be considered valid while
     *                      calculating the match
     */
    private boolean matchAction(String action, boolean wildcardSupported) {
        if (wildcardSupported && !mActions.isEmpty() && WILDCARD.equals(action)) {
    private boolean matchAction(String action, boolean wildcardSupported,
            @Nullable Collection<String> ignoreActions) {
        if (wildcardSupported && WILDCARD.equals(action)) {
            if (ignoreActions == null) {
                return !mActions.isEmpty();
            }
            for (int i = mActions.size() - 1; i >= 0; i--) {
                if (!ignoreActions.contains(mActions.get(i))) {
                    return true;
                }
            }
            return false;
        }
        if (ignoreActions != null && ignoreActions.contains(action)) {
            return false;
        }
        return hasAction(action);
    }

@@ -1779,17 +1795,24 @@ public class IntentFilter implements Parcelable {
     */
    public final int match(String action, String type, String scheme,
            Uri data, Set<String> categories, String logTag) {
        return match(action, type, scheme, data, categories, logTag, false /*supportWildcards*/);
        return match(action, type, scheme, data, categories, logTag, false /*supportWildcards*/,
                null /*ignoreActions*/);
    }

    /**
     * Variant of {@link #match(ContentResolver, Intent, boolean, String)} that supports wildcards
     * in the action, type, scheme, host and path.
     * @hide if true, will allow supported parameters to use wildcards to match this filter
     * @param supportWildcards if true, will allow supported parameters to use wildcards to match
     *                         this filter
     * @param ignoreActions a collection of actions that, if not null should be ignored and not used
     *                      if provided as the matching action or the set of actions defined by this
     *                      filter
     * @hide
     */
    public final int match(String action, String type, String scheme,
            Uri data, Set<String> categories, String logTag, boolean supportWildcards) {
        if (action != null && !matchAction(action, supportWildcards)) {
            Uri data, Set<String> categories, String logTag, boolean supportWildcards,
            @Nullable Collection<String> ignoreActions) {
        if (action != null && !matchAction(action, supportWildcards, ignoreActions)) {
            if (false) Log.v(
                logTag, "No matching action " + action + " for " + this);
            return NO_MATCH_ACTION;
+74 −13
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public class AppsFilter {

    private final OverlayReferenceMapper mOverlayReferenceMapper;
    private PackageParser.SigningDetails mSystemSigningDetails;
    private Set<String> mProtectedBroadcasts = new ArraySet<>();

    AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
            boolean systemAppsQueryable,
@@ -298,10 +299,10 @@ public class AppsFilter {

    /** Returns true if the querying package may query for the potential target package */
    private static boolean canQueryViaComponents(AndroidPackage querying,
            AndroidPackage potentialTarget) {
            AndroidPackage potentialTarget, Set<String> protectedBroadcasts) {
        if (!querying.getQueriesIntents().isEmpty()) {
            for (Intent intent : querying.getQueriesIntents()) {
                if (matchesIntentFilters(intent, potentialTarget)) {
                if (matchesIntentFilters(intent, potentialTarget, protectedBroadcasts)) {
                    return true;
                }
            }
@@ -353,13 +354,14 @@ public class AppsFilter {
        return false;
    }

    private static boolean matchesIntentFilters(Intent intent, AndroidPackage potentialTarget) {
    private static boolean matchesIntentFilters(Intent intent, AndroidPackage potentialTarget,
            Set<String> protectedBroadcasts) {
        for (int s = ArrayUtils.size(potentialTarget.getServices()) - 1; s >= 0; s--) {
            ParsedService service = potentialTarget.getServices().get(s);
            if (!service.isExported()) {
                continue;
            }
            if (matchesAnyFilter(intent, service)) {
            if (matchesAnyFilter(intent, service, null /*protectedBroadcasts*/)) {
                return true;
            }
        }
@@ -368,7 +370,8 @@ public class AppsFilter {
            if (!activity.isExported()) {
                continue;
            }
            if (matchesAnyFilter(intent, activity)) {

            if (matchesAnyFilter(intent, activity, null /*protectedBroadcasts*/)) {
                return true;
            }
        }
@@ -377,25 +380,32 @@ public class AppsFilter {
            if (!receiver.isExported()) {
                continue;
            }
            if (matchesAnyFilter(intent, receiver)) {
            if (matchesAnyFilter(intent, receiver, protectedBroadcasts)) {
                return true;
            }
        }
        return false;
    }

    private static boolean matchesAnyFilter(Intent intent, ParsedComponent component) {
    private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
            Set<String> protectedBroadcasts) {
        List<ParsedIntentInfo> intents = component.getIntents();
        for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
            IntentFilter intentFilter = intents.get(i);
            if (intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
                    intent.getData(), intent.getCategories(), "AppsFilter", true) > 0) {
            if (matchesIntentFilter(intent, intentFilter, protectedBroadcasts)) {
                return true;
            }
        }
        return false;
    }

    private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
            @Nullable Set<String> protectedBroadcasts) {
        return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
                intent.getData(), intent.getCategories(), "AppsFilter", true, protectedBroadcasts)
                > 0;
    }

    /**
     * Grants access based on an interaction between a calling and target package, granting
     * visibility of the caller from the target.
@@ -434,6 +444,12 @@ public class AppsFilter {
                }
            }
        }

        if (!newPkgSetting.pkg.getProtectedBroadcasts().isEmpty()) {
            mProtectedBroadcasts.addAll(newPkgSetting.pkg.getProtectedBroadcasts());
            recomputeComponentVisibility(existingSettings, newPkgSetting.pkg.getPackageName());
        }

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
        try {
            final AndroidPackage newPkg = newPkgSetting.pkg;
@@ -464,7 +480,7 @@ public class AppsFilter {
                final AndroidPackage existingPkg = existingSetting.pkg;
                // let's evaluate the ability of already added packages to see this new package
                if (!newIsForceQueryable) {
                    if (canQueryViaComponents(existingPkg, newPkg)) {
                    if (canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
                        mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
                    }
                    if (canQueryViaPackage(existingPkg, newPkg)
@@ -474,7 +490,7 @@ public class AppsFilter {
                }
                // now we'll evaluate our new package's ability to see existing packages
                if (!mForceQueryable.contains(existingSetting.appId)) {
                    if (canQueryViaComponents(newPkg, existingPkg)) {
                    if (canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
                        mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
                    }
                    if (canQueryViaPackage(newPkg, existingPkg)
@@ -511,10 +527,47 @@ public class AppsFilter {
                && pkgSetting.signatures.mSigningDetails.signaturesMatchExactly(sysSigningDetails);
    }

    private static void sort(int[] uids, int nextUidIndex) {
        Arrays.sort(uids, 0, nextUidIndex);
    private ArraySet<String> collectProtectedBroadcasts(
            ArrayMap<String, PackageSetting> existingSettings, @Nullable String excludePackage) {
        ArraySet<String> ret = new ArraySet<>();
        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            PackageSetting setting = existingSettings.valueAt(i);
            if (setting.pkg == null || setting.pkg.getPackageName().equals(excludePackage)) {
                continue;
            }
            final List<String> protectedBroadcasts = setting.pkg.getProtectedBroadcasts();
            if (!protectedBroadcasts.isEmpty()) {
                ret.addAll(protectedBroadcasts);
            }
        }
        return ret;
    }

    private void recomputeComponentVisibility(ArrayMap<String, PackageSetting> existingSettings,
            @Nullable String excludePackage) {
        mQueriesViaComponent.clear();
        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            PackageSetting setting = existingSettings.valueAt(i);
            if (setting.pkg == null
                    || setting.pkg.getPackageName().equals(excludePackage)
                    || mForceQueryable.contains(setting.appId)) {
                continue;
            }
            for (int j = existingSettings.size() - 1; j >= 0; j--) {
                if (i == j) {
                    continue;
                }
                final PackageSetting otherSetting = existingSettings.valueAt(j);
                if (otherSetting.pkg == null
                        || otherSetting.pkg.getPackageName().equals(excludePackage)) {
                    continue;
                }
                if (canQueryViaComponents(setting.pkg, otherSetting.pkg, mProtectedBroadcasts)) {
                    mQueriesViaComponent.add(setting.appId, otherSetting.appId);
                }
            }
        }
    }
    /**
     * Fetches all app Ids that a given setting is currently visible to, per provided user. This
     * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see
@@ -608,6 +661,14 @@ public class AppsFilter {
            }
        }

        if (!setting.pkg.getProtectedBroadcasts().isEmpty()) {
            final String removingPackageName = setting.pkg.getPackageName();
            mProtectedBroadcasts.clear();
            mProtectedBroadcasts.addAll(
                    collectProtectedBroadcasts(existingSettings, removingPackageName));
            recomputeComponentVisibility(existingSettings, removingPackageName);
        }

        mOverlayReferenceMapper.removePkg(setting.name);
        mFeatureConfig.updatePackageState(setting, true /*removed*/);
    }
+103 −26

File changed.

Preview size limit exceeded, changes collapsed.