IntentResolver.java revision f2ac2761276e4972f6463d6818c9f5798bdc9a4d
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackbornimport java.io.PrintWriter; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 2138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackbornimport java.util.Arrays; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashSet; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.net.Uri; 312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.util.FastImmutableArraySet; 32f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport android.util.ArrayMap; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 34cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackbornimport android.util.PrintWriterPrinter; 358a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 416d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackbornimport com.android.internal.util.FastPrintWriter; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 466c418d585e0a91054b168fde3130188afd006c98Dianne Hackbornpublic abstract class IntentResolver<F extends IntentFilter, R extends Object> { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static String TAG = "IntentResolver"; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private static boolean DEBUG = false; 4943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato final private static boolean localLOGV = DEBUG || false; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addFilter(F f) { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 538a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Adding filter: " + f); 548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 558a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Building Lookup Maps:"); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilters.add(f); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numS = register_intent_filter(f, f.schemesIterator(), 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSchemeToFilter, " Scheme: "); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numT = register_mime_types(f, " Type: "); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numS == 0 && numT == 0) { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register_intent_filter(f, f.actionsIterator(), 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActionToFilter, " Action: "); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numT != 0) { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project register_intent_filter(f, f.actionsIterator(), 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypedActionToFilter, " TypedAction: "); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn private boolean filterEquals(IntentFilter f1, IntentFilter f2) { 73f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn int s1 = f1.countActions(); 74f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn int s2 = f2.countActions(); 75f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 76f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 77f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 78f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 79f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasAction(f1.getAction(i))) { 80f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 81f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 82f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 83f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countCategories(); 84f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countCategories(); 85f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 86f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 87f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 88f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 89f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasCategory(f1.getCategory(i))) { 90f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 91f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 92f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 93f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countDataTypes(); 94f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countDataTypes(); 95f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 96f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 97f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 98f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 99f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasExactDataType(f1.getDataType(i))) { 100f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 101f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 102f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 103f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countDataSchemes(); 104f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countDataSchemes(); 105f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 106f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 107f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 108f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 109f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasDataScheme(f1.getDataScheme(i))) { 110f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 111f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 112f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 113f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countDataAuthorities(); 114f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countDataAuthorities(); 115f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 116f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 117f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 118f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 119f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasDataAuthority(f1.getDataAuthority(i))) { 120f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 121f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 122f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 123f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countDataPaths(); 124f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countDataPaths(); 125f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 126f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 127f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 128f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 129f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasDataPath(f1.getDataPath(i))) { 130f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 131f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 132f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 133f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s1 = f1.countDataSchemeSpecificParts(); 134f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn s2 = f2.countDataSchemeSpecificParts(); 135f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (s1 != s2) { 136f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 137f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 138f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<s1; i++) { 139f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) { 140f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return false; 141f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 142f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 143f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return true; 144f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 145f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn 146f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn private ArrayList<F> collectFilters(F[] array, IntentFilter matching) { 147f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn ArrayList<F> res = null; 148f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (array != null) { 149f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (int i=0; i<array.length; i++) { 150f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn F cur = array[i]; 151f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (cur == null) { 152f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn break; 153f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 154f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (filterEquals(cur, matching)) { 155f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (res == null) { 156f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn res = new ArrayList<>(); 157f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 158f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn res.add(cur); 159f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 160f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 161f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 162f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return res; 163f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 164f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn 165f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn public ArrayList<F> findFilters(IntentFilter matching) { 166f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (matching.countDataSchemes() == 1) { 167f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn // Fast case. 168f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching); 169f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) { 170f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn // Another fast case. 171f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching); 172f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0 173f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn && matching.countActions() == 1) { 174f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn // Last fast case. 175f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return collectFilters(mActionToFilter.get(matching.getAction(0)), matching); 176f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } else { 177f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn ArrayList<F> res = null; 178f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn for (F cur : mFilters) { 179f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (filterEquals(cur, matching)) { 180f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn if (res == null) { 181f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn res = new ArrayList<>(); 182f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 183f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn res.add(cur); 184f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 185f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 186f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn return res; 187f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 188f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn } 189f2ac2761276e4972f6463d6818c9f5798bdc9a4dDianne Hackborn 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeFilter(F f) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(f); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilters.remove(f); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeFilterInternal(F f) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 1978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Removing filter: " + f); 1988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 1998a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Cleaning Lookup Maps:"); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numS = unregister_intent_filter(f, f.schemesIterator(), 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSchemeToFilter, " Scheme: "); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numT = unregister_mime_types(f, " Type: "); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numS == 0 && numT == 0) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActionToFilter, " Action: "); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numT != 0) { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregister_intent_filter(f, f.actionsIterator(), 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTypedActionToFilter, " TypedAction: "); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 215d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean dumpMap(PrintWriter out, String titlePrefix, String title, 2169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn String prefix, Map<String, F[]> map, String packageName, 217cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String eprefix = prefix + " "; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String fprefix = prefix + " "; 220d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedSomething = false; 221cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Printer printer = null; 2229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (Map.Entry<String, F[]> e : map.entrySet()) { 2239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] a = e.getValue(); 2249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = a.length; 225d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedHeader = false; 2269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 2279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int i=0; i<N && (filter=a[i]) != null; i++) { 2284efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (packageName != null && !isPackageForFilter(packageName, filter)) { 229d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn continue; 230d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 231d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (title != null) { 232d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(titlePrefix); out.println(title); 233d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn title = null; 234d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 235d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (!printedHeader) { 236d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn out.print(eprefix); out.print(e.getKey()); out.println(":"); 237d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedHeader = true; 238d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 239d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn printedSomething = true; 240d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn dumpFilter(out, fprefix, filter); 241cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printFilter) { 242cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (printer == null) { 243cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn printer = new PrintWriterPrinter(out); 244cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 245cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn filter.dump(printer, fprefix + " "); 246cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 249d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return printedSomething; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 252cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn public boolean dump(PrintWriter out, String title, String prefix, String packageName, 253cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn boolean printFilter) { 2541d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn String innerPrefix = prefix + " "; 255d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String sepPrefix = "\n" + prefix; 256d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String curPrefix = title + "\n" + prefix; 257d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix, 258cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypeToFilter, packageName, printFilter)) { 259d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 260d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 261d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix, 262cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mBaseTypeToFilter, packageName, printFilter)) { 263d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 264d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 265d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix, 266cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mWildTypeToFilter, packageName, printFilter)) { 267d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 268d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 269d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Schemes:", innerPrefix, 270cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mSchemeToFilter, packageName, printFilter)) { 271d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 272d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 273d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix, 274cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mActionToFilter, packageName, printFilter)) { 275d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 276d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 277d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix, 278cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn mTypedActionToFilter, packageName, printFilter)) { 279d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 280d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 281d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return curPrefix == sepPrefix; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class IteratorWrapper implements Iterator<F> { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Iterator<F> mI; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private F mCur; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IteratorWrapper(Iterator<F> it) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI = it; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasNext() { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mI.hasNext(); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public F next() { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mCur = mI.next()); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove() { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCur != null) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(mCur); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI.remove(); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns an iterator allowing filters to be removed. 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Iterator<F> filterIterator() { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new IteratorWrapper(mFilters.iterator()); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a read-only set of the filters. 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Set<F> filterSet() { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Collections.unmodifiableSet(mFilters); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 323eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda public List<R> queryIntentFromList(Intent intent, String resolvedType, 3249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn boolean defaultOnly, ArrayList<F[]> listCut, int userId) { 325eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ArrayList<R> resultList = new ArrayList<R>(); 326eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 327eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final boolean debug = localLOGV || 328eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 329eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 3302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 331eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final String scheme = intent.getScheme(); 332eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda int N = listCut.size(); 333eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda for (int i = 0; i < N; ++i) { 3342c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 335483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, listCut.get(i), resultList, userId); 336eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 337eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda sortResults(resultList); 338eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda return resultList; 339eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 340eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 341483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, 342483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani int userId) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = intent.getScheme(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<R> finalList = new ArrayList<R>(); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean debug = localLOGV || 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v( 3516d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn TAG, "Resolving type=" + resolvedType + " scheme=" + scheme 3526d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] firstTypeCut = null; 3559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] secondTypeCut = null; 3569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] thirdTypeCut = null; 3579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] schemeCut = null; 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a MIME type, then we want to collect all of 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match that MIME type. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType != null) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int slashpos = resolvedType.indexOf('/'); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String baseType = resolvedType.substring(0, slashpos); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!baseType.equals("*")) { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType.length() != slashpos+2 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || resolvedType.charAt(slashpos+1) != '*') { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not a wild card, so we can just look for all filters that 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // completely match or wildcards whose base type matches. 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypeToFilter.get(resolvedType); 37138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 37338ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Second type cut: " 37438ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn + Arrays.toString(secondTypeCut)); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can match anything with our base type. 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mBaseTypeToFilter.get(baseType); 37838ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 38038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Second type cut: " 38138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn + Arrays.toString(secondTypeCut)); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Any */* types always apply, but we only need to do this 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the intent type was not already */*. 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thirdTypeCut = mWildTypeToFilter.get("*"); 38638ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut)); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction() != null) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The intent specified any type ({@literal *}/*). This 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can be a whole heck of a lot of things, so as a first 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cut let's use the action instead. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 39238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut)); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a data URI, then we want to collect all of 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match its scheme (we will further refine matches 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on the authority and path by directly matching each resulting filter). 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scheme != null) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeCut = mSchemeToFilter.get(scheme); 40238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut)); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent does not specify any data -- either a MIME type or 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a URI -- then we will only be looking for matches against empty 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // data. 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType == null && scheme == null && intent.getAction() != null) { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mActionToFilter.get(intent.getAction()); 41038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut)); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4132c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstTypeCut != null) { 4152c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 416483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, firstTypeCut, finalList, userId); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (secondTypeCut != null) { 4192c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 420483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, secondTypeCut, finalList, userId); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thirdTypeCut != null) { 4232c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 424483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, thirdTypeCut, finalList, userId); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (schemeCut != null) { 4272c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 428483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, schemeCut, finalList, userId); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sortResults(finalList); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 4338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Final result list:"); 4346d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn for (int i=0; i<finalList.size(); i++) { 4356d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.v(TAG, " " + finalList.get(i)); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return finalList; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether the given filter is allowed to go into the result 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list. Mainly intended to prevent adding multiple filters for the 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * same target object. 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean allowFilterResult(F filter, List<R> dest) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 450e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn /** 451e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * Returns whether the object associated with the given filter is 452e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * "stopped," that is whether it should not be included in the result 453e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * if the intent requests to excluded stopped objects. 454e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn */ 455483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected boolean isFilterStopped(F filter, int userId) { 456e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn return false; 457e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 458e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 4596c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn /** 4604efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * Returns whether this filter is owned by this package. This must be 4614efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * implemented to provide correct filtering of Intents that have 4624efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * specified a package name they are to be delivered to. 4636c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn */ 4644efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver protected abstract boolean isPackageForFilter(String packageName, F filter); 4659ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 4669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn protected abstract F[] newArray(int size); 4679ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 4686c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 469483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected R newResult(F filter, int match, int userId) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (R)filter; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4736c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void sortResults(List<R> results) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(results, mResolvePrioritySorter); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn protected void dumpFilter(PrintWriter out, String prefix, F filter) { 4791d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn out.print(prefix); out.println(filter); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 482f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) { 4839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 4849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array == null) { 4859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array = newArray(2); 4869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, array); 4879ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[0] = filter; 4889ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 4899ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = array.length; 4909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int i = N; 4919ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (i > 0 && array[i-1] == null) { 4929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn i--; 4939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 4949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (i < N) { 4959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[i] = filter; 4969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 4979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray((N*3)/2); 4989ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, N); 4999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn newa[N] = filter; 5009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 5019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_mime_types(F filter, String prefix) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 513502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5158a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mTypeToFilter, name, filter); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mBaseTypeToFilter, baseName, filter); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mWildTypeToFilter, baseName, filter); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_mime_types(F filter, String prefix) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 544502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mTypeToFilter, name, filter); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mBaseTypeToFilter, baseName, filter); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5609ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mWildTypeToFilter, baseName, filter); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_intent_filter(F filter, Iterator<String> i, 567f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn ArrayMap<String, F[]> dest, String prefix) { 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5779ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(dest, name, filter); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_intent_filter(F filter, Iterator<String> i, 583f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn ArrayMap<String, F[]> dest, String prefix) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(dest, name, filter); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 598f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final void remove_all_objects(ArrayMap<String, F[]> map, String name, 5999ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Object object) { 6009ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 6019ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array != null) { 6029ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int LAST = array.length-1; 6039ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (LAST >= 0 && array[LAST] == null) { 6049ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 6059ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6069ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int idx=LAST; idx>=0; idx--) { 6079ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array[idx] == object) { 6089ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int remain = LAST - idx; 6099ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (remain > 0) { 6109ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, idx+1, array, idx, remain); 6119ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6129ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[LAST] = null; 6139ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (LAST < 0) { 6179ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.remove(name); 6189ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else if (LAST < (array.length/2)) { 6199ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray(LAST+2); 6209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, LAST+1); 6219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 6229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6262c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) { 6272c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Set<String> categories = intent.getCategories(); 6282c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown if (categories == null) { 6292c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return null; 6302c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 6312c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()])); 6322c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 6332c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown 6342c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, 6352c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown boolean debug, boolean defaultOnly, 6369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn String resolvedType, String scheme, F[] src, List<R> dest, int userId) { 6372c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final String action = intent.getAction(); 6382c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Uri data = intent.getData(); 6396c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn final String packageName = intent.getPackage(); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 641e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn final boolean excludingStopped = intent.isExcludingStopped(); 642e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 6436d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn final Printer logPrinter; 6446d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn final PrintWriter logPrintWriter; 6456d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (debug) { 6466d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM); 6476d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter = new FastPrintWriter(logPrinter); 6486d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } else { 6496d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrinter = null; 6506d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter = null; 6516d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 6526d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn 6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = src != null ? src.length : 0; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasNonDefaults = false; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (i=0; i<N && (filter=src[i]) != null; i++) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int match; 6598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Matching against filter " + filter); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 661483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani if (excludingStopped && isFilterStopped(filter, userId)) { 662e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn if (debug) { 663e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn Slog.v(TAG, " Filter's target is stopped; skipping"); 664e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 665e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn continue; 666e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 667e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 6686c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn // Is delivery being limited to filters owned by a particular package? 6694efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (packageName != null && !isPackageForFilter(packageName, filter)) { 6706c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn if (debug) { 6716c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn Slog.v(TAG, " Filter is not from package " + packageName + "; skipping"); 6726c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 6736c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn continue; 6746c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 6756c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do we already have this one? 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowFilterResult(filter, dest)) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 6798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter's target already added"); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6842c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown match = filter.match(action, resolvedType, scheme, data, categories, TAG); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (match >= 0) { 6868a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, " Filter matched! match=0x" + 6876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Integer.toHexString(match) + " hasDefault=" 6886d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn + filter.hasCategory(Intent.CATEGORY_DEFAULT)); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 690483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani final R oneResult = newResult(filter, match, userId); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oneResult != null) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.add(oneResult); 6936d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (debug) { 6946d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn dumpFilter(logPrintWriter, " ", filter); 6956d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter.flush(); 6966d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn filter.dump(logPrinter, " "); 6976d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNonDefaults = true; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String reason; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (match) { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: reason = "unknown reason"; break; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter did not match: " + reason); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7176d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (hasNonDefaults) { 7186d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (dest.size() == 0) { 7196d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT"); 7206d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } else if (dest.size() > 1) { 7216d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT"); 7226d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sorts a List of IntentFilter objects into descending priority order. 7276c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("rawtypes") 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Comparator mResolvePrioritySorter = new Comparator() { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Object o1, Object o2) { 730502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q1 = ((IntentFilter) o1).getPriority(); 731502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q2 = ((IntentFilter) o2).getPriority(); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All filters that have been registered. 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashSet<F> mFilters = new HashSet<F>(); 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the MIME types that have been registered, such as "image/jpeg", 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*", or "{@literal *}/*". 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 745f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>(); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of all fully qualified MIME types that have been 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered, such as "image" or "*". Wild card MIME types such as 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*" will not be here. 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 752f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>(); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of the MIME types with a sub-type wildcard that 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * have been registered. For example, a filter with "image/*" will be 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here as "image" but one with "image/jpeg" will not be 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here. This also includes the "*" for the "{@literal *}/*" 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MIME type. 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 761f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>(); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the URI schemes (such as http) that have been registered. 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 766f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>(); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered, but only those that did 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not specify data. 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 772f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>(); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered and specified a MIME type. 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 777f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>(); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 779