IntentResolver.java revision 43a17654cf4bfe7f1ec22bd8b7b32daccdf27c09
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; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 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; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 33cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackbornimport android.util.PrintWriterPrinter; 348a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class IntentResolver<F extends IntentFilter, R extends Object> { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static String TAG = "IntentResolver"; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static boolean DEBUG = false; 4743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato final private static boolean localLOGV = DEBUG || false; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addFilter(F f) { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 518a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Adding filter: " + f); 528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 538a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Building Lookup Maps:"); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilters.add(f); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numS = register_intent_filter(f, f.schemesIterator(), 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSchemeToFilter, " Scheme: "); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numT = register_mime_types(f, " Type: "); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numS == 0 && numT == 0) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register_intent_filter(f, f.actionsIterator(), 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActionToFilter, " Action: "); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numT != 0) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register_intent_filter(f, f.actionsIterator(), 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypedActionToFilter, " TypedAction: "); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeFilter(F f) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(f); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilters.remove(f); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeFilterInternal(F f) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 778a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Removing filter: " + f); 788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Cleaning Lookup Maps:"); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numS = unregister_intent_filter(f, f.schemesIterator(), 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSchemeToFilter, " Scheme: "); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numT = unregister_mime_types(f, " Type: "); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numS == 0 && numT == 0) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActionToFilter, " Action: "); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numT != 0) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypedActionToFilter, " TypedAction: "); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 95d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean dumpMap(PrintWriter out, String titlePrefix, String title, 96cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn String prefix, Map<String, ArrayList<F>> map, String packageName, 97cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String eprefix = prefix + " "; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String fprefix = prefix + " "; 100d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedSomething = false; 101cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Printer printer = null; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, ArrayList<F>> e : map.entrySet()) { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> a = e.getValue(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = a.size(); 105d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedHeader = false; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 107d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn F filter = a.get(i); 108d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (packageName != null && !packageName.equals(packageForFilter(filter))) { 109d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn continue; 110d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 111d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (title != null) { 112d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(titlePrefix); out.println(title); 113d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn title = null; 114d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 115d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (!printedHeader) { 116d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(eprefix); out.print(e.getKey()); out.println(":"); 117d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedHeader = true; 118d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 119d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedSomething = true; 120d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn dumpFilter(out, fprefix, filter); 121cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printFilter) { 122cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printer == null) { 123cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn printer = new PrintWriterPrinter(out); 124cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 125cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn filter.dump(printer, fprefix + " "); 126cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 129d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return printedSomething; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 132cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn public boolean dump(PrintWriter out, String title, String prefix, String packageName, 133cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 1341d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn String innerPrefix = prefix + " "; 135d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String sepPrefix = "\n" + prefix; 136d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String curPrefix = title + "\n" + prefix; 137d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix, 138cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypeToFilter, packageName, printFilter)) { 139d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 140d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 141d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix, 142cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mBaseTypeToFilter, packageName, printFilter)) { 143d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 144d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 145d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix, 146cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mWildTypeToFilter, packageName, printFilter)) { 147d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 148d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 149d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Schemes:", innerPrefix, 150cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mSchemeToFilter, packageName, printFilter)) { 151d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 152d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 153d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix, 154cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mActionToFilter, packageName, printFilter)) { 155d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 156d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 157d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix, 158cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypedActionToFilter, packageName, printFilter)) { 159d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 160d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 161d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return curPrefix == sepPrefix; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class IteratorWrapper implements Iterator<F> { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Iterator<F> mI; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private F mCur; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IteratorWrapper(Iterator<F> it) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI = it; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasNext() { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mI.hasNext(); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public F next() { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mCur = mI.next()); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove() { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCur != null) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(mCur); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI.remove(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns an iterator allowing filters to be removed. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Iterator<F> filterIterator() { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new IteratorWrapper(mFilters.iterator()); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a read-only set of the filters. 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Set<F> filterSet() { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Collections.unmodifiableSet(mFilters); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 203eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda public List<R> queryIntentFromList(Intent intent, String resolvedType, 204eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda boolean defaultOnly, ArrayList<ArrayList<F>> listCut) { 205eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ArrayList<R> resultList = new ArrayList<R>(); 206eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 207eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final boolean debug = localLOGV || 208eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 209eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 2102c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 211eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final String scheme = intent.getScheme(); 212eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda int N = listCut.size(); 213eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda for (int i = 0; i < N; ++i) { 2142c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 215eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda resolvedType, scheme, listCut.get(i), resultList); 216eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 217eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda sortResults(resultList); 218eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda return resultList; 219eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 220eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 221074edef7c4fce50fc780e864068305f01965e3acMihai Preda public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = intent.getScheme(); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<R> finalList = new ArrayList<R>(); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean debug = localLOGV || 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2298a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v( 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Resolving type " + resolvedType + " scheme " + scheme 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " of intent " + intent); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> firstTypeCut = null; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> secondTypeCut = null; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> thirdTypeCut = null; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> schemeCut = null; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a MIME type, then we want to collect all of 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match that MIME type. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType != null) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int slashpos = resolvedType.indexOf('/'); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String baseType = resolvedType.substring(0, slashpos); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!baseType.equals("*")) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType.length() != slashpos+2 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || resolvedType.charAt(slashpos+1) != '*') { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not a wild card, so we can just look for all filters that 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // completely match or wildcards whose base type matches. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypeToFilter.get(resolvedType); 2508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 2528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can match anything with our base type. 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mBaseTypeToFilter.get(baseType); 2568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 2588a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Any */* types always apply, but we only need to do this 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the intent type was not already */*. 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thirdTypeCut = mWildTypeToFilter.get("*"); 2638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Third type cut: " + thirdTypeCut); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction() != null) { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The intent specified any type ({@literal *}/*). This 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can be a whole heck of a lot of things, so as a first 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cut let's use the action instead. 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 2698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Typed Action list: " + firstTypeCut); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a data URI, then we want to collect all of 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match its scheme (we will further refine matches 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on the authority and path by directly matching each resulting filter). 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scheme != null) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeCut = mSchemeToFilter.get(scheme); 2798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Scheme list: " + schemeCut); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent does not specify any data -- either a MIME type or 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a URI -- then we will only be looking for matches against empty 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // data. 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType == null && scheme == null && intent.getAction() != null) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mActionToFilter.get(intent.getAction()); 2878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Action list: " + firstTypeCut); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2902c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstTypeCut != null) { 2922c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolvedType, scheme, firstTypeCut, finalList); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (secondTypeCut != null) { 2962c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolvedType, scheme, secondTypeCut, finalList); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thirdTypeCut != null) { 3002c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolvedType, scheme, thirdTypeCut, finalList); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (schemeCut != null) { 3042c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolvedType, scheme, schemeCut, finalList); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sortResults(finalList); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 3108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Final result list:"); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (R r : finalList) { 3128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " " + r); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return finalList; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether the given filter is allowed to go into the result 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list. Mainly intended to prevent adding multiple filters for the 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * same target object. 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean allowFilterResult(F filter, List<R> dest) { 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 327e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn /** 328e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * Returns whether the object associated with the given filter is 329e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * "stopped," that is whether it should not be included in the result 330e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * if the intent requests to excluded stopped objects. 331e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn */ 332e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn protected boolean isFilterStopped(F filter) { 333e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn return false; 334e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 335e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 336d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn protected String packageForFilter(F filter) { 337d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return null; 338d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 339d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected R newResult(F filter, int match) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (R)filter; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void sortResults(List<R> results) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(results, mResolvePrioritySorter); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3481d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn protected void dumpFilter(PrintWriter out, String prefix, F filter) { 3491d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn out.print(prefix); out.println(filter); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_mime_types(F filter, String prefix) { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 360502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 3628a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> array = mTypeToFilter.get(name); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (array == null) { 3738a9b22056b13477f59df934928c00c58b5871c95Joe Onorato //Slog.v(TAG, "Creating new array for " + name); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = new ArrayList<F>(); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypeToFilter.put(name, array); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array.add(filter); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = mBaseTypeToFilter.get(baseName); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (array == null) { 3828a9b22056b13477f59df934928c00c58b5871c95Joe Onorato //Slog.v(TAG, "Creating new array for " + name); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = new ArrayList<F>(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBaseTypeToFilter.put(baseName, array); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array.add(filter); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = mWildTypeToFilter.get(baseName); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (array == null) { 3908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato //Slog.v(TAG, "Creating new array for " + name); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = new ArrayList<F>(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWildTypeToFilter.put(baseName, array); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array.add(filter); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_mime_types(F filter, String prefix) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 409502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!remove_all_objects(mTypeToFilter.get(name), filter)) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypeToFilter.remove(name); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!remove_all_objects(mBaseTypeToFilter.get(baseName), filter)) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBaseTypeToFilter.remove(baseName); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!remove_all_objects(mWildTypeToFilter.get(baseName), filter)) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWildTypeToFilter.remove(baseName); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_intent_filter(F filter, Iterator<String> i, 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<String, ArrayList<F>> dest, String prefix) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<F> array = dest.get(name); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (array == null) { 4508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato //Slog.v(TAG, "Creating new array for " + name); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = new ArrayList<F>(); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.put(name, array); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array.add(filter); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_intent_filter(F filter, Iterator<String> i, 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<String, ArrayList<F>> dest, String prefix) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!remove_all_objects(dest.get(name), filter)) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.remove(name); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final boolean remove_all_objects(List<F> list, Object object) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list != null) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = list.size(); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int idx=0; idx<N; idx++) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list.get(idx) == object) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.remove(idx); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx--; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N--; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return N > 0; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4922c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) { 4932c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Set<String> categories = intent.getCategories(); 4942c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown if (categories == null) { 4952c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return null; 4962c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 4972c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()])); 4982c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 4992c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown 5002c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, 5012c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown boolean debug, boolean defaultOnly, 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String resolvedType, String scheme, List<F> src, List<R> dest) { 5032c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final String action = intent.getAction(); 5042c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Uri data = intent.getData(); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 506e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn final boolean excludingStopped = intent.isExcludingStopped(); 507e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = src != null ? src.size() : 0; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasNonDefaults = false; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<N; i++) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project F filter = src.get(i); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int match; 5148a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Matching against filter " + filter); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 516e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn if (excludingStopped && isFilterStopped(filter)) { 517e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn if (debug) { 518e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn Slog.v(TAG, " Filter's target is stopped; skipping"); 519e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 520e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn continue; 521e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 522e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do we already have this one? 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowFilterResult(filter, dest)) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 5268a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter's target already added"); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown match = filter.match(action, resolvedType, scheme, data, categories, TAG); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (match >= 0) { 5338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, " Filter matched! match=0x" + 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Integer.toHexString(match)); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final R oneResult = newResult(filter, match); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oneResult != null) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.add(oneResult); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNonDefaults = true; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String reason; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (match) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: reason = "unknown reason"; break; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5538a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter did not match: " + reason); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dest.size() == 0 && hasNonDefaults) { 5598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT"); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sorts a List of IntentFilter objects into descending priority order. 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Comparator mResolvePrioritySorter = new Comparator() { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Object o1, Object o2) { 566502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q1 = ((IntentFilter) o1).getPriority(); 567502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q2 = ((IntentFilter) o2).getPriority(); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All filters that have been registered. 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashSet<F> mFilters = new HashSet<F>(); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the MIME types that have been registered, such as "image/jpeg", 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*", or "{@literal *}/*". 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mTypeToFilter 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of all fully qualified MIME types that have been 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered, such as "image" or "*". Wild card MIME types such as 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*" will not be here. 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mBaseTypeToFilter 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of the MIME types with a sub-type wildcard that 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * have been registered. For example, a filter with "image/*" will be 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here as "image" but one with "image/jpeg" will not be 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here. This also includes the "*" for the "{@literal *}/*" 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MIME type. 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mWildTypeToFilter 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the URI schemes (such as http) that have been registered. 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mSchemeToFilter 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered, but only those that did 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not specify data. 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mActionToFilter 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered and specified a MIME type. 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, ArrayList<F>> mTypedActionToFilter 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, ArrayList<F>>(); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 622