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; 379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackbornimport android.util.StringBuilderPrinter; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 456c418d585e0a91054b168fde3130188afd006c98Dianne Hackbornpublic abstract class IntentResolver<F extends IntentFilter, R extends Object> { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static String TAG = "IntentResolver"; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static boolean DEBUG = false; 4843a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato final private static boolean localLOGV = DEBUG || false; 4952c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn final private static boolean VALIDATE = 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 } 709ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 7152c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn if (VALIDATE) { 7252c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn mOldResolver.addFilter(f); 7352c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn verifyDataStructures(f); 7452c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeFilter(F f) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(f); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilters.remove(f); 809ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 8152c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn if (VALIDATE) { 8252c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn mOldResolver.removeFilter(f); 8352c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn verifyDataStructures(f); 8452c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeFilterInternal(F f) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 898a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Removing filter: " + f); 908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 918a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Cleaning Lookup Maps:"); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numS = unregister_intent_filter(f, f.schemesIterator(), 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSchemeToFilter, " Scheme: "); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numT = unregister_mime_types(f, " Type: "); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numS == 0 && numT == 0) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActionToFilter, " Action: "); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numT != 0) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypedActionToFilter, " TypedAction: "); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 107d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean dumpMap(PrintWriter out, String titlePrefix, String title, 1089ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn String prefix, Map<String, F[]> map, String packageName, 109cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String eprefix = prefix + " "; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String fprefix = prefix + " "; 112d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedSomething = false; 113cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Printer printer = null; 1149ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (Map.Entry<String, F[]> e : map.entrySet()) { 1159ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] a = e.getValue(); 1169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = a.length; 117d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedHeader = false; 1189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 1199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int i=0; i<N && (filter=a[i]) != null; i++) { 120d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (packageName != null && !packageName.equals(packageForFilter(filter))) { 121d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn continue; 122d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 123d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (title != null) { 124d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(titlePrefix); out.println(title); 125d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn title = null; 126d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 127d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (!printedHeader) { 128d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(eprefix); out.print(e.getKey()); out.println(":"); 129d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedHeader = true; 130d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 131d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedSomething = true; 132d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn dumpFilter(out, fprefix, filter); 133cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printFilter) { 134cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printer == null) { 135cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn printer = new PrintWriterPrinter(out); 136cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 137cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn filter.dump(printer, fprefix + " "); 138cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 141d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return printedSomething; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 144cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn public boolean dump(PrintWriter out, String title, String prefix, String packageName, 145cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 1461d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn String innerPrefix = prefix + " "; 147d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String sepPrefix = "\n" + prefix; 148d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String curPrefix = title + "\n" + prefix; 149d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix, 150cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypeToFilter, packageName, printFilter)) { 151d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 152d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 153d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix, 154cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mBaseTypeToFilter, packageName, printFilter)) { 155d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 156d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 157d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix, 158cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mWildTypeToFilter, packageName, printFilter)) { 159d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 160d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 161d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Schemes:", innerPrefix, 162cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mSchemeToFilter, packageName, printFilter)) { 163d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 164d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 165d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix, 166cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mActionToFilter, packageName, printFilter)) { 167d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 168d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 169d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix, 170cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypedActionToFilter, packageName, printFilter)) { 171d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 172d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 173d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return curPrefix == sepPrefix; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class IteratorWrapper implements Iterator<F> { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Iterator<F> mI; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private F mCur; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IteratorWrapper(Iterator<F> it) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI = it; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasNext() { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mI.hasNext(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public F next() { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mCur = mI.next()); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove() { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCur != null) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(mCur); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI.remove(); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns an iterator allowing filters to be removed. 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Iterator<F> filterIterator() { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new IteratorWrapper(mFilters.iterator()); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a read-only set of the filters. 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Set<F> filterSet() { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Collections.unmodifiableSet(mFilters); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 215eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda public List<R> queryIntentFromList(Intent intent, String resolvedType, 2169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn boolean defaultOnly, ArrayList<F[]> listCut, int userId) { 217eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ArrayList<R> resultList = new ArrayList<R>(); 218eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 219eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final boolean debug = localLOGV || 220eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 221eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 2222c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 223eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final String scheme = intent.getScheme(); 224eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda int N = listCut.size(); 225eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda for (int i = 0; i < N; ++i) { 2262c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 227483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, listCut.get(i), resultList, userId); 228eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 229eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda sortResults(resultList); 230eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda return resultList; 231eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 232eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 233483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, 234483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani int userId) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = intent.getScheme(); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<R> finalList = new ArrayList<R>(); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean debug = localLOGV || 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2428a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v( 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Resolving type " + resolvedType + " scheme " + scheme 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " of intent " + intent); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] firstTypeCut = null; 2479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] secondTypeCut = null; 2489ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] thirdTypeCut = null; 2499ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] schemeCut = null; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a MIME type, then we want to collect all of 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match that MIME type. 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType != null) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int slashpos = resolvedType.indexOf('/'); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String baseType = resolvedType.substring(0, slashpos); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!baseType.equals("*")) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType.length() != slashpos+2 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || resolvedType.charAt(slashpos+1) != '*') { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not a wild card, so we can just look for all filters that 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // completely match or wildcards whose base type matches. 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypeToFilter.get(resolvedType); 2638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 2658a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can match anything with our base type. 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mBaseTypeToFilter.get(baseType); 2698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 2718a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Any */* types always apply, but we only need to do this 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the intent type was not already */*. 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thirdTypeCut = mWildTypeToFilter.get("*"); 2768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Third type cut: " + thirdTypeCut); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction() != null) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The intent specified any type ({@literal *}/*). This 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can be a whole heck of a lot of things, so as a first 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cut let's use the action instead. 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 2828a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Typed Action list: " + firstTypeCut); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a data URI, then we want to collect all of 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match its scheme (we will further refine matches 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on the authority and path by directly matching each resulting filter). 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scheme != null) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeCut = mSchemeToFilter.get(scheme); 2928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Scheme list: " + schemeCut); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent does not specify any data -- either a MIME type or 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a URI -- then we will only be looking for matches against empty 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // data. 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType == null && scheme == null && intent.getAction() != null) { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mActionToFilter.get(intent.getAction()); 3008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Action list: " + firstTypeCut); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3032c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstTypeCut != null) { 3052c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 306483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, firstTypeCut, finalList, userId); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (secondTypeCut != null) { 3092c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 310483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, secondTypeCut, finalList, userId); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thirdTypeCut != null) { 3132c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 314483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, thirdTypeCut, finalList, userId); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (schemeCut != null) { 3172c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 318483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, schemeCut, finalList, userId); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sortResults(finalList); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32252c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn if (VALIDATE) { 32352c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn List<R> oldList = mOldResolver.queryIntent(intent, resolvedType, defaultOnly, userId); 32452c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn if (oldList.size() != finalList.size()) { 32552c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn ValidationFailure here = new ValidationFailure(); 32652c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn here.fillInStackTrace(); 32752c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn Log.wtf(TAG, "Query result " + intent + " size is " + finalList.size() 32852c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn + "; old implementation is " + oldList.size(), here); 32952c62344c585662d6b441a08c2a69a5732255a6fDianne Hackborn } 3309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 3319ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 3338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Final result list:"); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (R r : finalList) { 3358a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " " + r); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return finalList; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether the given filter is allowed to go into the result 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list. Mainly intended to prevent adding multiple filters for the 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * same target object. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean allowFilterResult(F filter, List<R> dest) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 350e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn /** 351e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * Returns whether the object associated with the given filter is 352e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * "stopped," that is whether it should not be included in the result 353e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * if the intent requests to excluded stopped objects. 354e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn */ 355483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected boolean isFilterStopped(F filter, int userId) { 356e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn return false; 357e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 358e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 3596c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn /** 3606c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn * Return the package that owns this filter. This must be implemented to 3616c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn * provide correct filtering of Intents that have specified a package name 3626c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn * they are to be delivered to. 3636c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn */ 3646c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn protected abstract String packageForFilter(F filter); 3659ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 3669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn protected abstract F[] newArray(int size); 3679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 3686c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 369483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected R newResult(F filter, int match, int userId) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (R)filter; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3736c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void sortResults(List<R> results) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(results, mResolvePrioritySorter); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn protected void dumpFilter(PrintWriter out, String prefix, F filter) { 3791d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn out.print(prefix); out.println(filter); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final void addFilter(HashMap<String, F[]> map, String name, F filter) { 3839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 3849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array == null) { 3859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array = newArray(2); 3869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, array); 3879ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[0] = filter; 3889ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 3899ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = array.length; 3909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int i = N; 3919ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (i > 0 && array[i-1] == null) { 3929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn i--; 3939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 3949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (i < N) { 3959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[i] = filter; 3969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 3979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray((N*3)/2); 3989ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, N); 3999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn newa[N] = filter; 4009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 4019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 4029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 4039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 4049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_mime_types(F filter, String prefix) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 413502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4158a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mTypeToFilter, name, filter); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mBaseTypeToFilter, baseName, filter); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mWildTypeToFilter, baseName, filter); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_mime_types(F filter, String prefix) { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 444502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mTypeToFilter, name, filter); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 4589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mBaseTypeToFilter, baseName, filter); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mWildTypeToFilter, baseName, filter); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_intent_filter(F filter, Iterator<String> i, 4679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn HashMap<String, F[]> dest, String prefix) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4779ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(dest, name, filter); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_intent_filter(F filter, Iterator<String> i, 4839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn HashMap<String, F[]> dest, String prefix) { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 4928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 4939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(dest, name, filter); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final void remove_all_objects(HashMap<String, F[]> map, String name, 4999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Object object) { 5009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 5019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array != null) { 5029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int LAST = array.length-1; 5039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (LAST >= 0 && array[LAST] == null) { 5049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 5059ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5069ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int idx=LAST; idx>=0; idx--) { 5079ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array[idx] == object) { 5089ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int remain = LAST - idx; 5099ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (remain > 0) { 5109ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, idx+1, array, idx, remain); 5119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[LAST] = null; 5139ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (LAST < 0) { 5179ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.remove(name); 5189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else if (LAST < (array.length/2)) { 5199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray(LAST+2); 5209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, LAST+1); 5219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 5229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5262c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) { 5272c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Set<String> categories = intent.getCategories(); 5282c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown if (categories == null) { 5292c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return null; 5302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 5312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()])); 5322c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 5332c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown 5342c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, 5352c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown boolean debug, boolean defaultOnly, 5369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn String resolvedType, String scheme, F[] src, List<R> dest, int userId) { 5372c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final String action = intent.getAction(); 5382c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Uri data = intent.getData(); 5396c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn final String packageName = intent.getPackage(); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 541e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn final boolean excludingStopped = intent.isExcludingStopped(); 542e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 5439ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = src != null ? src.length : 0; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasNonDefaults = false; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 5469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 5479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (i=0; i<N && (filter=src[i]) != null; i++) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int match; 5498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Matching against filter " + filter); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 551483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani if (excludingStopped && isFilterStopped(filter, userId)) { 552e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn if (debug) { 553e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn Slog.v(TAG, " Filter's target is stopped; skipping"); 554e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 555e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn continue; 556e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 557e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 5586c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn // Is delivery being limited to filters owned by a particular package? 5596c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn if (packageName != null && !packageName.equals(packageForFilter(filter))) { 5606c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn if (debug) { 5616c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn Slog.v(TAG, " Filter is not from package " + packageName + "; skipping"); 5626c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 5636c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn continue; 5646c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 5656c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do we already have this one? 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowFilterResult(filter, dest)) { 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 5698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter's target already added"); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5742c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown match = filter.match(action, resolvedType, scheme, data, categories, TAG); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (match >= 0) { 5768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, " Filter matched! match=0x" + 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Integer.toHexString(match)); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 579483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani final R oneResult = newResult(filter, match, userId); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oneResult != null) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.add(oneResult); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNonDefaults = true; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String reason; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (match) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: reason = "unknown reason"; break; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter did not match: " + reason); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dest.size() == 0 && hasNonDefaults) { 6028a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT"); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sorts a List of IntentFilter objects into descending priority order. 6076c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("rawtypes") 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Comparator mResolvePrioritySorter = new Comparator() { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Object o1, Object o2) { 610502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q1 = ((IntentFilter) o1).getPriority(); 611502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q2 = ((IntentFilter) o2).getPriority(); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn static class ValidationFailure extends RuntimeException { 6179ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 6199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private void verifyDataStructures(IntentFilter src) { 6209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mTypeToFilter", mTypeToFilter, mOldResolver.mTypeToFilter); 6219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mBaseTypeToFilter", mBaseTypeToFilter, mOldResolver.mBaseTypeToFilter); 6229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mWildTypeToFilter", mWildTypeToFilter, mOldResolver.mWildTypeToFilter); 6239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mSchemeToFilter", mSchemeToFilter, mOldResolver.mSchemeToFilter); 6249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mActionToFilter", mActionToFilter, mOldResolver.mActionToFilter); 6259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn compareMaps(src, "mTypedActionToFilter", mTypedActionToFilter, mOldResolver.mTypedActionToFilter); 6269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 6289ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private void compareMaps(IntentFilter src, String name, HashMap<String, F[]> cur, 6299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn HashMap<String, ArrayList<F>> old) { 6309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (cur.size() != old.size()) { 6319ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn StringBuilder missing = new StringBuilder(128); 6329ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (Map.Entry<String, ArrayList<F>> e : old.entrySet()) { 6339ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final F[] curArray = cur.get(e.getKey()); 6349ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (curArray == null) { 6359ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (missing.length() > 0) { 6369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn missing.append(' '); 6379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn missing.append(e.getKey()); 6399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn StringBuilder extra = new StringBuilder(128); 6429ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (Map.Entry<String, F[]> e : cur.entrySet()) { 6439ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (old.get(e.getKey()) == null) { 6449ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (extra.length() > 0) { 6459ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn extra.append(' '); 6469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn extra.append(e.getKey()); 6489ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6499ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6509ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn StringBuilder srcStr = new StringBuilder(1024); 6519ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn StringBuilderPrinter printer = new StringBuilderPrinter(srcStr); 6529ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn src.dump(printer, ""); 6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn ValidationFailure here = new ValidationFailure(); 6549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn here.fillInStackTrace(); 6559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Log.wtf(TAG, "New map " + name + " size is " + cur.size() 6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + "; old implementation is " + old.size() 6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + "; missing: " + missing.toString() 6589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + "; extra: " + extra.toString() 6599ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + "; src: " + srcStr.toString(), here); 6609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return; 6619ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6629ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (Map.Entry<String, ArrayList<F>> e : old.entrySet()) { 6639ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final F[] curArray = cur.get(e.getKey()); 6649ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int curLen = curArray != null ? curArray.length : 0; 6659ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (curLen == 0) { 6669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn ValidationFailure here = new ValidationFailure(); 6679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn here.fillInStackTrace(); 6689ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Log.wtf(TAG, "New map " + name + " doesn't contain expected key " 6699ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + e.getKey() + " (array=" + curArray + ")"); 6709ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return; 6719ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6729ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (curLen > 0 && curArray[curLen-1] == null) { 6739ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn curLen--; 6749ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6759ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final ArrayList<F> oldArray = e.getValue(); 6769ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int oldLen = oldArray.size(); 6779ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (curLen != oldLen) { 6789ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn ValidationFailure here = new ValidationFailure(); 6799ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn here.fillInStackTrace(); 6809ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Log.wtf(TAG, "New map " + name + " entry " + e.getKey() + " size is " 6819ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + curLen + "; old implementation is " + oldLen, here); 6829ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return; 6839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int i=0; i<oldLen; i++) { 6859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F f = oldArray.get(i); 6869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn boolean found = false; 6879ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int j=0; j<curLen; j++) { 6889ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (curArray[j] == f) { 6899ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn found = true; 6909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn break; 6919ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (!found) { 6949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn ValidationFailure here = new ValidationFailure(); 6959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn here.fillInStackTrace(); 6969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Log.wtf(TAG, "New map " + name + " entry + " + e.getKey() 6979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + " doesn't contain expected filter " + f, here); 6989ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int i=0; i<curLen; i++) { 7019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (curArray[i] == null) { 7029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn ValidationFailure here = new ValidationFailure(); 7039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn here.fillInStackTrace(); 7049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Log.wtf(TAG, "New map " + name + " entry + " + e.getKey() 7059ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn + " has unexpected null at " + i + "; array: " + curArray, here); 7069ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn break; 7079ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7089ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7099ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7109ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 7129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final IntentResolverOld<F, R> mOldResolver = new IntentResolverOld<F, R>() { 7139ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn @Override protected String packageForFilter(F filter) { 7149ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return IntentResolver.this.packageForFilter(filter); 7159ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn @Override protected boolean allowFilterResult(F filter, List<R> dest) { 7179ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return IntentResolver.this.allowFilterResult(filter, dest); 7189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn @Override protected boolean isFilterStopped(F filter, int userId) { 7209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return IntentResolver.this.isFilterStopped(filter, userId); 7219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn @Override protected R newResult(F filter, int match, int userId) { 7239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn return IntentResolver.this.newResult(filter, match, userId); 7249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn @Override protected void sortResults(List<R> results) { 7269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn IntentResolver.this.sortResults(results); 7279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 7289ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn }; 7299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All filters that have been registered. 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashSet<F> mFilters = new HashSet<F>(); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the MIME types that have been registered, such as "image/jpeg", 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*", or "{@literal *}/*". 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mTypeToFilter = new HashMap<String, F[]>(); 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of all fully qualified MIME types that have been 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered, such as "image" or "*". Wild card MIME types such as 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*" will not be here. 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mBaseTypeToFilter = new HashMap<String, F[]>(); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of the MIME types with a sub-type wildcard that 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * have been registered. For example, a filter with "image/*" will be 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here as "image" but one with "image/jpeg" will not be 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here. This also includes the "*" for the "{@literal *}/*" 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MIME type. 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mWildTypeToFilter = new HashMap<String, F[]>(); 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the URI schemes (such as http) that have been registered. 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mSchemeToFilter = new HashMap<String, F[]>(); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered, but only those that did 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not specify data. 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mActionToFilter = new HashMap<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 and specified a MIME type. 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7719ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn private final HashMap<String, F[]> mTypedActionToFilter = new HashMap<String, F[]>(); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 773