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;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addFilter(F f) {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (localLOGV) {
538a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Adding filter: " + f);
548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
558a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "    Building Lookup Maps:");
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilters.add(f);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numS = register_intent_filter(f, f.schemesIterator(),
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSchemeToFilter, "      Scheme: ");
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numT = register_mime_types(f, "      Type: ");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numS == 0 && numT == 0) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            register_intent_filter(f, f.actionsIterator(),
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mActionToFilter, "      Action: ");
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numT != 0) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            register_intent_filter(f, f.actionsIterator(),
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTypedActionToFilter, "      TypedAction: ");
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
72f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    private boolean filterEquals(IntentFilter f1, IntentFilter f2) {
73f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        int s1 = f1.countActions();
74f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        int s2 = f2.countActions();
75f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
76f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
77f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
78f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
79f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasAction(f1.getAction(i))) {
80f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
81f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
82f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
83f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countCategories();
84f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countCategories();
85f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
86f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
87f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
88f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
89f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasCategory(f1.getCategory(i))) {
90f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
91f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
92f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
93f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataTypes();
94f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataTypes();
95f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
96f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
97f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
98f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
99f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasExactDataType(f1.getDataType(i))) {
100f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
101f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
102f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
103f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataSchemes();
104f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataSchemes();
105f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
106f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
107f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
108f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
109f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataScheme(f1.getDataScheme(i))) {
110f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
111f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
112f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
113f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataAuthorities();
114f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataAuthorities();
115f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
116f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
117f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
118f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
119f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
120f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
121f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
122f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
123f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataPaths();
124f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataPaths();
125f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
126f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
127f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
128f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
129f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataPath(f1.getDataPath(i))) {
130f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
131f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
132f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
133f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s1 = f1.countDataSchemeSpecificParts();
134f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        s2 = f2.countDataSchemeSpecificParts();
135f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (s1 != s2) {
136f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return false;
137f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
138f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        for (int i=0; i<s1; i++) {
139f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
140f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                return false;
141f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
142f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
143f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        return true;
144f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
145f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
146f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    private ArrayList<F> collectFilters(F[] array, IntentFilter matching) {
147f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        ArrayList<F> res = null;
148f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (array != null) {
149f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            for (int i=0; i<array.length; i++) {
150f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                F cur = array[i];
151f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (cur == null) {
152f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    break;
153f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
154f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (filterEquals(cur, matching)) {
155f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    if (res == null) {
156f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                        res = new ArrayList<>();
157f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    }
158f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    res.add(cur);
159f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
160f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
161f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
162f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        return res;
163f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
164f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
165f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    public ArrayList<F> findFilters(IntentFilter matching) {
166f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        if (matching.countDataSchemes() == 1) {
167f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Fast case.
168f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching);
169f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) {
170f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Another fast case.
171f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching);
172f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0
173f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                && matching.countActions() == 1) {
174f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            // Last fast case.
175f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return collectFilters(mActionToFilter.get(matching.getAction(0)), matching);
176f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        } else {
177f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            ArrayList<F> res = null;
178f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            for (F cur : mFilters) {
179f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                if (filterEquals(cur, matching)) {
180f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    if (res == null) {
181f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                        res = new ArrayList<>();
182f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    }
183f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                    res.add(cur);
184f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn                }
185f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            }
186f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn            return res;
187f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn        }
188f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn    }
189f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeFilter(F f) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFilterInternal(f);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilters.remove(f);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void removeFilterInternal(F f) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (localLOGV) {
1978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Removing filter: " + f);
1988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
1998a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "    Cleaning Lookup Maps:");
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numS = unregister_intent_filter(f, f.schemesIterator(),
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSchemeToFilter, "      Scheme: ");
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numT = unregister_mime_types(f, "      Type: ");
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numS == 0 && numT == 0) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unregister_intent_filter(f, f.actionsIterator(),
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mActionToFilter, "      Action: ");
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numT != 0) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unregister_intent_filter(f, f.actionsIterator(),
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTypedActionToFilter, "      TypedAction: ");
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
215d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn    boolean dumpMap(PrintWriter out, String titlePrefix, String title,
216d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            String prefix, ArrayMap<String, F[]> map, String packageName,
217d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            boolean printFilter, boolean collapseDuplicates) {
218d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final String eprefix = prefix + "  ";
219d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final String fprefix = prefix + "    ";
220d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        final ArrayMap<Object, MutableInt> found = new ArrayMap<>();
221d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        boolean printedSomething = false;
222cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn        Printer printer = null;
223d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        for (int mapi=0; mapi<map.size(); mapi++) {
224d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            F[] a = map.valueAt(mapi);
2259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = a.length;
226d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            boolean printedHeader = false;
2279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            F filter;
228d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            if (collapseDuplicates) {
229d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                found.clear();
230d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<N && (filter=a[i]) != null; i++) {
231d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
232d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        continue;
233d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
234d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    Object label = filterToLabel(filter);
235d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    int index = found.indexOfKey(label);
236d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (index < 0) {
237d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        found.put(label, new MutableInt(1));
238d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    } else {
239d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        found.valueAt(index).value++;
240d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
241d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
242d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<found.size(); i++) {
243d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (title != null) {
244d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(titlePrefix); out.println(title);
245d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        title = null;
246d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
247d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (!printedHeader) {
248d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
249d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        printedHeader = true;
250d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
251d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    printedSomething = true;
252d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value);
253d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
254d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            } else {
255d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                for (int i=0; i<N && (filter=a[i]) != null; i++) {
256d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
257d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        continue;
258d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
259d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (title != null) {
260d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(titlePrefix); out.println(title);
261d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        title = null;
262d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
263d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (!printedHeader) {
264d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
265d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        printedHeader = true;
266d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
267d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    printedSomething = true;
268d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    dumpFilter(out, fprefix, filter);
269d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (printFilter) {
270d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        if (printer == null) {
271d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                            printer = new PrintWriterPrinter(out);
272d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        }
273d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        filter.dump(printer, fprefix + "  ");
274cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                    }
275cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
278d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return printedSomething;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
281cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn    public boolean dump(PrintWriter out, String title, String prefix, String packageName,
282d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            boolean printFilter, boolean collapseDuplicates) {
2831d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        String innerPrefix = prefix + "  ";
284d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String sepPrefix = "\n" + prefix;
285d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String curPrefix = title + "\n" + prefix;
286d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
287d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mTypeToFilter, packageName, printFilter, collapseDuplicates)) {
288d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
289d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
290d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
291d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mBaseTypeToFilter, packageName, printFilter, collapseDuplicates)) {
292d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
293d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
294d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
295d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mWildTypeToFilter, packageName, printFilter, collapseDuplicates)) {
296d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
297d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
298d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
299d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mSchemeToFilter, packageName, printFilter, collapseDuplicates)) {
300d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
301d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
302d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
303d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mActionToFilter, packageName, printFilter, collapseDuplicates)) {
304d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
305d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
306d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
307d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                mTypedActionToFilter, packageName, printFilter, collapseDuplicates)) {
308d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
309d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
310d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return curPrefix == sepPrefix;
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class IteratorWrapper implements Iterator<F> {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Iterator<F> mI;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private F mCur;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IteratorWrapper(Iterator<F> it) {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI = it;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean hasNext() {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mI.hasNext();
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public F next() {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (mCur = mI.next());
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void remove() {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCur != null) {
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                removeFilterInternal(mCur);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI.remove();
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
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     * Returns an iterator allowing filters to be removed.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Iterator<F> filterIterator() {
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new IteratorWrapper(mFilters.iterator());
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a read-only set of the filters.
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Set<F> filterSet() {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Collections.unmodifiableSet(mFilters);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
352eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    public List<R> queryIntentFromList(Intent intent, String resolvedType,
3539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            boolean defaultOnly, ArrayList<F[]> listCut, int userId) {
354eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        ArrayList<R> resultList = new ArrayList<R>();
355eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
356eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final boolean debug = localLOGV ||
357eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
358eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
3592c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
360eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final String scheme = intent.getScheme();
361eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        int N = listCut.size();
362eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        for (int i = 0; i < N; ++i) {
3632c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
364483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, listCut.get(i), resultList, userId);
365eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        }
366eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        sortResults(resultList);
367eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        return resultList;
368eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    }
369eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
370483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
371483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            int userId) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String scheme = intent.getScheme();
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ArrayList<R> finalList = new ArrayList<R>();
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean debug = localLOGV ||
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (debug) Slog.v(
3806d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            TAG, "Resolving type=" + resolvedType + " scheme=" + scheme
3816d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent);
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] firstTypeCut = null;
3849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] secondTypeCut = null;
3859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] thirdTypeCut = null;
3869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] schemeCut = null;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a MIME type, then we want to collect all of
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match that MIME type.
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType != null) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int slashpos = resolvedType.indexOf('/');
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final String baseType = resolvedType.substring(0, slashpos);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!baseType.equals("*")) {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (resolvedType.length() != slashpos+2
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            || resolvedType.charAt(slashpos+1) != '*') {
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Not a wild card, so we can just look for all filters that
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // completely match or wildcards whose base type matches.
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mTypeToFilter.get(resolvedType);
40038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
40238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
40338ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We can match anything with our base type.
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mBaseTypeToFilter.get(baseType);
40738ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
40938ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
41038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Any */* types always apply, but we only need to do this
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // if the intent type was not already */*.
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    thirdTypeCut = mWildTypeToFilter.get("*");
41538ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (intent.getAction() != null) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // The intent specified any type ({@literal *}/*).  This
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // can be a whole heck of a lot of things, so as a first
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // cut let's use the action instead.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    firstTypeCut = mTypedActionToFilter.get(intent.getAction());
42138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a data URI, then we want to collect all of
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match its scheme (we will further refine matches
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // on the authority and path by directly matching each resulting filter).
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (scheme != null) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            schemeCut = mSchemeToFilter.get(scheme);
43138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent does not specify any data -- either a MIME type or
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // a URI -- then we will only be looking for matches against empty
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // data.
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType == null && scheme == null && intent.getAction() != null) {
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstTypeCut = mActionToFilter.get(intent.getAction());
43938ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4422c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (firstTypeCut != null) {
4442c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
445483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, firstTypeCut, finalList, userId);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondTypeCut != null) {
4482c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
449483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, secondTypeCut, finalList, userId);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (thirdTypeCut != null) {
4522c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
453483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, thirdTypeCut, finalList, userId);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (schemeCut != null) {
4562c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
457483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, schemeCut, finalList, userId);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sortResults(finalList);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (debug) {
4628a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Final result list:");
4636d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            for (int i=0; i<finalList.size(); i++) {
4646d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.v(TAG, "  " + finalList.get(i));
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return finalList;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control whether the given filter is allowed to go into the result
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * list.  Mainly intended to prevent adding multiple filters for the
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same target object.
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean allowFilterResult(F filter, List<R> dest) {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    /**
480e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * Returns whether the object associated with the given filter is
481e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * "stopped," that is whether it should not be included in the result
482e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * if the intent requests to excluded stopped objects.
483e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     */
484483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected boolean isFilterStopped(F filter, int userId) {
485e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        return false;
486e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    }
487e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
4886c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    /**
4894efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * Returns whether this filter is owned by this package. This must be
4904efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * implemented to provide correct filtering of Intents that have
4914efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * specified a package name they are to be delivered to.
4926c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn     */
4934efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    protected abstract boolean isPackageForFilter(String packageName, F filter);
4949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
4959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    protected abstract F[] newArray(int size);
4969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
4976c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
498483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected R newResult(F filter, int match, int userId) {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (R)filter;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5026c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void sortResults(List<R> results) {
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Collections.sort(results, mResolvePrioritySorter);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5071d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn    protected void dumpFilter(PrintWriter out, String prefix, F filter) {
5081d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        out.print(prefix); out.println(filter);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
511d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    protected Object filterToLabel(F filter) {
512d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        return "IntentFilter";
513d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    }
514d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn
515d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
516d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        out.print(prefix); out.print(label); out.print(": "); out.println(count);
517d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn    }
518d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn
519f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
5209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
5219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array == null) {
5229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array = newArray(2);
5239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            map.put(name,  array);
5249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array[0] = filter;
5259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        } else {
5269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = array.length;
5279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int i = N;
5289ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (i > 0 && array[i-1] == null) {
5299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                i--;
5309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
5319ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (i < N) {
5329ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                array[i] = filter;
5339ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else {
5349ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray((N*3)/2);
5359ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, N);
5369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                newa[N] = filter;
5379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
5389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
5399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        }
5409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    }
5419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_mime_types(F filter, String prefix) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
550502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5619ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(mTypeToFilter, name, filter);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5649ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mBaseTypeToFilter, baseName, filter);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mWildTypeToFilter, baseName, filter);
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_mime_types(F filter, String prefix) {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
581502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(mTypeToFilter, name, filter);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mBaseTypeToFilter, baseName, filter);
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mWildTypeToFilter, baseName, filter);
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_intent_filter(F filter, Iterator<String> i,
604f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
6138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
6149ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(dest, name, filter);
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_intent_filter(F filter, Iterator<String> i,
620f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
6298a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
6309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(dest, name, filter);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
635f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void remove_all_objects(ArrayMap<String, F[]> map, String name,
6369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            Object object) {
6379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
6389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array != null) {
6399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int LAST = array.length-1;
6409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (LAST >= 0 && array[LAST] == null) {
6419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                LAST--;
6429ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6439ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            for (int idx=LAST; idx>=0; idx--) {
6449ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                if (array[idx] == object) {
6459ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    final int remain = LAST - idx;
6469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    if (remain > 0) {
6479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                        System.arraycopy(array, idx+1, array, idx, remain);
6489ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    }
6499ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    array[LAST] = null;
6509ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    LAST--;
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (LAST < 0) {
6549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.remove(name);
6559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else if (LAST < (array.length/2)) {
6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray(LAST+2);
6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, LAST+1);
6589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
6599ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6632c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) {
6642c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Set<String> categories = intent.getCategories();
6652c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        if (categories == null) {
6662c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            return null;
6672c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        }
6682c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()]));
6692c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    }
6702c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown
6712c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
6722c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            boolean debug, boolean defaultOnly,
6739ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
6742c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final String action = intent.getAction();
6752c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Uri data = intent.getData();
6766c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn        final String packageName = intent.getPackage();
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
678e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        final boolean excludingStopped = intent.isExcludingStopped();
679e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
6806d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final Printer logPrinter;
6816d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final PrintWriter logPrintWriter;
6826d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (debug) {
6836d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
6846d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = new FastPrintWriter(logPrinter);
6856d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        } else {
6866d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = null;
6876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = null;
6886d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        }
6896d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
6909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        final int N = src != null ? src.length : 0;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNonDefaults = false;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
6939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F filter;
6949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        for (i=0; i<N && (filter=src[i]) != null; i++) {
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int match;
6968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (debug) Slog.v(TAG, "Matching against filter " + filter);
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
698483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            if (excludingStopped && isFilterStopped(filter, userId)) {
699e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                if (debug) {
700e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                    Slog.v(TAG, "  Filter's target is stopped; skipping");
701e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                }
702e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                continue;
703e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            }
704e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
7056c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            // Is delivery being limited to filters owned by a particular package?
7064efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver            if (packageName != null && !isPackageForFilter(packageName, filter)) {
7076c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                if (debug) {
7086c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                    Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
7096c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                }
7106c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                continue;
7116c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            }
7126c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Do we already have this one?
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!allowFilterResult(filter, dest)) {
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
7168a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter's target already added");
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7212c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            match = filter.match(action, resolvedType, scheme, data, categories, TAG);
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (match >= 0) {
7238a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
7246d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        Integer.toHexString(match) + " hasDefault="
7256d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        + filter.hasCategory(Intent.CATEGORY_DEFAULT));
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
727483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    final R oneResult = newResult(filter, match, userId);
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (oneResult != null) {
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        dest.add(oneResult);
7306d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        if (debug) {
7316d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            dumpFilter(logPrintWriter, "    ", filter);
7326d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            logPrintWriter.flush();
7336d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            filter.dump(logPrinter, "    ");
7346d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        }
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasNonDefaults = true;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String reason;
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (match) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default: reason = "unknown reason"; break;
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter did not match: " + reason);
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7546d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (hasNonDefaults) {
7556d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            if (dest.size() == 0) {
7566d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
7576d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            } else if (dest.size() > 1) {
7586d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
7596d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            }
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Sorts a List of IntentFilter objects into descending priority order.
7646c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("rawtypes")
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final Comparator mResolvePrioritySorter = new Comparator() {
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int compare(Object o1, Object o2) {
767502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q1 = ((IntentFilter) o1).getPriority();
768502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q2 = ((IntentFilter) o2).getPriority();
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0);
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All filters that have been registered.
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7769f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    private final ArraySet<F> mFilters = new ArraySet<F>();
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the MIME types that have been registered, such as "image/jpeg",
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*", or "{@literal *}/*".
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
782f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>();
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of all fully qualified MIME types that have been
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * registered, such as "image" or "*".  Wild card MIME types such as
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*" will not be here.
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
789f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>();
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of the MIME types with a sub-type wildcard that
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have been registered.  For example, a filter with "image/*" will be
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here as "image" but one with "image/jpeg" will not be
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here.  This also includes the "*" for the "{@literal *}/*"
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * MIME type.
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
798f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>();
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the URI schemes (such as http) that have been registered.
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
803f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>();
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered, but only those that did
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not specify data.
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered and specified a MIME type.
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
814f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>();
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
816