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.Iterator; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 282c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.net.Uri; 292c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brownimport android.util.FastImmutableArraySet; 30f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport android.util.ArrayMap; 319f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkeyimport android.util.ArraySet; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 33d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackbornimport android.util.MutableInt; 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, 216d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn String prefix, ArrayMap<String, F[]> map, String packageName, 217d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn boolean printFilter, boolean collapseDuplicates) { 218d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn final String eprefix = prefix + " "; 219d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn final String fprefix = prefix + " "; 220d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn final ArrayMap<Object, MutableInt> found = new ArrayMap<>(); 221d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedSomething = false; 222cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Printer printer = null; 223d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn for (int mapi=0; mapi<map.size(); mapi++) { 224d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn F[] a = map.valueAt(mapi); 2259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = a.length; 226d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn boolean printedHeader = false; 2279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 228d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (collapseDuplicates) { 229d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn found.clear(); 230d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn for (int i=0; i<N && (filter=a[i]) != null; i++) { 231d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (packageName != null && !isPackageForFilter(packageName, filter)) { 232d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn continue; 233d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 234d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn Object label = filterToLabel(filter); 235d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn int index = found.indexOfKey(label); 236d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (index < 0) { 237d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn found.put(label, new MutableInt(1)); 238d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } else { 239d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn found.valueAt(index).value++; 240d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 241d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 242d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn for (int i=0; i<found.size(); i++) { 243d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (title != null) { 244d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn out.print(titlePrefix); out.println(title); 245d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn title = null; 246d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 247d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (!printedHeader) { 248d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":"); 249d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn printedHeader = true; 250d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 251d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn printedSomething = true; 252d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value); 253d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 254d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } else { 255d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn for (int i=0; i<N && (filter=a[i]) != null; i++) { 256d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (packageName != null && !isPackageForFilter(packageName, filter)) { 257d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn continue; 258d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 259d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (title != null) { 260d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn out.print(titlePrefix); out.println(title); 261d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn title = null; 262d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 263d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (!printedHeader) { 264d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":"); 265d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn printedHeader = true; 266d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 267d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn printedSomething = true; 268d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn dumpFilter(out, fprefix, filter); 269d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (printFilter) { 270d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn if (printer == null) { 271d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn printer = new PrintWriterPrinter(out); 272d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 273d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn filter.dump(printer, fprefix + " "); 274cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 275cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 278d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return printedSomething; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 281cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn public boolean dump(PrintWriter out, String title, String prefix, String packageName, 282d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn boolean printFilter, boolean collapseDuplicates) { 2831d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn String innerPrefix = prefix + " "; 284d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String sepPrefix = "\n" + prefix; 285d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn String curPrefix = title + "\n" + prefix; 286d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix, 287d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mTypeToFilter, packageName, printFilter, collapseDuplicates)) { 288d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 289d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 290d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix, 291d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mBaseTypeToFilter, packageName, printFilter, collapseDuplicates)) { 292d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 293d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 294d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix, 295d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mWildTypeToFilter, packageName, printFilter, collapseDuplicates)) { 296d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 297d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 298d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Schemes:", innerPrefix, 299d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mSchemeToFilter, packageName, printFilter, collapseDuplicates)) { 300d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 301d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 302d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix, 303d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mActionToFilter, packageName, printFilter, collapseDuplicates)) { 304d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 305d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 306d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix, 307d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn mTypedActionToFilter, packageName, printFilter, collapseDuplicates)) { 308d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn curPrefix = sepPrefix; 309d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn } 310d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return curPrefix == sepPrefix; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class IteratorWrapper implements Iterator<F> { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Iterator<F> mI; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private F mCur; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IteratorWrapper(Iterator<F> it) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI = it; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasNext() { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mI.hasNext(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public F next() { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mCur = mI.next()); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove() { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCur != null) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeFilterInternal(mCur); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mI.remove(); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns an iterator allowing filters to be removed. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Iterator<F> filterIterator() { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new IteratorWrapper(mFilters.iterator()); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a read-only set of the filters. 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Set<F> filterSet() { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Collections.unmodifiableSet(mFilters); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 352eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda public List<R> queryIntentFromList(Intent intent, String resolvedType, 3539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn boolean defaultOnly, ArrayList<F[]> listCut, int userId) { 354eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ArrayList<R> resultList = new ArrayList<R>(); 355eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 356eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final boolean debug = localLOGV || 357eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 358eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 3592c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 360eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda final String scheme = intent.getScheme(); 361eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda int N = listCut.size(); 362eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda for (int i = 0; i < N; ++i) { 3632c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 364483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, listCut.get(i), resultList, userId); 365eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 366eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda sortResults(resultList); 367eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda return resultList; 368eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda } 369eae850cefe7e149f396c9e8ca1f34ec02b20a3f0Mihai Preda 370483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, 371483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani int userId) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = intent.getScheme(); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<R> finalList = new ArrayList<R>(); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean debug = localLOGV || 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v( 3806d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn TAG, "Resolving type=" + resolvedType + " scheme=" + scheme 3816d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] firstTypeCut = null; 3849ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] secondTypeCut = null; 3859ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] thirdTypeCut = null; 3869ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] schemeCut = null; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a MIME type, then we want to collect all of 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match that MIME type. 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType != null) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int slashpos = resolvedType.indexOf('/'); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String baseType = resolvedType.substring(0, slashpos); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!baseType.equals("*")) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType.length() != slashpos+2 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || resolvedType.charAt(slashpos+1) != '*') { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Not a wild card, so we can just look for all filters that 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // completely match or wildcards whose base type matches. 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypeToFilter.get(resolvedType); 40038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 40238ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Second type cut: " 40338ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn + Arrays.toString(secondTypeCut)); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can match anything with our base type. 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mBaseTypeToFilter.get(baseType); 40738ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut)); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project secondTypeCut = mWildTypeToFilter.get(baseType); 40938ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Second type cut: " 41038ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn + Arrays.toString(secondTypeCut)); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Any */* types always apply, but we only need to do this 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the intent type was not already */*. 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thirdTypeCut = mWildTypeToFilter.get("*"); 41538ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut)); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction() != null) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The intent specified any type ({@literal *}/*). This 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can be a whole heck of a lot of things, so as a first 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cut let's use the action instead. 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 42138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut)); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent includes a data URI, then we want to collect all of 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the filters that match its scheme (we will further refine matches 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on the authority and path by directly matching each resulting filter). 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scheme != null) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeCut = mSchemeToFilter.get(scheme); 43138ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut)); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the intent does not specify any data -- either a MIME type or 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a URI -- then we will only be looking for matches against empty 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // data. 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resolvedType == null && scheme == null && intent.getAction() != null) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTypeCut = mActionToFilter.get(intent.getAction()); 43938ba6e9ee3e634914153c2181f050a2bb250e484Dianne Hackborn if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut)); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4422c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown FastImmutableArraySet<String> categories = getFastIntentCategories(intent); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstTypeCut != null) { 4442c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 445483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, firstTypeCut, finalList, userId); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (secondTypeCut != null) { 4482c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 449483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, secondTypeCut, finalList, userId); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thirdTypeCut != null) { 4522c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 453483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, thirdTypeCut, finalList, userId); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (schemeCut != null) { 4562c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown buildResolveList(intent, categories, debug, defaultOnly, 457483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani resolvedType, scheme, schemeCut, finalList, userId); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sortResults(finalList); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 4628a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Final result list:"); 4636d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn for (int i=0; i<finalList.size(); i++) { 4646d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.v(TAG, " " + finalList.get(i)); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return finalList; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether the given filter is allowed to go into the result 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list. Mainly intended to prevent adding multiple filters for the 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * same target object. 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean allowFilterResult(F filter, List<R> dest) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn /** 480e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * Returns whether the object associated with the given filter is 481e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * "stopped," that is whether it should not be included in the result 482e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn * if the intent requests to excluded stopped objects. 483e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn */ 484483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected boolean isFilterStopped(F filter, int userId) { 485e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn return false; 486e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 487e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 4886c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn /** 4894efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * Returns whether this filter is owned by this package. This must be 4904efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * implemented to provide correct filtering of Intents that have 4914efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * specified a package name they are to be delivered to. 4926c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn */ 4934efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver protected abstract boolean isPackageForFilter(String packageName, F filter); 4949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 4959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn protected abstract F[] newArray(int size); 4969ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 4976c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 498483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani protected R newResult(F filter, int match, int userId) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (R)filter; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5026c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("unchecked") 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void sortResults(List<R> results) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(results, mResolvePrioritySorter); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5071d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn protected void dumpFilter(PrintWriter out, String prefix, F filter) { 5081d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn out.print(prefix); out.println(filter); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 511d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn protected Object filterToLabel(F filter) { 512d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn return "IntentFilter"; 513d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 514d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn 515d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 516d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn out.print(prefix); out.print(label); out.print(": "); out.println(count); 517d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn } 518d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn 519f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) { 5209ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 5219ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array == null) { 5229ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array = newArray(2); 5239ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, array); 5249ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[0] = filter; 5259ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 5269ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = array.length; 5279ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int i = N; 5289ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (i > 0 && array[i-1] == null) { 5299ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn i--; 5309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5319ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (i < N) { 5329ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[i] = filter; 5339ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else { 5349ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray((N*3)/2); 5359ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, N); 5369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn newa[N] = filter; 5379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 5389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 5419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_mime_types(F filter, String prefix) { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 550502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mTypeToFilter, name, filter); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5649ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mBaseTypeToFilter, baseName, filter); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5669ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(mWildTypeToFilter, baseName, filter); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_mime_types(F filter, String prefix) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Iterator<String> i = filter.typesIterator(); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 581502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root String name = i.next(); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 5838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseName = name; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int slashpos = name.indexOf('/'); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project baseName = name.substring(0, slashpos).intern(); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name + "/*"; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mTypeToFilter, name, filter); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (slashpos > 0) { 5959ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mBaseTypeToFilter, baseName, filter); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5979ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(mWildTypeToFilter, baseName, filter); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int register_intent_filter(F filter, Iterator<String> i, 604f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn ArrayMap<String, F[]> dest, String prefix) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 6138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 6149ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn addFilter(dest, name, filter); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int unregister_intent_filter(F filter, Iterator<String> i, 620f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn ArrayMap<String, F[]> dest, String prefix) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == null) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num = 0; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i.hasNext()) { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = i.next(); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project num++; 6298a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, prefix + name); 6309ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn remove_all_objects(dest, name, filter); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 635f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final void remove_all_objects(ArrayMap<String, F[]> map, String name, 6369ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn Object object) { 6379ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] array = map.get(name); 6389ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array != null) { 6399ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn int LAST = array.length-1; 6409ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn while (LAST >= 0 && array[LAST] == null) { 6419ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 6429ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6439ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (int idx=LAST; idx>=0; idx--) { 6449ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (array[idx] == object) { 6459ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int remain = LAST - idx; 6469ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (remain > 0) { 6479ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, idx+1, array, idx, remain); 6489ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6499ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn array[LAST] = null; 6509ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn LAST--; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn if (LAST < 0) { 6549ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.remove(name); 6559ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } else if (LAST < (array.length/2)) { 6569ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F[] newa = newArray(LAST+2); 6579ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn System.arraycopy(array, 0, newa, 0, LAST+1); 6589ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn map.put(name, newa); 6599ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6632c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) { 6642c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Set<String> categories = intent.getCategories(); 6652c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown if (categories == null) { 6662c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return null; 6672c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 6682c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()])); 6692c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown } 6702c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown 6712c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, 6722c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown boolean debug, boolean defaultOnly, 6739ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn String resolvedType, String scheme, F[] src, List<R> dest, int userId) { 6742c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final String action = intent.getAction(); 6752c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown final Uri data = intent.getData(); 6766c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn final String packageName = intent.getPackage(); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 678e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn final boolean excludingStopped = intent.isExcludingStopped(); 679e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 6806d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn final Printer logPrinter; 6816d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn final PrintWriter logPrintWriter; 6826d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (debug) { 6836d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM); 6846d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter = new FastPrintWriter(logPrinter); 6856d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } else { 6866d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrinter = null; 6876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter = null; 6886d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 6896d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn 6909ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn final int N = src != null ? src.length : 0; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasNonDefaults = false; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 6939ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn F filter; 6949ec6cdde9f8f22356dcc9f811d99ebf813194721Dianne Hackborn for (i=0; i<N && (filter=src[i]) != null; i++) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int match; 6968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, "Matching against filter " + filter); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 698483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani if (excludingStopped && isFilterStopped(filter, userId)) { 699e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn if (debug) { 700e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn Slog.v(TAG, " Filter's target is stopped; skipping"); 701e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 702e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn continue; 703e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn } 704e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn 7056c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn // Is delivery being limited to filters owned by a particular package? 7064efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (packageName != null && !isPackageForFilter(packageName, filter)) { 7076c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn if (debug) { 7086c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn Slog.v(TAG, " Filter is not from package " + packageName + "; skipping"); 7096c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 7106c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn continue; 7116c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 7126c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do we already have this one? 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowFilterResult(filter, dest)) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 7168a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter's target already added"); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7212c376fc46cd01b12e003a7bf83d82f527f6efaf1Jeff Brown match = filter.match(action, resolvedType, scheme, data, categories, TAG); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (match >= 0) { 7238a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (debug) Slog.v(TAG, " Filter matched! match=0x" + 7246d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Integer.toHexString(match) + " hasDefault=" 7256d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn + filter.hasCategory(Intent.CATEGORY_DEFAULT)); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 727483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani final R oneResult = newResult(filter, match, userId); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oneResult != null) { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.add(oneResult); 7306d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (debug) { 7316d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn dumpFilter(logPrintWriter, " ", filter); 7326d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn logPrintWriter.flush(); 7336d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn filter.dump(logPrinter, " "); 7346d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNonDefaults = true; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (debug) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String reason; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (match) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: reason = "unknown reason"; break; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, " Filter did not match: " + reason); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7546d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (hasNonDefaults) { 7556d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn if (dest.size() == 0) { 7566d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT"); 7576d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } else if (dest.size() > 1) { 7586d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT"); 7596d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sorts a List of IntentFilter objects into descending priority order. 7646c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn @SuppressWarnings("rawtypes") 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Comparator mResolvePrioritySorter = new Comparator() { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Object o1, Object o2) { 767502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q1 = ((IntentFilter) o1).getPriority(); 768502e9a47c64d819a7aa45251bcf7cb5dd77a310bKenny Root final int q2 = ((IntentFilter) o2).getPriority(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All filters that have been registered. 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7769f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey private final ArraySet<F> mFilters = new ArraySet<F>(); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the MIME types that have been registered, such as "image/jpeg", 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*", or "{@literal *}/*". 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 782f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>(); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of all fully qualified MIME types that have been 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered, such as "image" or "*". Wild card MIME types such as 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "image/*" will not be here. 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>(); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The base names of all of the MIME types with a sub-type wildcard that 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * have been registered. For example, a filter with "image/*" will be 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here as "image" but one with "image/jpeg" will not be 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included here. This also includes the "*" for the "{@literal *}/*" 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MIME type. 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 798f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>(); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the URI schemes (such as http) that have been registered. 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 803f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered, but only those that did 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not specify data. 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>(); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All of the actions that have been registered and specified a MIME type. 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 814f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 816