19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
191d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackbornimport java.io.PrintWriter;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
2138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackbornimport java.util.Arrays;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
282c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.net.Uri;
292c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.util.FastImmutableArraySet;
30f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport android.util.ArrayMap;
319f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkeyimport android.util.ArraySet;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
33d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackbornimport android.util.MutableInt;
34cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackbornimport android.util.PrintWriterPrinter;
358a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter;
416d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackbornimport com.android.internal.util.FastPrintWriter;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
466c418d585e0a91054b168fde3130188afd006c98Dianne Hackbornpublic abstract class IntentResolver<F extends IntentFilter, R extends Object> {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final private static String TAG = "IntentResolver";
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final private static boolean DEBUG = false;
4943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato    final private static boolean localLOGV = DEBUG || false;
501c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    final private static boolean localVerificationLOGV = DEBUG || false;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addFilter(F f) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (localLOGV) {
548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Adding filter: " + f);
558a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "    Building Lookup Maps:");
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilters.add(f);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numS = register_intent_filter(f, f.schemesIterator(),
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSchemeToFilter, "      Scheme: ");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numT = register_mime_types(f, "      Type: ");
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numS == 0 && numT == 0) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            register_intent_filter(f, f.actionsIterator(),
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mActionToFilter, "      Action: ");
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numT != 0) {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            register_intent_filter(f, f.actionsIterator(),
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTypedActionToFilter, "      TypedAction: ");
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
73f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    private boolean filterEquals(IntentFilter f1, IntentFilter f2) {
74f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        int s1 = f1.countActions();
75f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        int s2 = f2.countActions();
76f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
77f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
78f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
79f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
80f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasAction(f1.getAction(i))) {
81f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
82f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
83f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
84f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countCategories();
85f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countCategories();
86f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
87f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
88f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
89f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
90f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasCategory(f1.getCategory(i))) {
91f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
92f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
93f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
94f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataTypes();
95f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataTypes();
96f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
97f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
98f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
99f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
100f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasExactDataType(f1.getDataType(i))) {
101f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
102f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
103f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
104f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataSchemes();
105f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataSchemes();
106f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
107f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
108f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
109f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
110f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataScheme(f1.getDataScheme(i))) {
111f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
112f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
113f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
114f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataAuthorities();
115f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataAuthorities();
116f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
117f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
118f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
119f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
120f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
121f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
122f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
123f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
124f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataPaths();
125f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataPaths();
126f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
127f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
128f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
129f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
130f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataPath(f1.getDataPath(i))) {
131f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
132f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
133f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
134f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataSchemeSpecificParts();
135f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataSchemeSpecificParts();
136f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
137f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
138f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
139f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
140f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
141f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
142f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
143f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
144f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        return true;
145f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
146f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
147f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    private ArrayList<F> collectFilters(F[] array, IntentFilter matching) {
148f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        ArrayList<F> res = null;
149f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (array != null) {
150f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            for (int i=0; i<array.length; i++) {
151f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                F cur = array[i];
152f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (cur == null) {
153f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    break;
154f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
155f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (filterEquals(cur, matching)) {
156f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    if (res == null) {
157f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                        res = new ArrayList<>();
158f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    }
159f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    res.add(cur);
160f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
161f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
162f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
163f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        return res;
164f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
165f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
166f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    public ArrayList<F> findFilters(IntentFilter matching) {
167f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (matching.countDataSchemes() == 1) {
168f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Fast case.
169f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching);
170f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) {
171f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Another fast case.
172f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching);
173f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0
174f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                && matching.countActions() == 1) {
175f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Last fast case.
176f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mActionToFilter.get(matching.getAction(0)), matching);
177f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else {
178f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            ArrayList<F> res = null;
179f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            for (F cur : mFilters) {
180f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (filterEquals(cur, matching)) {
181f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    if (res == null) {
182f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                        res = new ArrayList<>();
183f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    }
184f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    res.add(cur);
185f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
186f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
187f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return res;
188f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
189f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
190f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeFilter(F f) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFilterInternal(f);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilters.remove(f);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void removeFilterInternal(F f) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (localLOGV) {
1988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Removing filter: " + f);
1998a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
2008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "    Cleaning Lookup Maps:");
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numS = unregister_intent_filter(f, f.schemesIterator(),
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSchemeToFilter, "      Scheme: ");
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numT = unregister_mime_types(f, "      Type: ");
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numS == 0 && numT == 0) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unregister_intent_filter(f, f.actionsIterator(),
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mActionToFilter, "      Action: ");
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numT != 0) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unregister_intent_filter(f, f.actionsIterator(),
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTypedActionToFilter, "      TypedAction: ");
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
216d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn    boolean dumpMap(PrintWriter out, String titlePrefix, String title,
217d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            String prefix, ArrayMap<String, F[]> map, String packageName,
218d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            boolean printFilter, boolean collapseDuplicates) {
219d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final String eprefix = prefix + "  ";
220d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final String fprefix = prefix + "    ";
221d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final ArrayMap<Object, MutableInt> found = new ArrayMap<>();
222d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        boolean printedSomething = false;
223cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn        Printer printer = null;
224d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        for (int mapi=0; mapi<map.size(); mapi++) {
225d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            F[] a = map.valueAt(mapi);
2269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = a.length;
227d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            boolean printedHeader = false;
2289ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            F filter;
229d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            if (collapseDuplicates) {
230d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                found.clear();
231d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<N && (filter=a[i]) != null; i++) {
232d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
233d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        continue;
234d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
235d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    Object label = filterToLabel(filter);
236d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    int index = found.indexOfKey(label);
237d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (index < 0) {
238d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        found.put(label, new MutableInt(1));
239d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    } else {
240d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        found.valueAt(index).value++;
241d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
242d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
243d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<found.size(); i++) {
244d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (title != null) {
245d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(titlePrefix); out.println(title);
246d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        title = null;
247d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
248d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (!printedHeader) {
249d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
250d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        printedHeader = true;
251d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
252d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    printedSomething = true;
253d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value);
254d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
255d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            } else {
256d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<N && (filter=a[i]) != null; i++) {
257d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
258d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        continue;
259d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
260d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (title != null) {
261d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(titlePrefix); out.println(title);
262d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        title = null;
263d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
264d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (!printedHeader) {
265d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
266d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        printedHeader = true;
267d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
268d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    printedSomething = true;
269d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    dumpFilter(out, fprefix, filter);
270d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (printFilter) {
271d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        if (printer == null) {
272d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                            printer = new PrintWriterPrinter(out);
273d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        }
274d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        filter.dump(printer, fprefix + "  ");
275cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                    }
276cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
279d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return printedSomething;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
282cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn    public boolean dump(PrintWriter out, String title, String prefix, String packageName,
283d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            boolean printFilter, boolean collapseDuplicates) {
2841d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        String innerPrefix = prefix + "  ";
285d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String sepPrefix = "\n" + prefix;
286d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String curPrefix = title + "\n" + prefix;
287d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
288d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mTypeToFilter, packageName, printFilter, collapseDuplicates)) {
289d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
290d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
291d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
292d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mBaseTypeToFilter, packageName, printFilter, collapseDuplicates)) {
293d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
294d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
295d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
296d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mWildTypeToFilter, packageName, printFilter, collapseDuplicates)) {
297d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
298d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
299d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
300d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mSchemeToFilter, packageName, printFilter, collapseDuplicates)) {
301d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
302d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
303d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
304d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mActionToFilter, packageName, printFilter, collapseDuplicates)) {
305d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
306d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
307d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
308d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mTypedActionToFilter, packageName, printFilter, collapseDuplicates)) {
309d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
310d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
311d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return curPrefix == sepPrefix;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class IteratorWrapper implements Iterator<F> {
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Iterator<F> mI;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private F mCur;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IteratorWrapper(Iterator<F> it) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI = it;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean hasNext() {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mI.hasNext();
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public F next() {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (mCur = mI.next());
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void remove() {
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCur != null) {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                removeFilterInternal(mCur);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI.remove();
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an iterator allowing filters to be removed.
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Iterator<F> filterIterator() {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new IteratorWrapper(mFilters.iterator());
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a read-only set of the filters.
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Set<F> filterSet() {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Collections.unmodifiableSet(mFilters);
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
353eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    public List<R> queryIntentFromList(Intent intent, String resolvedType,
3549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            boolean defaultOnly, ArrayList<F[]> listCut, int userId) {
355eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        ArrayList<R> resultList = new ArrayList<R>();
356eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
357eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final boolean debug = localLOGV ||
358eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
359eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
3602c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
361eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final String scheme = intent.getScheme();
362eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        int N = listCut.size();
363eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        for (int i = 0; i < N; ++i) {
3642c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
365483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, listCut.get(i), resultList, userId);
366eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        }
367eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        sortResults(resultList);
368eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        return resultList;
369eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    }
370eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
371483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
372483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            int userId) {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String scheme = intent.getScheme();
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ArrayList<R> finalList = new ArrayList<R>();
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean debug = localLOGV ||
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3808a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (debug) Slog.v(
3816d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            TAG, "Resolving type=" + resolvedType + " scheme=" + scheme
3826d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent);
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] firstTypeCut = null;
3859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] secondTypeCut = null;
3869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] thirdTypeCut = null;
3879ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] schemeCut = null;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a MIME type, then we want to collect all of
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match that MIME type.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType != null) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int slashpos = resolvedType.indexOf('/');
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final String baseType = resolvedType.substring(0, slashpos);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!baseType.equals("*")) {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (resolvedType.length() != slashpos+2
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            || resolvedType.charAt(slashpos+1) != '*') {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Not a wild card, so we can just look for all filters that
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // completely match or wildcards whose base type matches.
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mTypeToFilter.get(resolvedType);
40138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
40338ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
40438ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We can match anything with our base type.
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mBaseTypeToFilter.get(baseType);
40838ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
41038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
41138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Any */* types always apply, but we only need to do this
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // if the intent type was not already */*.
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    thirdTypeCut = mWildTypeToFilter.get("*");
41638ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (intent.getAction() != null) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // The intent specified any type ({@literal *}/*).  This
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // can be a whole heck of a lot of things, so as a first
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // cut let's use the action instead.
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    firstTypeCut = mTypedActionToFilter.get(intent.getAction());
42238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a data URI, then we want to collect all of
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match its scheme (we will further refine matches
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // on the authority and path by directly matching each resulting filter).
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (scheme != null) {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            schemeCut = mSchemeToFilter.get(scheme);
43238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent does not specify any data -- either a MIME type or
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // a URI -- then we will only be looking for matches against empty
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // data.
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType == null && scheme == null && intent.getAction() != null) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstTypeCut = mActionToFilter.get(intent.getAction());
44038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4432c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (firstTypeCut != null) {
4452c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
446483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, firstTypeCut, finalList, userId);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondTypeCut != null) {
4492c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
450483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, secondTypeCut, finalList, userId);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (thirdTypeCut != null) {
4532c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
454483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, thirdTypeCut, finalList, userId);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (schemeCut != null) {
4572c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
458483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, schemeCut, finalList, userId);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sortResults(finalList);
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (debug) {
4638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Final result list:");
4646d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            for (int i=0; i<finalList.size(); i++) {
4656d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.v(TAG, "  " + finalList.get(i));
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return finalList;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control whether the given filter is allowed to go into the result
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * list.  Mainly intended to prevent adding multiple filters for the
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same target object.
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean allowFilterResult(F filter, List<R> dest) {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
480e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    /**
481e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * Returns whether the object associated with the given filter is
4821c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * "stopped", that is whether it should not be included in the result
483e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * if the intent requests to excluded stopped objects.
484e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     */
485483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected boolean isFilterStopped(F filter, int userId) {
486e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        return false;
487e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    }
488e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
4896c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    /**
4901c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * Returns whether the given filter is "verified" that is whether it has been verified against
4911c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * its data URIs.
4921c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     *
4931c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * The verification would happen only and only if the Intent action is
4941c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * {@link android.content.Intent#ACTION_VIEW} and the Intent category is
4951c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * {@link android.content.Intent#CATEGORY_BROWSABLE} and the Intent data scheme
4961c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * is "http" or "https".
4971c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     *
4981c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * @see android.content.IntentFilter#setAutoVerify(boolean)
4991c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     * @see android.content.IntentFilter#getAutoVerify()
5001c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio     */
5011c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    protected boolean isFilterVerified(F filter) {
5021c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        return filter.isVerified();
5031c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    }
5041c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
5051c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    /**
5064efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * Returns whether this filter is owned by this package. This must be
5074efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * implemented to provide correct filtering of Intents that have
5084efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * specified a package name they are to be delivered to.
5096c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn     */
5104efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    protected abstract boolean isPackageForFilter(String packageName, F filter);
5119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
5129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    protected abstract F[] newArray(int size);
5139ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
5146c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
515483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected R newResult(F filter, int match, int userId) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (R)filter;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5196c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void sortResults(List<R> results) {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Collections.sort(results, mResolvePrioritySorter);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5241d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn    protected void dumpFilter(PrintWriter out, String prefix, F filter) {
5251d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        out.print(prefix); out.println(filter);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
528d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    protected Object filterToLabel(F filter) {
529d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        return "IntentFilter";
530d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    }
531d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn
532d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
533d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        out.print(prefix); out.print(label); out.print(": "); out.println(count);
534d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    }
535d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn
536f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
5379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
5389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array == null) {
5399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array = newArray(2);
5409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            map.put(name,  array);
5419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array[0] = filter;
5429ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        } else {
5439ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = array.length;
5449ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int i = N;
5459ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (i > 0 && array[i-1] == null) {
5469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                i--;
5479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
5489ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (i < N) {
5499ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                array[i] = filter;
5509ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else {
5519ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray((N*3)/2);
5529ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, N);
5539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                newa[N] = filter;
5549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
5559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
5569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        }
5579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    }
5589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_mime_types(F filter, String prefix) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
567502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5789ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(mTypeToFilter, name, filter);
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5819ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mBaseTypeToFilter, baseName, filter);
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mWildTypeToFilter, baseName, filter);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_mime_types(F filter, String prefix) {
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
598502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
6008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(mTypeToFilter, name, filter);
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
6129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mBaseTypeToFilter, baseName, filter);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6149ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mWildTypeToFilter, baseName, filter);
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_intent_filter(F filter, Iterator<String> i,
621f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
6308a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
6319ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(dest, name, filter);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_intent_filter(F filter, Iterator<String> i,
637f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
6468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
6479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(dest, name, filter);
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
652f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void remove_all_objects(ArrayMap<String, F[]> map, String name,
6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            Object object) {
6549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
6559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array != null) {
6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int LAST = array.length-1;
6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (LAST >= 0 && array[LAST] == null) {
6589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                LAST--;
6599ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            for (int idx=LAST; idx>=0; idx--) {
6619ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                if (array[idx] == object) {
6629ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    final int remain = LAST - idx;
6639ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    if (remain > 0) {
6649ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                        System.arraycopy(array, idx+1, array, idx, remain);
6659ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    }
6669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    array[LAST] = null;
6679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    LAST--;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6709ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (LAST < 0) {
6719ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.remove(name);
6729ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else if (LAST < (array.length/2)) {
6739ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray(LAST+2);
6749ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, LAST+1);
6759ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
6769ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6802c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) {
6812c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Set<String> categories = intent.getCategories();
6822c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        if (categories == null) {
6832c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            return null;
6842c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        }
6852c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()]));
6862c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    }
6872c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown
6882c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
6892c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            boolean debug, boolean defaultOnly,
6909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
6912c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final String action = intent.getAction();
6922c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Uri data = intent.getData();
6936c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn        final String packageName = intent.getPackage();
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
695e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        final boolean excludingStopped = intent.isExcludingStopped();
696e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
6976d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final Printer logPrinter;
6986d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final PrintWriter logPrintWriter;
6996d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (debug) {
7006d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
7016d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = new FastPrintWriter(logPrinter);
7026d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        } else {
7036d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = null;
7046d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = null;
7056d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        }
7066d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
7079ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        final int N = src != null ? src.length : 0;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNonDefaults = false;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
7109ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F filter;
7119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        for (i=0; i<N && (filter=src[i]) != null; i++) {
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int match;
7138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (debug) Slog.v(TAG, "Matching against filter " + filter);
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
715483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            if (excludingStopped && isFilterStopped(filter, userId)) {
716e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                if (debug) {
717e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                    Slog.v(TAG, "  Filter's target is stopped; skipping");
718e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                }
719e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                continue;
720e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            }
721e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
7226c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            // Is delivery being limited to filters owned by a particular package?
7234efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver            if (packageName != null && !isPackageForFilter(packageName, filter)) {
7246c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                if (debug) {
7256c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                    Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
7266c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                }
7276c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                continue;
7286c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            }
7296c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn
7301c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            // Are we verified ?
7311c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            if (filter.getAutoVerify()) {
7321c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                if (localVerificationLOGV || debug) {
7331c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    Slog.v(TAG, "  Filter verified: " + isFilterVerified(filter));
73472c10a25f0b91bac8d50ec512d37d516ece7c9d5Christopher Tate                    int authorities = filter.countDataAuthorities();
73572c10a25f0b91bac8d50ec512d37d516ece7c9d5Christopher Tate                    for (int z = 0; z < authorities; z++) {
73672c10a25f0b91bac8d50ec512d37d516ece7c9d5Christopher Tate                        Slog.v(TAG, "   " + filter.getDataAuthority(z).getHost());
73772c10a25f0b91bac8d50ec512d37d516ece7c9d5Christopher Tate                    }
7381c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                }
7391c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
7401c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Do we already have this one?
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!allowFilterResult(filter, dest)) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
7448a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter's target already added");
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7492c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            match = filter.match(action, resolvedType, scheme, data, categories, TAG);
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (match >= 0) {
7518a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
7526d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        Integer.toHexString(match) + " hasDefault="
7536d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        + filter.hasCategory(Intent.CATEGORY_DEFAULT));
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
755483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    final R oneResult = newResult(filter, match, userId);
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (oneResult != null) {
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        dest.add(oneResult);
7586d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        if (debug) {
7596d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            dumpFilter(logPrintWriter, "    ", filter);
7606d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            logPrintWriter.flush();
7616d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            filter.dump(logPrinter, "    ");
7626d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        }
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasNonDefaults = true;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String reason;
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (match) {
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default: reason = "unknown reason"; break;
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7778a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter did not match: " + reason);
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7826d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (hasNonDefaults) {
7836d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            if (dest.size() == 0) {
7846d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
7856d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            } else if (dest.size() > 1) {
7866d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
7876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            }
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Sorts a List of IntentFilter objects into descending priority order.
7926c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("rawtypes")
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final Comparator mResolvePrioritySorter = new Comparator() {
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int compare(Object o1, Object o2) {
795502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q1 = ((IntentFilter) o1).getPriority();
796502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q2 = ((IntentFilter) o2).getPriority();
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0);
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All filters that have been registered.
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8049f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    private final ArraySet<F> mFilters = new ArraySet<F>();
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the MIME types that have been registered, such as "image/jpeg",
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*", or "{@literal *}/*".
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
810f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>();
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of all fully qualified MIME types that have been
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * registered, such as "image" or "*".  Wild card MIME types such as
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*" will not be here.
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
817f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>();
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of the MIME types with a sub-type wildcard that
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have been registered.  For example, a filter with "image/*" will be
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here as "image" but one with "image/jpeg" will not be
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here.  This also includes the "*" for the "{@literal *}/*"
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * MIME type.
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
826f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>();
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the URI schemes (such as http) that have been registered.
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
831f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>();
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered, but only those that did
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not specify data.
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
837f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered and specified a MIME type.
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
842f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>();
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
844