IntentResolver.java revision f2ac2761276e4972f6463d6818c9f5798bdc9a4d
14774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall/* 2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Copyright (C) 2006 The Android Open Source Project 3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 44774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * Licensed under the Apache License, Version 2.0 (the "License"); 54774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * you may not use this file except in compliance with the License. 64774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * You may obtain a copy of the License at 7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 84774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * http://www.apache.org/licenses/LICENSE-2.0 9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 104774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * Unless required by applicable law or agreed to in writing, software 114774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * distributed under the License is distributed on an "AS IS" BASIS, 124774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * See the License for the specific language governing permissions and 14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * limitations under the License. 15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennispackage com.android.server; 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.io.PrintWriter; 20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.ArrayList; 21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Arrays; 22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Collections; 23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Comparator; 24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.HashSet; 25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Iterator; 26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.List; 27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Map; 28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.Set; 29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.net.Uri; 317db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopianimport android.util.FastImmutableArraySet; 32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.ArrayMap; 33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.Log; 34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.PrintWriterPrinter; 35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.Slog; 36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.LogPrinter; 37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.Printer; 381c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.Intent; 40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.IntentFilter; 41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport com.android.internal.util.FastPrintWriter; 420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/** 44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@hide} 45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpublic abstract class IntentResolver<F extends IntentFilter, R extends Object> { 47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final private static String TAG = "IntentResolver"; 48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final private static boolean DEBUG = false; 49ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian final private static boolean localLOGV = DEBUG || false; 50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void addFilter(F f) { 52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (localLOGV) { 53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, "Adding filter: " + f); 54518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 55e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian Slog.v(TAG, " Building Lookup Maps:"); 56e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 57518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFilters.add(f); 59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int numS = register_intent_filter(f, f.schemesIterator(), 60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mSchemeToFilter, " Scheme: "); 61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int numT = register_mime_types(f, " Type: "); 62e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (numS == 0 && numT == 0) { 63e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian register_intent_filter(f, f.actionsIterator(), 64e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian mActionToFilter, " Action: "); 65e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 66e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (numT != 0) { 67e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian register_intent_filter(f, f.actionsIterator(), 68e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian mTypedActionToFilter, " TypedAction: "); 69e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 70e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 71e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian 72e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian private boolean filterEquals(IntentFilter f1, IntentFilter f2) { 73e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian int s1 = f1.countActions(); 74e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian int s2 = f2.countActions(); 75e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (s1 != s2) { 76e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 77e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 78e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 79e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasAction(f1.getAction(i))) { 80e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 81e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 82e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 83e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s1 = f1.countCategories(); 84e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s2 = f2.countCategories(); 85e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (s1 != s2) { 862bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian return false; 87e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 88e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 89e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasCategory(f1.getCategory(i))) { 90e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 91e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 92e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 93e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s1 = f1.countDataTypes(); 94e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s2 = f2.countDataTypes(); 95e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (s1 != s2) { 96e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 97e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 98e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 99e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasExactDataType(f1.getDataType(i))) { 100e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 101e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 102e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 103e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s1 = f1.countDataSchemes(); 104e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s2 = f2.countDataSchemes(); 105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (s1 != s2) { 106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return false; 107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (int i=0; i<s1; i++) { 109e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasDataScheme(f1.getDataScheme(i))) { 110e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian s1 = f1.countDataAuthorities(); 114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian s2 = f2.countDataAuthorities(); 115e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (s1 != s2) { 116e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 117e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 118e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 119e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasDataAuthority(f1.getDataAuthority(i))) { 120e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 121e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 122e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 123e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s1 = f1.countDataPaths(); 124e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s2 = f2.countDataPaths(); 125e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (s1 != s2) { 126e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 127e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 128e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 1291c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang if (!f2.hasDataPath(f1.getDataPath(i))) { 1301c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang return false; 1311c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 1321c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 133e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian s1 = f1.countDataSchemeSpecificParts(); 1342bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian s2 = f2.countDataSchemeSpecificParts(); 1352bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian if (s1 != s2) { 1362bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian return false; 137e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 138e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<s1; i++) { 139e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) { 140e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return false; 141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 143e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian return true; 144e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 145e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian 146e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian private ArrayList<F> collectFilters(F[] array, IntentFilter matching) { 147e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian ArrayList<F> res = null; 148e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (array != null) { 149e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (int i=0; i<array.length; i++) { 150e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian F cur = array[i]; 151e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (cur == null) { 152e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian break; 153e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian } 154e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian if (filterEquals(cur, matching)) { 155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (res == null) { 156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian res = new ArrayList<>(); 157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian res.add(cur); 159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res; 163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public ArrayList<F> findFilters(IntentFilter matching) { 166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (matching.countDataSchemes() == 1) { 167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Fast case. 168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching); 169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) { 170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Another fast case. 171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching); 172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0 173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian && matching.countActions() == 1) { 174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Last fast case. 175a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy return collectFilters(mActionToFilter.get(matching.getAction(0)), matching); 176a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy } else { 177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ArrayList<F> res = null; 178e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian for (F cur : mFilters) { 179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (filterEquals(cur, matching)) { 180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (res == null) { 181e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian res = new ArrayList<>(); 182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian res.add(cur); 184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res; 187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void removeFilter(F f) { 191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian removeFilterInternal(f); 192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFilters.remove(f); 193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian void removeFilterInternal(F f) { 196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (localLOGV) { 197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, "Removing filter: " + f); 198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, " Cleaning Lookup Maps:"); 200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int numS = unregister_intent_filter(f, f.schemesIterator(), 203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mSchemeToFilter, " Scheme: "); 204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int numT = unregister_mime_types(f, " Type: "); 205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (numS == 0 && numT == 0) { 206518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian unregister_intent_filter(f, f.actionsIterator(), 207518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mActionToFilter, " Action: "); 208518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (numT != 0) { 210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian unregister_intent_filter(f, f.actionsIterator(), 211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mTypedActionToFilter, " TypedAction: "); 212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 214b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean dumpMap(PrintWriter out, String titlePrefix, String title, 216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String prefix, Map<String, F[]> map, String packageName, 217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean printFilter) { 218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String eprefix = prefix + " "; 219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String fprefix = prefix + " "; 220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean printedSomething = false; 221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Printer printer = null; 222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (Map.Entry<String, F[]> e : map.entrySet()) { 223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] a = e.getValue(); 224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int N = a.length; 225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean printedHeader = false; 226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F filter; 227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (int i=0; i<N && (filter=a[i]) != null; i++) { 228518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (packageName != null && !isPackageForFilter(packageName, filter)) { 229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian continue; 230b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 231518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (title != null) { 232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian out.print(titlePrefix); out.println(title); 233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian title = null; 2344774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall } 235518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!printedHeader) { 236518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian out.print(eprefix); out.print(e.getKey()); out.println(":"); 237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian printedHeader = true; 238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian printedSomething = true; 240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dumpFilter(out, fprefix, filter); 241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (printFilter) { 242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (printer == null) { 243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian printer = new PrintWriterPrinter(out); 244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian filter.dump(printer, fprefix + " "); 246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 248b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return printedSomething; 250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 2517773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 2527773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian public boolean dump(PrintWriter out, String title, String prefix, String packageName, 253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean printFilter) { 254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String innerPrefix = prefix + " "; 2557773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian String sepPrefix = "\n" + prefix; 2567773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian String curPrefix = title + "\n" + prefix; 2577773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix, 2587773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian mTypeToFilter, packageName, printFilter)) { 2597773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian curPrefix = sepPrefix; 2607773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian } 2617773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix, 262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mBaseTypeToFilter, packageName, printFilter)) { 2637773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian curPrefix = sepPrefix; 2647773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian } 265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix, 266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mWildTypeToFilter, packageName, printFilter)) { 267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian curPrefix = sepPrefix; 268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (dumpMap(out, curPrefix, "Schemes:", innerPrefix, 270518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mSchemeToFilter, packageName, printFilter)) { 271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian curPrefix = sepPrefix; 272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 273b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix, 274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mActionToFilter, packageName, printFilter)) { 275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian curPrefix = sepPrefix; 276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix, 278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mTypedActionToFilter, packageName, printFilter)) { 279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian curPrefix = sepPrefix; 280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return curPrefix == sepPrefix; 282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 283ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 284ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian private class IteratorWrapper implements Iterator<F> { 2851cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy private final Iterator<F> mI; 2861cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy private F mCur; 2871cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 2881cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy IteratorWrapper(Iterator<F> it) { 2891cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy mI = it; 2901cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 2911cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 2921cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public boolean hasNext() { 2931cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy return mI.hasNext(); 294be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy } 2951cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 2961cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public F next() { 2971cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy return (mCur = mI.next()); 2981cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 299be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy 3001cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public void remove() { 3011cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy if (mCur != null) { 3021cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy removeFilterInternal(mCur); 3031cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3041cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy mI.remove(); 3051cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3061cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 3071cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3081cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 3091cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy /** 3101cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy * Returns an iterator allowing filters to be removed. 3111cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy */ 3121cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public Iterator<F> filterIterator() { 3131cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy return new IteratorWrapper(mFilters.iterator()); 3141cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3154774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall 3161cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy /** 3171cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy * Returns a read-only set of the filters. 3181cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy */ 3191cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public Set<F> filterSet() { 3201cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy return Collections.unmodifiableSet(mFilters); 3211cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3221cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 3231cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy public List<R> queryIntentFromList(Intent intent, String resolvedType, 3241cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy boolean defaultOnly, ArrayList<F[]> listCut, int userId) { 3251cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy ArrayList<R> resultList = new ArrayList<R>(); 3261cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 3271cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy final boolean debug = localLOGV || 3281cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3291cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy 3301cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 3311cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy final String scheme = intent.getScheme(); 3321cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy int N = listCut.size(); 3331cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy for (int i = 0; i < N; ++i) { 3341cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy buildResolveList(intent, categories, debug, defaultOnly, 3351cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy resolvedType, scheme, listCut.get(i), resultList, userId); 3361cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy } 3371cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy sortResults(resultList); 3387773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian return resultList; 3397773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian } 340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 341518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, 342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int userId) { 343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String scheme = intent.getScheme(); 344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 345518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ArrayList<R> finalList = new ArrayList<R>(); 346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final boolean debug = localLOGV || 348518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 349b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 350b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (debug) Slog.v( 351b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall TAG, "Resolving type=" + resolvedType + " scheme=" + scheme 3524774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent); 353518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 3547773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian F[] firstTypeCut = null; 355518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] secondTypeCut = null; 356518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] thirdTypeCut = null; 357518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] schemeCut = null; 358518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 359518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // If the intent includes a MIME type, then we want to collect all of 360518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // the filters that match that MIME type. 361518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (resolvedType != null) { 362518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int slashpos = resolvedType.indexOf('/'); 363518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (slashpos > 0) { 364518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final String baseType = resolvedType.substring(0, slashpos); 365518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!baseType.equals("*")) { 366518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (resolvedType.length() != slashpos+2 367b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall || resolvedType.charAt(slashpos+1) != '*') { 368b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall // Not a wild card, so we can just look for all filters that 369b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall // completely match or wildcards whose base type matches. 370ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian firstTypeCut = mTypeToFilter.get(resolvedType); 371518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 372518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian secondTypeCut = mWildTypeToFilter.get(baseType); 37381a63350527cafce6929309533c58586878f10b5Mathias Agopian if (debug) Slog.v(TAG, "Second type cut: " 374e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block + Arrays.toString(secondTypeCut)); 37581a63350527cafce6929309533c58586878f10b5Mathias Agopian } else { 37681a63350527cafce6929309533c58586878f10b5Mathias Agopian // We can match anything with our base type. 37781a63350527cafce6929309533c58586878f10b5Mathias Agopian firstTypeCut = mBaseTypeToFilter.get(baseType); 37881a63350527cafce6929309533c58586878f10b5Mathias Agopian if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 379518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian secondTypeCut = mWildTypeToFilter.get(baseType); 380518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) Slog.v(TAG, "Second type cut: " 3817773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian + Arrays.toString(secondTypeCut)); 382518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 383bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis // Any */* types always apply, but we only need to do this 384bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis // if the intent type was not already */*. 385e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block thirdTypeCut = mWildTypeToFilter.get("*"); 386bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut)); 38781a63350527cafce6929309533c58586878f10b5Mathias Agopian } else if (intent.getAction() != null) { 388bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis // The intent specified any type ({@literal *}/*). This 389bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis // can be a whole heck of a lot of things, so as a first 390518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // cut let's use the action instead. 391518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 392518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut)); 39359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis } 39459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis } 39559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis } 39659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 39759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis // If the intent includes a data URI, then we want to collect all of 398518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // the filters that match its scheme (we will further refine matches 3997773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian // on the authority and path by directly matching each resulting filter). 400518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (scheme != null) { 401b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall schemeCut = mSchemeToFilter.get(scheme); 402b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut)); 403518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 404518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 40581a63350527cafce6929309533c58586878f10b5Mathias Agopian // If the intent does not specify any data -- either a MIME type or 40681a63350527cafce6929309533c58586878f10b5Mathias Agopian // a URI -- then we will only be looking for matches against empty 40781a63350527cafce6929309533c58586878f10b5Mathias Agopian // data. 40881a63350527cafce6929309533c58586878f10b5Mathias Agopian if (resolvedType == null && scheme == null && intent.getAction() != null) { 409518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian firstTypeCut = mActionToFilter.get(intent.getAction()); 410518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut)); 411518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 412518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 413518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 414518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (firstTypeCut != null) { 415518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian buildResolveList(intent, categories, debug, defaultOnly, 416518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian resolvedType, scheme, firstTypeCut, finalList, userId); 417518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 418518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (secondTypeCut != null) { 419b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall buildResolveList(intent, categories, debug, defaultOnly, 420b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall resolvedType, scheme, secondTypeCut, finalList, userId); 421b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 422518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (thirdTypeCut != null) { 4237773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian buildResolveList(intent, categories, debug, defaultOnly, 424518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian resolvedType, scheme, thirdTypeCut, finalList, userId); 425b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 426b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (schemeCut != null) { 427518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian buildResolveList(intent, categories, debug, defaultOnly, 428518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian resolvedType, scheme, schemeCut, finalList, userId); 429518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 430518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian sortResults(finalList); 431518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 432518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 433518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, "Final result list:"); 434518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (int i=0; i<finalList.size(); i++) { 435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, " " + finalList.get(i)); 436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 437518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 438b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall return finalList; 439b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 440b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 441518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 4427773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian * Control whether the given filter is allowed to go into the result 443518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * list. Mainly intended to prevent adding multiple filters for the 444b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * same target object. 445b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall */ 446518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected boolean allowFilterResult(F filter, List<R> dest) { 447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return true; 448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 449518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 4514774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall * Returns whether the object associated with the given filter is 452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * "stopped," that is whether it should not be included in the result 453518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * if the intent requests to excluded stopped objects. 454518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 455518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected boolean isFilterStopped(F filter, int userId) { 456b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall return false; 457518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 458518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 459b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 4605b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian * Returns whether this filter is owned by this package. This must be 4615b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian * implemented to provide correct filtering of Intents that have 462518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * specified a package name they are to be delivered to. 463518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 464ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian protected abstract boolean isPackageForFilter(String packageName, F filter); 465518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 466518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected abstract F[] newArray(int size); 467518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 468518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @SuppressWarnings("unchecked") 469518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected R newResult(F filter, int match, int userId) { 470518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return (R)filter; 471518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 472518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 473518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @SuppressWarnings("unchecked") 474518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void sortResults(List<R> results) { 475518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Collections.sort(results, mResolvePrioritySorter); 476b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 477518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 478518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void dumpFilter(PrintWriter out, String prefix, F filter) { 479b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall out.print(prefix); out.println(filter); 4805b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } 4815b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian 482518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) { 483518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] array = map.get(name); 4847773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (array == null) { 4857773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian array = newArray(2); 486518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian map.put(name, array); 487518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian array[0] = filter; 488e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } else { 4891c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis final int N = array.length; 490e8696a40e09b24b634214684d18526187b316a2fJamie Gennis int i = N; 491e8696a40e09b24b634214684d18526187b316a2fJamie Gennis while (i > 0 && array[i-1] == null) { 492b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall i--; 493e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 494e8696a40e09b24b634214684d18526187b316a2fJamie Gennis if (i < N) { 495e8696a40e09b24b634214684d18526187b316a2fJamie Gennis array[i] = filter; 496e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } else { 497b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall F[] newa = newArray((N*3)/2); 498e8696a40e09b24b634214684d18526187b316a2fJamie Gennis System.arraycopy(array, 0, newa, 0, N); 499e8696a40e09b24b634214684d18526187b316a2fJamie Gennis newa[N] = filter; 500e8696a40e09b24b634214684d18526187b316a2fJamie Gennis map.put(name, newa); 501e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 502e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 503e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 504e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 505e8696a40e09b24b634214684d18526187b316a2fJamie Gennis private final int register_mime_types(F filter, String prefix) { 506e8696a40e09b24b634214684d18526187b316a2fJamie Gennis final Iterator<String> i = filter.typesIterator(); 507e8696a40e09b24b634214684d18526187b316a2fJamie Gennis if (i == null) { 508e8696a40e09b24b634214684d18526187b316a2fJamie Gennis return 0; 509518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 510518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 511518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int num = 0; 512518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian while (i.hasNext()) { 513518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String name = i.next(); 514518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian num++; 515518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (localLOGV) Slog.v(TAG, prefix + name); 516518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String baseName = name; 517518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int slashpos = name.indexOf('/'); 518b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (slashpos > 0) { 519b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall baseName = name.substring(0, slashpos).intern(); 520b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 521518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian name = name + "/*"; 522518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 523518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 524518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian addFilter(mTypeToFilter, name, filter); 525518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 5267773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (slashpos > 0) { 527518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian addFilter(mBaseTypeToFilter, baseName, filter); 528518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 529518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian addFilter(mWildTypeToFilter, baseName, filter); 530518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 531518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 532518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 533518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return num; 534518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 535518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 5367773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian private final int unregister_mime_types(F filter, String prefix) { 5374774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall final Iterator<String> i = filter.typesIterator(); 5387773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (i == null) { 539518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return 0; 540518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 541518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 542518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int num = 0; 543b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall while (i.hasNext()) { 544b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall String name = i.next(); 5450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy num++; 546a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (localLOGV) Slog.v(TAG, prefix + name); 5470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy String baseName = name; 5480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy final int slashpos = name.indexOf('/'); 549518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (slashpos > 0) { 550500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian baseName = name.substring(0, slashpos).intern(); 551500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian } else { 552500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian name = name + "/*"; 553500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian } 554500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian 555500407a2c07ced40c36e7356574a47bcec9c2fd9Mathias Agopian remove_all_objects(mTypeToFilter, name, filter); 556518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 557518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (slashpos > 0) { 558518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian remove_all_objects(mBaseTypeToFilter, baseName, filter); 559518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 560518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian remove_all_objects(mWildTypeToFilter, baseName, filter); 561518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 562518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 563518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return num; 564518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 565b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 5665b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian private final int register_intent_filter(F filter, Iterator<String> i, 5675b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian ArrayMap<String, F[]> dest, String prefix) { 568518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (i == null) { 569b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall return 0; 5705b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } 5715b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian 5724774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall int num = 0; 573518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian while (i.hasNext()) { 574ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian String name = i.next(); 575518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian num++; 576518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (localLOGV) Slog.v(TAG, prefix + name); 577518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian addFilter(dest, name, filter); 578518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 579518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return num; 580518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 581518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 582518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final int unregister_intent_filter(F filter, Iterator<String> i, 583518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ArrayMap<String, F[]> dest, String prefix) { 584518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (i == null) { 585518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return 0; 586b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 587518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 588518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int num = 0; 5895b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian while (i.hasNext()) { 5905b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian String name = i.next(); 5915b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian num++; 592518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (localLOGV) Slog.v(TAG, prefix + name); 593518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian remove_all_objects(dest, name, filter); 594518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 595518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return num; 596518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 597518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 598b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall private final void remove_all_objects(ArrayMap<String, F[]> map, String name, 599b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall Object object) { 600b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall F[] array = map.get(name); 601518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (array != null) { 602518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int LAST = array.length-1; 6035b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian while (LAST >= 0 && array[LAST] == null) { 604518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian LAST--; 605518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 606518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (int idx=LAST; idx>=0; idx--) { 607518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (array[idx] == object) { 608518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int remain = LAST - idx; 609518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (remain > 0) { 610518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian System.arraycopy(array, idx+1, array, idx, remain); 611518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 612518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian array[LAST] = null; 613518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian LAST--; 614518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 615518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 616518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (LAST < 0) { 617518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian map.remove(name); 618518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (LAST < (array.length/2)) { 619518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F[] newa = newArray(LAST+2); 6204774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall System.arraycopy(array, 0, newa, 0, LAST+1); 621518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian map.put(name, newa); 622518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 623518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 624518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 625518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 626518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) { 627518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final Set<String> categories = intent.getCategories(); 628518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (categories == null) { 629518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return null; 630518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 631518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()])); 632518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 633518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 634518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, 635518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean debug, boolean defaultOnly, 636518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String resolvedType, String scheme, F[] src, List<R> dest, int userId) { 637518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final String action = intent.getAction(); 638518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final Uri data = intent.getData(); 639518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final String packageName = intent.getPackage(); 640518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 641518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final boolean excludingStopped = intent.isExcludingStopped(); 642518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 643518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final Printer logPrinter; 644518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final PrintWriter logPrintWriter; 645518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 646518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM); 647518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian logPrintWriter = new FastPrintWriter(logPrinter); 648518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 649518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian logPrinter = null; 650b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall logPrintWriter = null; 651fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian } 652fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian 653518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int N = src != null ? src.length : 0; 654518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean hasNonDefaults = false; 655fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian int i; 656518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian F filter; 657518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (i=0; i<N && (filter=src[i]) != null; i++) { 6580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy int match; 659a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (debug) Slog.v(TAG, "Matching against filter " + filter); 66093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 6610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy if (excludingStopped && isFilterStopped(filter, userId)) { 662518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 663518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, " Filter's target is stopped; skipping"); 664518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 665518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian continue; 666518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 667518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 668518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Is delivery being limited to filters owned by a particular package? 6695fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian if (packageName != null && !isPackageForFilter(packageName, filter)) { 670e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block if (debug) { 6715fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian Slog.v(TAG, " Filter is not from package " + packageName + "; skipping"); 672518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 673518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian continue; 674518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 675518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 676518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Do we already have this one? 677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!allowFilterResult(filter, dest)) { 678518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 679518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, " Filter's target already added"); 680518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 681518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian continue; 682b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 683518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 684518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian match = filter.match(action, resolvedType, scheme, data, categories, TAG); 685b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (match >= 0) { 686518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) Slog.v(TAG, " Filter matched! match=0x" + 687518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Integer.toHexString(match) + " hasDefault=" 688518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian + filter.hasCategory(Intent.CATEGORY_DEFAULT)); 6897773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 6907773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian final R oneResult = newResult(filter, match, userId); 691518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (oneResult != null) { 692518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.add(oneResult); 693518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 694518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dumpFilter(logPrintWriter, " ", filter); 695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian logPrintWriter.flush(); 696518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian filter.dump(logPrinter, " "); 697518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 698518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 699518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 700518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian hasNonDefaults = true; 701518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 702518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 703518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (debug) { 704518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String reason; 705518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switch (match) { 706518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 707518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 708518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 709518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 710518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian default: reason = "unknown reason"; break; 711518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 712518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.v(TAG, " Filter did not match: " + reason); 713518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 714518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 715518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 716518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 717518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (hasNonDefaults) { 7184774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall if (dest.size() == 0) { 719518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT"); 720518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (dest.size() > 1) { 721518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT"); 722518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 723518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 724518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 725518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 726518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Sorts a List of IntentFilter objects into descending priority order. 727518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @SuppressWarnings("rawtypes") 728518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final Comparator mResolvePrioritySorter = new Comparator() { 729518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public int compare(Object o1, Object o2) { 730518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int q1 = ((IntentFilter) o1).getPriority(); 731518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final int q2 = ((IntentFilter) o2).getPriority(); 732518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 733518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 734518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }; 735518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 736518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 737518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * All filters that have been registered. 738518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 739518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final HashSet<F> mFilters = new HashSet<F>(); 740518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 741518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 742518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * All of the MIME types that have been registered, such as "image/jpeg", 743518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * "image/*", or "{@literal *}/*". 744518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 745ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>(); 746ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 747ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 748ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * The base names of all of all fully qualified MIME types that have been 749ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * registered, such as "image" or "*". Wild card MIME types such as 750518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * "image/*" will not be here. 751518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 752518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>(); 753518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 754518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 755518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * The base names of all of the MIME types with a sub-type wildcard that 756ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * have been registered. For example, a filter with "image/*" will be 757ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * included here as "image" but one with "image/jpeg" will not be 758ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * included here. This also includes the "*" for the "{@literal *}/*" 759ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * MIME type. 760ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 761518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>(); 762518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 763518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 764518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * All of the URI schemes (such as http) that have been registered. 765ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 766ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>(); 767ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 768ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 769518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * All of the actions that have been registered, but only those that did 770ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * not specify data. 771ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 772ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>(); 773ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 774518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 775518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * All of the actions that have been registered and specified a MIME type. 776518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 777518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>(); 778518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 779518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian