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

Commit 9c2a9b10 authored by John Wu's avatar John Wu
Browse files

Block intents with action set as null

Update the intent matching algorithm to stop passing action tests if the
provided action is null. This behavior is gated behind targetSdk >= U.

Test: atest IntentFilterTest
Bug: 229362273
Change-Id: I2d8735e2673c926c51b2ef7cf616a5fb3709b628
parent 50fce419
Loading
Loading
Loading
Loading
+70 −3
Original line number Original line Diff line number Diff line
@@ -20,6 +20,9 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemApi;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.net.Uri;
import android.os.Build;
import android.os.Build;
@@ -28,6 +31,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.PatternMatcher;
import android.os.PatternMatcher;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.AndroidException;
import android.util.AndroidException;
import android.util.ArraySet;
import android.util.ArraySet;
@@ -181,6 +185,28 @@ public class IntentFilter implements Parcelable {
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
    private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];


    /**
     * An intent with action set as null used to always pass the action test during intent
     * filter matching. This causes a lot of confusion and unexpected intent matches.
     * Null action intents should be blocked when either the intent sender or receiver
     * application targets U or higher.
     *
     * mBlockNullAction indicates whether the intent filter owner (intent receiver) is
     * targeting U+. This value will be properly set by package manager when IntentFilters are
     * passed to an application, so that when an application is trying to perform intent filter
     * matching locally, the correct matching algorithm will be chosen.
     *
     * When an IntentFilter is sent to system server (e.g. for registering runtime receivers),
     * the value set in mBlockNullAction will be ignored and overwritten with the correct
     * value evaluated based on the Binder calling identity. This makes sure that the
     * security enforcement cannot be bypassed by crafting a malicious IntentFilter.
     *
     * @hide
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public static final long BLOCK_NULL_ACTION_INTENTS = 264497795;

    /**
    /**
     * The filter {@link #setPriority} value at which system high-priority
     * The filter {@link #setPriority} value at which system high-priority
     * receivers are placed; that is, receivers that should execute before
     * receivers are placed; that is, receivers that should execute before
@@ -328,6 +354,8 @@ public class IntentFilter implements Parcelable {
    private ArrayList<String> mMimeGroups = null;
    private ArrayList<String> mMimeGroups = null;
    private boolean mHasStaticPartialTypes = false;
    private boolean mHasStaticPartialTypes = false;
    private boolean mHasDynamicPartialTypes = false;
    private boolean mHasDynamicPartialTypes = false;
    private boolean mBlockNullAction = false;
    private boolean mBlockNullActionEvaluated = false;
    private PersistableBundle mExtras = null;
    private PersistableBundle mExtras = null;


    private static final int STATE_VERIFY_AUTO         = 0x00000001;
    private static final int STATE_VERIFY_AUTO         = 0x00000001;
@@ -527,6 +555,8 @@ public class IntentFilter implements Parcelable {
        }
        }
        mHasStaticPartialTypes = o.mHasStaticPartialTypes;
        mHasStaticPartialTypes = o.mHasStaticPartialTypes;
        mHasDynamicPartialTypes = o.mHasDynamicPartialTypes;
        mHasDynamicPartialTypes = o.mHasDynamicPartialTypes;
        mBlockNullAction = o.getBlockNullAction();
        mBlockNullActionEvaluated = true;
        mVerifyState = o.mVerifyState;
        mVerifyState = o.mVerifyState;
        mInstantAppVisibility = o.mInstantAppVisibility;
        mInstantAppVisibility = o.mInstantAppVisibility;
    }
    }
@@ -2202,6 +2232,30 @@ public class IntentFilter implements Parcelable {
        return mExtras == null ? new PersistableBundle() : mExtras;
        return mExtras == null ? new PersistableBundle() : mExtras;
    }
    }


    /**
     * @hide
     */
    public final void setBlockNullAction(boolean blockNullAction) {
        mBlockNullAction = blockNullAction;
        mBlockNullActionEvaluated = true;
    }

    /**
     * @hide
     */
    public final boolean getBlockNullAction() {
        if (!mBlockNullActionEvaluated) {
            if (Process.myUid() == Process.ROOT_UID) {
                // Do not evaluate the boolean when running as root, as we do not want
                // the value to be evaluated when classes are being preloaded in Zygote.
                return true;
            }
            mBlockNullAction = CompatChanges.isChangeEnabled(BLOCK_NULL_ACTION_INTENTS);
            mBlockNullActionEvaluated = true;
        }
        return mBlockNullAction;
    }

    /**
    /**
     * Return a {@link Predicate} which tests whether this filter matches the
     * Return a {@link Predicate} which tests whether this filter matches the
     * given <var>intent</var>.
     * given <var>intent</var>.
@@ -2254,7 +2308,9 @@ public class IntentFilter implements Parcelable {
        String type = resolve ? intent.resolveType(resolver) : intent.getType();
        String type = resolve ? intent.resolveType(resolver) : intent.getType();
        return match(intent.getAction(), type, intent.getScheme(),
        return match(intent.getAction(), type, intent.getScheme(),
                     intent.getData(), intent.getCategories(), logTag,
                     intent.getData(), intent.getCategories(), logTag,
                     false /* supportWildcards */, null /* ignoreActions */,
                     false /* supportWildcards */,
                     CompatChanges.isChangeEnabled(BLOCK_NULL_ACTION_INTENTS),
                     null /* ignoreActions */,
                     intent.getExtras());
                     intent.getExtras());
    }
    }


@@ -2306,6 +2362,7 @@ public class IntentFilter implements Parcelable {
            Uri data, Set<String> categories, String logTag, boolean supportWildcards,
            Uri data, Set<String> categories, String logTag, boolean supportWildcards,
            @Nullable Collection<String> ignoreActions) {
            @Nullable Collection<String> ignoreActions) {
        return match(action, type, scheme, data, categories, logTag, supportWildcards,
        return match(action, type, scheme, data, categories, logTag, supportWildcards,
                CompatChanges.isChangeEnabled(BLOCK_NULL_ACTION_INTENTS),
                ignoreActions, null /* extras */);
                ignoreActions, null /* extras */);
    }
    }


@@ -2313,12 +2370,19 @@ public class IntentFilter implements Parcelable {
     * Variant of {@link #match(String, String, String, Uri, Set, String, boolean, Collection)}
     * Variant of {@link #match(String, String, String, Uri, Set, String, boolean, Collection)}
     * that supports matching the extra values in the intent.
     * that supports matching the extra values in the intent.
     *
     *
     * @param blockNullAction This value decides whether to always block null action regardless
     *                        of the value of mBlockNullAction. Usually this is determined
     *                        by the caller's target SDK value. For more details, check the
     *                        documentation for {@link #BLOCK_NULL_ACTION_INTENTS}.
     *
     * @hide
     * @hide
     */
     */
    public final int match(String action, String type, String scheme,
    public final int match(String action, String type, String scheme,
            Uri data, Set<String> categories, String logTag, boolean supportWildcards,
            Uri data, Set<String> categories, String logTag, boolean supportWildcards,
            @Nullable Collection<String> ignoreActions, @Nullable Bundle extras) {
            boolean blockNullAction, @Nullable Collection<String> ignoreActions,
        if (action != null && !matchAction(action, supportWildcards, ignoreActions)) {
            @Nullable Bundle extras) {
        if ((action == null && (blockNullAction || getBlockNullAction()))
                || !matchAction(action, supportWildcards, ignoreActions)) {
            if (false) Log.v(
            if (false) Log.v(
                logTag, "No matching action " + action + " for " + this);
                logTag, "No matching action " + action + " for " + this);
            return NO_MATCH_ACTION;
            return NO_MATCH_ACTION;
@@ -2853,6 +2917,7 @@ public class IntentFilter implements Parcelable {
        dest.writeInt(mPriority);
        dest.writeInt(mPriority);
        dest.writeInt(mHasStaticPartialTypes ? 1 : 0);
        dest.writeInt(mHasStaticPartialTypes ? 1 : 0);
        dest.writeInt(mHasDynamicPartialTypes ? 1 : 0);
        dest.writeInt(mHasDynamicPartialTypes ? 1 : 0);
        dest.writeInt(getBlockNullAction() ? 1 : 0);
        dest.writeInt(getAutoVerify() ? 1 : 0);
        dest.writeInt(getAutoVerify() ? 1 : 0);
        dest.writeInt(mInstantAppVisibility);
        dest.writeInt(mInstantAppVisibility);
        dest.writeInt(mOrder);
        dest.writeInt(mOrder);
@@ -2962,6 +3027,8 @@ public class IntentFilter implements Parcelable {
        mPriority = source.readInt();
        mPriority = source.readInt();
        mHasStaticPartialTypes = source.readInt() > 0;
        mHasStaticPartialTypes = source.readInt() > 0;
        mHasDynamicPartialTypes = source.readInt() > 0;
        mHasDynamicPartialTypes = source.readInt() > 0;
        mBlockNullAction = source.readInt() > 0;
        mBlockNullActionEvaluated = true;
        setAutoVerify(source.readInt() > 0);
        setAutoVerify(source.readInt() > 0);
        setVisibilityToInstantApp(source.readInt());
        setVisibilityToInstantApp(source.readInt());
        mOrder = source.readInt();
        mOrder = source.readInt();
+29 −2
Original line number Original line Diff line number Diff line
@@ -16,12 +16,17 @@


package com.android.server;
package com.android.server;


import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH;

import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.compat.CompatChanges;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Process;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.FastImmutableArraySet;
import android.util.FastImmutableArraySet;
@@ -34,6 +39,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastPrintWriter;
import com.android.server.am.ActivityManagerUtils;
import com.android.server.pm.Computer;
import com.android.server.pm.Computer;
import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.pm.snapshot.PackageDataSnapshot;


@@ -169,7 +175,7 @@ public abstract class IntentResolver<F, R extends Object> {
        }
        }


        final int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(),
        final int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(),
                intent.getData(), intent.getCategories(), TAG);
                intent.getData(), intent.getCategories(), TAG, false, false, null, null);


        if (match >= 0) {
        if (match >= 0) {
            if (debug) {
            if (debug) {
@@ -840,7 +846,28 @@ public abstract class IntentResolver<F, R extends Object> {
                continue;
                continue;
            }
            }


            match = intentFilter.match(action, resolvedType, scheme, data, categories, TAG);
            // IntentFilter#mBlockNullAction indicates whether the intent filter owner
            // (intent receiver) is targeting U+. The blockNullAction local variable here
            // indicates whether the calling process (intent sender) is targeting U+.
            // IntentFilter#mBlockNullAction is ignored here, and will be updated and handled in
            // PackageManagerServiceUtils#applySaferIntentEnforcements.

            // Bypass CompatChanges check when calling UID is SYSTEM_UID as it may be in the
            // system server bootstrapping process and can cause circular dependency.
            final boolean blockNullAction = Binder.getCallingUid() == Process.SYSTEM_UID
                    || CompatChanges.isChangeEnabled(
                            IntentFilter.BLOCK_NULL_ACTION_INTENTS, Binder.getCallingUid());
            // Set this to false as it will be updated and handled later
            intentFilter.setBlockNullAction(false);
            match = intentFilter.match(action, resolvedType, scheme, data, categories, TAG,
                    false /*supportWildcards*/, blockNullAction,
                    null /*ignoreActions*/,
                    null /*extras*/);
            if (action == null) {
                ActivityManagerUtils.logUnsafeIntentEvent(
                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH,
                        Binder.getCallingUid(), intent, resolvedType, match < 0);
            }
            if (match >= 0) {
            if (match >= 0) {
                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
                        Integer.toHexString(match) + " hasDefault="
                        Integer.toHexString(match) + " hasDefault="
+14 −13
Original line number Original line Diff line number Diff line
@@ -101,6 +101,7 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALLOWLISTS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALLOWLISTS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
@@ -12714,18 +12715,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            boolean hasToBeExportedToMatch = platformCompat.isChangeEnabledByUid(
            boolean hasToBeExportedToMatch = platformCompat.isChangeEnabledByUid(
                    ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
                    ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
                    callingUid);
                    callingUid);
            String[] categories = intent.getCategories() == null ? new String[0]
            ActivityManagerUtils.logUnsafeIntentEvent(
                    : intent.getCategories().toArray(String[]::new);
                    UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH,
            FrameworkStatsLog.write(FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED,
                    callingUid, intent, resolvedType, hasToBeExportedToMatch);
                    FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH,
                    callingUid,
                    componentInfo,
                    callerPackage,
                    intent.getAction(),
                    categories,
                    resolvedType,
                    intent.getScheme(),
                    hasToBeExportedToMatch);
            if (!hasToBeExportedToMatch) {
            if (!hasToBeExportedToMatch) {
                return;
                return;
            }
            }
@@ -13499,6 +13491,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        final boolean visibleToInstantApps
        final boolean visibleToInstantApps
                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
        // Override the block null action intent information with actual calling UID
        filter.setBlockNullAction(CompatChanges.isChangeEnabled(
                IntentFilter.BLOCK_NULL_ACTION_INTENTS, Binder.getCallingUid()));
        int callingUid;
        int callingUid;
        int callingPid;
        int callingPid;
        boolean instantApp;
        boolean instantApp;
@@ -13639,7 +13635,12 @@ public class ActivityManagerService extends IActivityManager.Stub
                // provider that needs to lock mProviderMap in ActivityThread
                // provider that needs to lock mProviderMap in ActivityThread
                // and also it may need to wait application response, so we
                // and also it may need to wait application response, so we
                // cannot lock ActivityManagerService here.
                // cannot lock ActivityManagerService here.
                if (filter.match(resolver, intent, true, TAG) >= 0) {
                if (filter.match(intent.getAction(), intent.resolveType(resolver),
                        intent.getScheme(), intent.getData(), intent.getCategories(), TAG,
                        false /* supportWildcards */,
                        false /* blockNullAction: already evaluated in the beginning */,
                        null /* ignoreActions */,
                        intent.getExtras()) >= 0) {
                    if (allSticky == null) {
                    if (allSticky == null) {
                        allSticky = new ArrayList<Intent>();
                        allSticky = new ArrayList<Intent>();
                    }
                    }
+23 −0
Original line number Original line Diff line number Diff line
@@ -17,11 +17,13 @@ package com.android.server.am;


import android.app.ActivityThread;
import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.content.Intent;
import android.provider.Settings;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArrayMap;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;


import java.security.MessageDigest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchAlgorithmException;
@@ -133,4 +135,25 @@ public class ActivityManagerUtils {
    public static int hashComponentNameForAtom(String shortInstanceName) {
    public static int hashComponentNameForAtom(String shortInstanceName) {
        return getUnsignedHashUnCached(shortInstanceName) ^ getAndroidIdHash();
        return getUnsignedHashUnCached(shortInstanceName) ^ getAndroidIdHash();
    }
    }

    /**
     * Helper method to log an unsafe intent event.
     */
    public static void logUnsafeIntentEvent(int event, int callingUid,
            Intent intent, String resolvedType, boolean blocked) {
        String[] categories = intent.getCategories() == null ? new String[0]
                : intent.getCategories().toArray(String[]::new);
        String component = intent.getComponent() == null ? null
                : intent.getComponent().flattenToString();
        FrameworkStatsLog.write(FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED,
                event,
                callingUid,
                component,
                intent.getPackage(),
                intent.getAction(),
                categories,
                resolvedType,
                intent.getScheme(),
                blocked);
    }
}
}
+22 −9
Original line number Original line Diff line number Diff line
@@ -16,13 +16,16 @@


package com.android.server.pm;
package com.android.server.pm;


import static android.content.IntentFilter.BLOCK_NULL_ACTION_INTENTS;
import static android.os.Process.THREAD_PRIORITY_DEFAULT;
import static android.os.Process.THREAD_PRIORITY_DEFAULT;


import android.Manifest;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.compat.CompatChanges;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Pair;
@@ -139,19 +142,26 @@ final class AppsFilterUtils {


    private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget,
    private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget,
            WatchedArraySet<String> protectedBroadcasts) {
            WatchedArraySet<String> protectedBroadcasts) {
        final boolean blockNullAction = CompatChanges.isChangeEnabled(BLOCK_NULL_ACTION_INTENTS,
                potentialTarget.getPackageName(), UserHandle.SYSTEM);

        if (matchesAnyComponents(
        if (matchesAnyComponents(
                intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) {
                intent, potentialTarget.getServices(), null /*protectedBroadcasts*/,
                blockNullAction)) {
            return true;
            return true;
        }
        }
        if (matchesAnyComponents(
        if (matchesAnyComponents(
                intent, potentialTarget.getActivities(), null /*protectedBroadcasts*/)) {
                intent, potentialTarget.getActivities(), null /*protectedBroadcasts*/,
                blockNullAction)) {
            return true;
            return true;
        }
        }
        if (matchesAnyComponents(intent, potentialTarget.getReceivers(), protectedBroadcasts)) {
        if (matchesAnyComponents(intent, potentialTarget.getReceivers(), protectedBroadcasts,
                blockNullAction)) {
            return true;
            return true;
        }
        }
        if (matchesAnyComponents(
        if (matchesAnyComponents(
                intent, potentialTarget.getProviders(), null /*protectedBroadcasts*/)) {
                intent, potentialTarget.getProviders(), null /*protectedBroadcasts*/,
                blockNullAction)) {
            return true;
            return true;
        }
        }
        return false;
        return false;
@@ -159,13 +169,14 @@ final class AppsFilterUtils {


    private static boolean matchesAnyComponents(Intent intent,
    private static boolean matchesAnyComponents(Intent intent,
            List<? extends ParsedMainComponent> components,
            List<? extends ParsedMainComponent> components,
            WatchedArraySet<String> protectedBroadcasts) {
            WatchedArraySet<String> protectedBroadcasts,
            boolean blockNullAction) {
        for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) {
        for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) {
            ParsedMainComponent component = components.get(i);
            ParsedMainComponent component = components.get(i);
            if (!component.isExported()) {
            if (!component.isExported()) {
                continue;
                continue;
            }
            }
            if (matchesAnyFilter(intent, component, protectedBroadcasts)) {
            if (matchesAnyFilter(intent, component, protectedBroadcasts, blockNullAction)) {
                return true;
                return true;
            }
            }
        }
        }
@@ -173,10 +184,11 @@ final class AppsFilterUtils {
    }
    }


    private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
    private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
            WatchedArraySet<String> protectedBroadcasts) {
            WatchedArraySet<String> protectedBroadcasts, boolean blockNullAction) {
        List<ParsedIntentInfo> intents = component.getIntents();
        List<ParsedIntentInfo> intents = component.getIntents();
        for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
        for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
            IntentFilter intentFilter = intents.get(i).getIntentFilter();
            IntentFilter intentFilter = intents.get(i).getIntentFilter();
            intentFilter.setBlockNullAction(blockNullAction);
            if (matchesIntentFilter(intent, intentFilter, protectedBroadcasts)) {
            if (matchesIntentFilter(intent, intentFilter, protectedBroadcasts)) {
                return true;
                return true;
            }
            }
@@ -187,8 +199,9 @@ final class AppsFilterUtils {
    private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
    private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
            @Nullable WatchedArraySet<String> protectedBroadcasts) {
            @Nullable WatchedArraySet<String> protectedBroadcasts) {
        return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
        return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
                intent.getData(), intent.getCategories(), "AppsFilter", true,
                intent.getData(), intent.getCategories(), "AppsFilter", true, false,
                protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0;
                protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null,
                null) > 0;
    }
    }


    /**
    /**
Loading