IntentResolver.java revision 1d442e0d990b581357f33f5463c7c5cb49b551e8
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (C) 2006 The Android Open Source Project 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License"); 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * you may not use this file except in compliance with the License. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * You may obtain a copy of the License at 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * http://www.apache.org/licenses/LICENSE-2.0 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS, 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See the License for the specific language governing permissions and 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * limitations under the License. 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpackage com.android.server; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.io.PrintWriter; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.ArrayList; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.Collections; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.Comparator; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.HashMap; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.HashSet; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.Iterator; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.List; 271e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport java.util.Map; 281e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport java.util.Set; 291e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport android.util.Log; 311e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport android.util.LogPrinter; 321e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport android.util.Printer; 331e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt 341e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport android.util.Config; 351e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtimport android.content.ContentResolver; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport android.content.Intent; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport android.content.IntentFilter; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * {@hide} 41cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt */ 42cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtpublic class IntentResolver<F extends IntentFilter, R extends Object> { 43cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt final private static String TAG = "IntentResolver"; 44cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt final private static boolean DEBUG = false; 45cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt final private static boolean localLOGV = DEBUG || Config.LOGV; 46cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 47cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt public void addFilter(F f) { 48cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (localLOGV) { 49cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt Log.v(TAG, "Adding filter: " + f); 5004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt f.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 511e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt Log.v(TAG, " Building Lookup Maps:"); 521e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt } 531e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt 541e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt mFilters.add(f); 551e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt int numS = register_intent_filter(f, f.schemesIterator(), 561e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt mSchemeToFilter, " Scheme: "); 571e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt int numT = register_mime_types(f, " Type: "); 581e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (numS == 0 && numT == 0) { 591e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt register_intent_filter(f, f.actionsIterator(), 601e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt mActionToFilter, " Action: "); 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (numT != 0) { 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt register_intent_filter(f, f.actionsIterator(), 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mTypedActionToFilter, " TypedAction: "); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public void removeFilter(F f) { 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt removeFilterInternal(f); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mFilters.remove(f); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void removeFilterInternal(F f) { 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (localLOGV) { 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Log.v(TAG, "Removing filter: " + f); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Log.v(TAG, " Cleaning Lookup Maps:"); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int numS = unregister_intent_filter(f, f.schemesIterator(), 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mSchemeToFilter, " Scheme: "); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int numT = unregister_mime_types(f, " Type: "); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (numS == 0 && numT == 0) { 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unregister_intent_filter(f, f.actionsIterator(), 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mActionToFilter, " Action: "); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (numT != 0) { 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unregister_intent_filter(f, f.actionsIterator(), 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mTypedActionToFilter, " TypedAction: "); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void dumpMap(PrintWriter out, String prefix, Map<String, ArrayList<F>> map) { 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String eprefix = prefix + " "; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String fprefix = prefix + " "; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (Map.Entry<String, ArrayList<F>> e : map.entrySet()) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(eprefix); out.print(e.getKey()); out.println(":"); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> a = e.getValue(); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final int N = a.size(); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (int i=0; i<N; i++) { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpFilter(out, fprefix, a.get(i)); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public void dump(PrintWriter out, String prefix) { 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String innerPrefix = prefix + " "; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("Full MIME Types:"); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mTypeToFilter); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.println(" "); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("Base MIME Types:"); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mBaseTypeToFilter); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.println(" "); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("Wild MIME Types:"); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mWildTypeToFilter); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.println(" "); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("Schemes:"); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mSchemeToFilter); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.println(" "); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("Non-Data Actions:"); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mActionToFilter); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.println(" "); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println("MIME Typed Actions:"); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dumpMap(out, innerPrefix, mTypedActionToFilter); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private class IteratorWrapper implements Iterator<F> { 12868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt private final Iterator<F> mI; 12968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt private F mCur; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IteratorWrapper(Iterator<F> it) { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mI = it; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public boolean hasNext() { 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return mI.hasNext(); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public F next() { 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (mCur = mI.next()); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public void remove() { 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mCur != null) { 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt removeFilterInternal(mCur); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mI.remove(); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns an iterator allowing filters to be removed. 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public Iterator<F> filterIterator() { 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return new IteratorWrapper(mFilters.iterator()); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns a read-only set of the filters. 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public Set<F> filterSet() { 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Collections.unmodifiableSet(mFilters); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt public List<R> queryIntent(ContentResolver resolver, Intent intent, 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String resolvedType, boolean defaultOnly) { 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String scheme = intent.getScheme(); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<R> finalList = new ArrayList<R>(); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final boolean debug = localLOGV || 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v( 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TAG, "Resolving type " + resolvedType + " scheme " + scheme 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt + " of intent " + intent); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> firstTypeCut = null; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> secondTypeCut = null; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> thirdTypeCut = null; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> schemeCut = null; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the intent includes a MIME type, then we want to collect all of 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // the filters that match that MIME type. 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resolvedType != null) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int slashpos = resolvedType.indexOf('/'); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (slashpos > 0) { 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final String baseType = resolvedType.substring(0, slashpos); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!baseType.equals("*")) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resolvedType.length() != slashpos+2 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt || resolvedType.charAt(slashpos+1) != '*') { 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Not a wild card, so we can just look for all filters that 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // completely match or wildcards whose base type matches. 19568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt firstTypeCut = mTypeToFilter.get(resolvedType); 19668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (debug) Log.v(TAG, "First type cut: " + firstTypeCut); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt secondTypeCut = mWildTypeToFilter.get(baseType); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Second type cut: " + secondTypeCut); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // We can match anything with our base type. 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt firstTypeCut = mBaseTypeToFilter.get(baseType); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "First type cut: " + firstTypeCut); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt secondTypeCut = mWildTypeToFilter.get(baseType); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Second type cut: " + secondTypeCut); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Any */* types always apply, but we only need to do this 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // if the intent type was not already */*. 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt thirdTypeCut = mWildTypeToFilter.get("*"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Third type cut: " + thirdTypeCut); 210fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (intent.getAction() != null) { 211fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // The intent specified any type ({@literal *}/*). This 212fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // can be a whole heck of a lot of things, so as a first 213fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // cut let's use the action instead. 214fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt firstTypeCut = mTypedActionToFilter.get(intent.getAction()); 21568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (debug) Log.v(TAG, "Typed Action list: " + firstTypeCut); 21668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 21768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 21868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the intent includes a data URI, then we want to collect all of 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // the filters that match its scheme (we will further refine matches 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // on the authority and path by directly matching each resulting filter). 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scheme != null) { 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt schemeCut = mSchemeToFilter.get(scheme); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Scheme list: " + schemeCut); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the intent does not specify any data -- either a MIME type or 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // a URI -- then we will only be looking for matches against empty 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // data. 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resolvedType == null && scheme == null && intent.getAction() != null) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt firstTypeCut = mActionToFilter.get(intent.getAction()); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Action list: " + firstTypeCut); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (firstTypeCut != null) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buildResolveList(intent, debug, defaultOnly, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resolvedType, scheme, firstTypeCut, finalList); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (secondTypeCut != null) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buildResolveList(intent, debug, defaultOnly, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resolvedType, scheme, secondTypeCut, finalList); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (thirdTypeCut != null) { 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buildResolveList(intent, debug, defaultOnly, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resolvedType, scheme, thirdTypeCut, finalList); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (schemeCut != null) { 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buildResolveList(intent, debug, defaultOnly, 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resolvedType, scheme, schemeCut, finalList); 25168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 25268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sortResults(finalList); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Log.v(TAG, "Final result list:"); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (R r : finalList) { 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Log.v(TAG, " " + r); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return finalList; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Control whether the given filter is allowed to go into the result 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * list. Mainly intended to prevent adding multiple filters for the 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * same target object. 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt protected boolean allowFilterResult(F filter, List<R> dest) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt protected R newResult(F filter, int match) { 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (R)filter; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt protected void sortResults(List<R> results) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Collections.sort(results, mResolvePrioritySorter); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt protected void dumpFilter(PrintWriter out, String prefix, F filter) { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out.print(prefix); out.println(filter); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private final int register_mime_types(F filter, String prefix) { 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final Iterator<String> i = filter.typesIterator(); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == null) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num = 0; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (i.hasNext()) { 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String name = (String)i.next(); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (localLOGV) Log.v(TAG, prefix + name); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String baseName = name; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final int slashpos = name.indexOf('/'); 2976cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (slashpos > 0) { 2986cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt baseName = name.substring(0, slashpos).intern(); 2996cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt } else { 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = name + "/*"; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> array = mTypeToFilter.get(name); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array == null) { 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt //Log.v(TAG, "Creating new array for " + name); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = new ArrayList<F>(); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mTypeToFilter.put(name, array); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array.add(filter); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (slashpos > 0) { 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = mBaseTypeToFilter.get(baseName); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array == null) { 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt //Log.v(TAG, "Creating new array for " + name); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = new ArrayList<F>(); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mBaseTypeToFilter.put(baseName, array); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array.add(filter); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = mWildTypeToFilter.get(baseName); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array == null) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt //Log.v(TAG, "Creating new array for " + name); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = new ArrayList<F>(); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mWildTypeToFilter.put(baseName, array); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array.add(filter); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private final int unregister_mime_types(F filter, String prefix) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final Iterator<String> i = filter.typesIterator(); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == null) { 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num = 0; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (i.hasNext()) { 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String name = (String)i.next(); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (localLOGV) Log.v(TAG, prefix + name); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String baseName = name; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final int slashpos = name.indexOf('/'); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (slashpos > 0) { 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt baseName = name.substring(0, slashpos).intern(); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = name + "/*"; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!remove_all_objects(mTypeToFilter.get(name), filter)) { 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mTypeToFilter.remove(name); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (slashpos > 0) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!remove_all_objects(mBaseTypeToFilter.get(baseName), filter)) { 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mBaseTypeToFilter.remove(baseName); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!remove_all_objects(mWildTypeToFilter.get(baseName), filter)) { 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mWildTypeToFilter.remove(baseName); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private final int register_intent_filter(F filter, Iterator<String> i, 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HashMap<String, ArrayList<F>> dest, String prefix) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == null) { 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num = 0; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (i.hasNext()) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String name = i.next(); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (localLOGV) Log.v(TAG, prefix + name); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayList<F> array = dest.get(name); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (array == null) { 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt //Log.v(TAG, "Creating new array for " + name); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt array = new ArrayList<F>(); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dest.put(name, array); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt array.add(filter); 38704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 38804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return num; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private final int unregister_intent_filter(F filter, Iterator<String> i, 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HashMap<String, ArrayList<F>> dest, String prefix) { 39304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i == null) { 3945460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return 0; 3955460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 39604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 39704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int num = 0; 39804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt while (i.hasNext()) { 399cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt String name = i.next(); 400cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt num++; 401cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (localLOGV) Log.v(TAG, prefix + name); 402cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!remove_all_objects(dest.get(name), filter)) { 403cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dest.remove(name); 404cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 405cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 406cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return num; 40704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 40804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 40904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt private final boolean remove_all_objects(List<F> list, Object object) { 4105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (list != null) { 4115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt int N = list.size(); 41204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (int idx=0; idx<N; idx++) { 41304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (list.get(idx) == object) { 414cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt list.remove(idx); 415cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt idx--; 416cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt N--; 417cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 418cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 41904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return N > 0; 42004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 42104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private void buildResolveList(Intent intent, boolean debug, boolean defaultOnly, 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt String resolvedType, String scheme, List<F> src, List<R> dest) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Set<String> categories = intent.getCategories(); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final int N = src != null ? src.size() : 0; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt boolean hasNonDefaults = false; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i=0; i<N; i++) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt F filter = src.get(i); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int match; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, "Matching against filter " + filter); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Do we already have this one? 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!allowFilterResult(filter, dest)) { 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) { 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Log.v(TAG, " Filter's target already added"); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt match = filter.match( 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intent.getAction(), resolvedType, scheme, intent.getData(), categories, TAG); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (match >= 0) { 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (debug) Log.v(TAG, " Filter matched! match=0x" + 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Integer.toHexString(match)); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) { 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt final R oneResult = newResult(filter, match); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oneResult != null) { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dest.add(oneResult); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hasNonDefaults = true; 4564b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 4574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else { 4584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (debug) { 4594b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt String reason; 4604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt switch (match) { 4614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 4624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 4634b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 4644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 4654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt default: reason = "unknown reason"; break; 466cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 467cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt Log.v(TAG, " Filter did not match: " + reason); 468cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 469cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 470cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 471cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 472cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dest.size() == 0 && hasNonDefaults) { 473cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt Log.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT"); 474cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 475cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 476cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 477cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt // Sorts a List of IntentFilter objects into descending priority order. 478cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt private static final Comparator mResolvePrioritySorter = new Comparator() { 479cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt public int compare(Object o1, Object o2) { 480cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt float q1 = ((IntentFilter)o1).getPriority(); 481cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt float q2 = ((IntentFilter)o2).getPriority(); 482cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0); 483cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 484cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt }; 485cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 486 /** 487 * All filters that have been registered. 488 */ 489 private final HashSet<F> mFilters = new HashSet<F>(); 490 491 /** 492 * All of the MIME types that have been registered, such as "image/jpeg", 493 * "image/*", or "{@literal *}/*". 494 */ 495 private final HashMap<String, ArrayList<F>> mTypeToFilter 496 = new HashMap<String, ArrayList<F>>(); 497 498 /** 499 * The base names of all of all fully qualified MIME types that have been 500 * registered, such as "image" or "*". Wild card MIME types such as 501 * "image/*" will not be here. 502 */ 503 private final HashMap<String, ArrayList<F>> mBaseTypeToFilter 504 = new HashMap<String, ArrayList<F>>(); 505 506 /** 507 * The base names of all of the MIME types with a sub-type wildcard that 508 * have been registered. For example, a filter with "image/*" will be 509 * included here as "image" but one with "image/jpeg" will not be 510 * included here. This also includes the "*" for the "{@literal *}/*" 511 * MIME type. 512 */ 513 private final HashMap<String, ArrayList<F>> mWildTypeToFilter 514 = new HashMap<String, ArrayList<F>>(); 515 516 /** 517 * All of the URI schemes (such as http) that have been registered. 518 */ 519 private final HashMap<String, ArrayList<F>> mSchemeToFilter 520 = new HashMap<String, ArrayList<F>>(); 521 522 /** 523 * All of the actions that have been registered, but only those that did 524 * not specify data. 525 */ 526 private final HashMap<String, ArrayList<F>> mActionToFilter 527 = new HashMap<String, ArrayList<F>>(); 528 529 /** 530 * All of the actions that have been registered and specified a MIME type. 531 */ 532 private final HashMap<String, ArrayList<F>> mTypedActionToFilter 533 = new HashMap<String, ArrayList<F>>(); 534} 535 536