IntentResolver.java revision f2ac2761276e4972f6463d6818c9f5798bdc9a4d
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.HashSet;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.net.Uri;
312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.util.FastImmutableArraySet;
32f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport android.util.ArrayMap;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
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,
2169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            String prefix, Map<String, F[]> map, String packageName,
217cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn            boolean printFilter) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String eprefix = prefix + "  ";
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String fprefix = prefix + "    ";
220d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        boolean printedSomething = false;
221cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn        Printer printer = null;
2229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        for (Map.Entry<String, F[]> e : map.entrySet()) {
2239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            F[] a = e.getValue();
2249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = a.length;
225d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            boolean printedHeader = false;
2269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            F filter;
2279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            for (int i=0; i<N && (filter=a[i]) != null; i++) {
2284efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver                if (packageName != null && !isPackageForFilter(packageName, filter)) {
229d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                    continue;
230d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
231d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                if (title != null) {
232d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                    out.print(titlePrefix); out.println(title);
233d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                    title = null;
234d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
235d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                if (!printedHeader) {
236d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                    out.print(eprefix); out.print(e.getKey()); out.println(":");
237d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                    printedHeader = true;
238d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                }
239d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                printedSomething = true;
240d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn                dumpFilter(out, fprefix, filter);
241cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                if (printFilter) {
242cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                    if (printer == null) {
243cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                        printer = new PrintWriterPrinter(out);
244cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                    }
245cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                    filter.dump(printer, fprefix + "  ");
246cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
249d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return printedSomething;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
252cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn    public boolean dump(PrintWriter out, String title, String prefix, String packageName,
253cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn            boolean printFilter) {
2541d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        String innerPrefix = prefix + "  ";
255d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String sepPrefix = "\n" + prefix;
256d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        String curPrefix = title + "\n" + prefix;
257d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
258cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mTypeToFilter, packageName, printFilter)) {
259d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
260d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
261d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
262cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mBaseTypeToFilter, packageName, printFilter)) {
263d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
264d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
265d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
266cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mWildTypeToFilter, packageName, printFilter)) {
267d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
268d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
269d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
270cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mSchemeToFilter, packageName, printFilter)) {
271d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
272d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
273d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
274cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mActionToFilter, packageName, printFilter)) {
275d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
276d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
277d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
278cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn                mTypedActionToFilter, packageName, printFilter)) {
279d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn            curPrefix = sepPrefix;
280d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        }
281d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        return curPrefix == sepPrefix;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class IteratorWrapper implements Iterator<F> {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Iterator<F> mI;
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private F mCur;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IteratorWrapper(Iterator<F> it) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI = it;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean hasNext() {
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mI.hasNext();
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public F next() {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (mCur = mI.next());
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void remove() {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCur != null) {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                removeFilterInternal(mCur);
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mI.remove();
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an iterator allowing filters to be removed.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Iterator<F> filterIterator() {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new IteratorWrapper(mFilters.iterator());
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a read-only set of the filters.
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Set<F> filterSet() {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Collections.unmodifiableSet(mFilters);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
323eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    public List<R> queryIntentFromList(Intent intent, String resolvedType,
3249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            boolean defaultOnly, ArrayList<F[]> listCut, int userId) {
325eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        ArrayList<R> resultList = new ArrayList<R>();
326eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
327eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final boolean debug = localLOGV ||
328eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
329eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
3302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
331eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        final String scheme = intent.getScheme();
332eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        int N = listCut.size();
333eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        for (int i = 0; i < N; ++i) {
3342c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
335483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, listCut.get(i), resultList, userId);
336eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        }
337eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        sortResults(resultList);
338eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda        return resultList;
339eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda    }
340eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda
341483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
342483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            int userId) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String scheme = intent.getScheme();
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ArrayList<R> finalList = new ArrayList<R>();
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean debug = localLOGV ||
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (debug) Slog.v(
3516d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            TAG, "Resolving type=" + resolvedType + " scheme=" + scheme
3526d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent);
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] firstTypeCut = null;
3559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] secondTypeCut = null;
3569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] thirdTypeCut = null;
3579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] schemeCut = null;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a MIME type, then we want to collect all of
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match that MIME type.
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType != null) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int slashpos = resolvedType.indexOf('/');
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final String baseType = resolvedType.substring(0, slashpos);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!baseType.equals("*")) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (resolvedType.length() != slashpos+2
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            || resolvedType.charAt(slashpos+1) != '*') {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Not a wild card, so we can just look for all filters that
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // completely match or wildcards whose base type matches.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mTypeToFilter.get(resolvedType);
37138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
37338ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
37438ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We can match anything with our base type.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstTypeCut = mBaseTypeToFilter.get(baseType);
37838ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        secondTypeCut = mWildTypeToFilter.get(baseType);
38038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                        if (debug) Slog.v(TAG, "Second type cut: "
38138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                                + Arrays.toString(secondTypeCut));
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Any */* types always apply, but we only need to do this
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // if the intent type was not already */*.
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    thirdTypeCut = mWildTypeToFilter.get("*");
38638ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (intent.getAction() != null) {
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // The intent specified any type ({@literal *}/*).  This
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // can be a whole heck of a lot of things, so as a first
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // cut let's use the action instead.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    firstTypeCut = mTypedActionToFilter.get(intent.getAction());
39238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn                    if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent includes a data URI, then we want to collect all of
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the filters that match its scheme (we will further refine matches
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // on the authority and path by directly matching each resulting filter).
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (scheme != null) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            schemeCut = mSchemeToFilter.get(scheme);
40238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the intent does not specify any data -- either a MIME type or
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // a URI -- then we will only be looking for matches against empty
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // data.
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resolvedType == null && scheme == null && intent.getAction() != null) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstTypeCut = mActionToFilter.get(intent.getAction());
41038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn            if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4132c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (firstTypeCut != null) {
4152c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
416483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, firstTypeCut, finalList, userId);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondTypeCut != null) {
4192c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
420483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, secondTypeCut, finalList, userId);
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (thirdTypeCut != null) {
4232c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
424483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, thirdTypeCut, finalList, userId);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (schemeCut != null) {
4272c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            buildResolveList(intent, categories, debug, defaultOnly,
428483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    resolvedType, scheme, schemeCut, finalList, userId);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sortResults(finalList);
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (debug) {
4338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.v(TAG, "Final result list:");
4346d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            for (int i=0; i<finalList.size(); i++) {
4356d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.v(TAG, "  " + finalList.get(i));
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return finalList;
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control whether the given filter is allowed to go into the result
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * list.  Mainly intended to prevent adding multiple filters for the
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same target object.
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean allowFilterResult(F filter, List<R> dest) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
450e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    /**
451e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * Returns whether the object associated with the given filter is
452e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * "stopped," that is whether it should not be included in the result
453e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     * if the intent requests to excluded stopped objects.
454e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn     */
455483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected boolean isFilterStopped(F filter, int userId) {
456e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        return false;
457e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    }
458e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
4596c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    /**
4604efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * Returns whether this filter is owned by this package. This must be
4614efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * implemented to provide correct filtering of Intents that have
4624efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver     * specified a package name they are to be delivered to.
4636c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn     */
4644efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver    protected abstract boolean isPackageForFilter(String packageName, F filter);
4659ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
4669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    protected abstract F[] newArray(int size);
4679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
4686c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
469483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    protected R newResult(F filter, int match, int userId) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (R)filter;
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4736c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("unchecked")
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void sortResults(List<R> results) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Collections.sort(results, mResolvePrioritySorter);
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn    protected void dumpFilter(PrintWriter out, String prefix, F filter) {
4791d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn        out.print(prefix); out.println(filter);
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
482f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
4839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
4849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array == null) {
4859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array = newArray(2);
4869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            map.put(name,  array);
4879ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            array[0] = filter;
4889ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        } else {
4899ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            final int N = array.length;
4909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int i = N;
4919ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (i > 0 && array[i-1] == null) {
4929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                i--;
4939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
4949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (i < N) {
4959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                array[i] = filter;
4969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else {
4979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray((N*3)/2);
4989ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, N);
4999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                newa[N] = filter;
5009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
5019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
5029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        }
5039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn    }
5049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_mime_types(F filter, String prefix) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
513502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5158a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(mTypeToFilter, name, filter);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mBaseTypeToFilter, baseName, filter);
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                addFilter(mWildTypeToFilter, baseName, filter);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_mime_types(F filter, String prefix) {
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Iterator<String> i = filter.typesIterator();
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
544502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            String name = i.next();
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String baseName = name;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int slashpos = name.indexOf('/');
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                baseName = name.substring(0, slashpos).intern();
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = name + "/*";
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(mTypeToFilter, name, filter);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (slashpos > 0) {
5589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mBaseTypeToFilter, baseName, filter);
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                remove_all_objects(mWildTypeToFilter, baseName, filter);
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int register_intent_filter(F filter, Iterator<String> i,
567f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5779ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            addFilter(dest, name, filter);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int unregister_intent_filter(F filter, Iterator<String> i,
583f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            ArrayMap<String, F[]> dest, String prefix) {
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i == null) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int num = 0;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (i.hasNext()) {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = i.next();
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            num++;
5928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (localLOGV) Slog.v(TAG, prefix + name);
5939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            remove_all_objects(dest, name, filter);
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return num;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
598f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final void remove_all_objects(ArrayMap<String, F[]> map, String name,
5999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            Object object) {
6009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F[] array = map.get(name);
6019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        if (array != null) {
6029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            int LAST = array.length-1;
6039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            while (LAST >= 0 && array[LAST] == null) {
6049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                LAST--;
6059ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6069ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            for (int idx=LAST; idx>=0; idx--) {
6079ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                if (array[idx] == object) {
6089ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    final int remain = LAST - idx;
6099ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    if (remain > 0) {
6109ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                        System.arraycopy(array, idx+1, array, idx, remain);
6119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    }
6129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    array[LAST] = null;
6139ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                    LAST--;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            if (LAST < 0) {
6179ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.remove(name);
6189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            } else if (LAST < (array.length/2)) {
6199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                F[] newa = newArray(LAST+2);
6209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                System.arraycopy(array, 0, newa, 0, LAST+1);
6219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn                map.put(name, newa);
6229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6262c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) {
6272c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Set<String> categories = intent.getCategories();
6282c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        if (categories == null) {
6292c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            return null;
6302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        }
6312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()]));
6322c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    }
6332c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown
6342c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown    private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
6352c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            boolean debug, boolean defaultOnly,
6369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn            String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
6372c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final String action = intent.getAction();
6382c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown        final Uri data = intent.getData();
6396c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn        final String packageName = intent.getPackage();
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
641e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        final boolean excludingStopped = intent.isExcludingStopped();
642e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
6436d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final Printer logPrinter;
6446d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        final PrintWriter logPrintWriter;
6456d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (debug) {
6466d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
6476d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = new FastPrintWriter(logPrinter);
6486d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        } else {
6496d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrinter = null;
6506d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            logPrintWriter = null;
6516d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        }
6526d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        final int N = src != null ? src.length : 0;
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNonDefaults = false;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        F filter;
6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn        for (i=0; i<N && (filter=src[i]) != null; i++) {
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int match;
6598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (debug) Slog.v(TAG, "Matching against filter " + filter);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
661483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            if (excludingStopped && isFilterStopped(filter, userId)) {
662e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                if (debug) {
663e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                    Slog.v(TAG, "  Filter's target is stopped; skipping");
664e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                }
665e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn                continue;
666e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            }
667e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn
6686c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            // Is delivery being limited to filters owned by a particular package?
6694efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver            if (packageName != null && !isPackageForFilter(packageName, filter)) {
6706c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                if (debug) {
6716c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                    Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
6726c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                }
6736c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn                continue;
6746c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn            }
6756c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Do we already have this one?
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!allowFilterResult(filter, dest)) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
6798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter's target already added");
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6842c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown            match = filter.match(action, resolvedType, scheme, data, categories, TAG);
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (match >= 0) {
6868a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
6876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        Integer.toHexString(match) + " hasDefault="
6886d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        + filter.hasCategory(Intent.CATEGORY_DEFAULT));
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
690483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    final R oneResult = newResult(filter, match, userId);
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (oneResult != null) {
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        dest.add(oneResult);
6936d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        if (debug) {
6946d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            dumpFilter(logPrintWriter, "    ", filter);
6956d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            logPrintWriter.flush();
6966d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                            filter.dump(logPrinter, "    ");
6976d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        }
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasNonDefaults = true;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (debug) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String reason;
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (match) {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default: reason = "unknown reason"; break;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "  Filter did not match: " + reason);
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7176d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (hasNonDefaults) {
7186d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            if (dest.size() == 0) {
7196d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
7206d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            } else if (dest.size() > 1) {
7216d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
7226d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            }
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Sorts a List of IntentFilter objects into descending priority order.
7276c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn    @SuppressWarnings("rawtypes")
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final Comparator mResolvePrioritySorter = new Comparator() {
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int compare(Object o1, Object o2) {
730502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q1 = ((IntentFilter) o1).getPriority();
731502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root            final int q2 = ((IntentFilter) o2).getPriority();
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0);
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All filters that have been registered.
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final HashSet<F> mFilters = new HashSet<F>();
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the MIME types that have been registered, such as "image/jpeg",
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*", or "{@literal *}/*".
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
745f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>();
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of all fully qualified MIME types that have been
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * registered, such as "image" or "*".  Wild card MIME types such as
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "image/*" will not be here.
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
752f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>();
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base names of all of the MIME types with a sub-type wildcard that
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have been registered.  For example, a filter with "image/*" will be
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here as "image" but one with "image/jpeg" will not be
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * included here.  This also includes the "*" for the "{@literal *}/*"
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * MIME type.
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
761f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>();
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the URI schemes (such as http) that have been registered.
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
766f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>();
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered, but only those that did
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not specify data.
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
772f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All of the actions that have been registered and specified a MIME type.
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
777f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>();
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
779