Loading core/java/android/content/IntentFilter.java +73 −1 Original line number Diff line number Diff line Loading @@ -564,6 +564,11 @@ public class IntentFilter implements Parcelable { return mDataTypes != null && findMimeType(type); } /** @hide */ public final boolean hasExactDataType(String type) { return mDataTypes != null && mDataTypes.contains(type); } /** * Return the number of data types in the filter. */ Loading Loading @@ -681,6 +686,29 @@ public class IntentFilter implements Parcelable { return mPort; } /** @hide */ public boolean match(AuthorityEntry other) { if (mWild != other.mWild) { return false; } if (!mHost.equals(other.mHost)) { return false; } if (mPort != other.mPort) { return false; } return true; } @Override public boolean equals(Object obj) { if (obj instanceof AuthorityEntry) { final AuthorityEntry other = (AuthorityEntry)obj; return match(other); } return false; } /** * Determine whether this AuthorityEntry matches the given data Uri. * <em>Note that this comparison is case-sensitive, unlike formal Loading Loading @@ -715,7 +743,7 @@ public class IntentFilter implements Parcelable { } return MATCH_CATEGORY_HOST; } }; } /** * Add a new Intent data "scheme specific part" to match against. The filter must Loading Loading @@ -792,6 +820,21 @@ public class IntentFilter implements Parcelable { return false; } /** @hide */ public final boolean hasDataSchemeSpecificPart(PatternMatcher ssp) { if (mDataSchemeSpecificParts == null) { return false; } final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size(); for (int i = 0; i < numDataSchemeSpecificParts; i++) { final PatternMatcher pe = mDataSchemeSpecificParts.get(i); if (pe.getType() == ssp.getType() && pe.getPath().equals(ssp.getPath())) { return true; } } return false; } /** * Return an iterator over the filter's data scheme specific parts. */ Loading Loading @@ -860,6 +903,20 @@ public class IntentFilter implements Parcelable { return matchDataAuthority(data) >= 0; } /** @hide */ public final boolean hasDataAuthority(AuthorityEntry auth) { if (mDataAuthorities == null) { return false; } final int numDataAuthorities = mDataAuthorities.size(); for (int i = 0; i < numDataAuthorities; i++) { if (mDataAuthorities.get(i).match(auth)) { return true; } } return false; } /** * Return an iterator over the filter's data authorities. */ Loading Loading @@ -942,6 +999,21 @@ public class IntentFilter implements Parcelable { return false; } /** @hide */ public final boolean hasDataPath(PatternMatcher path) { if (mDataPaths == null) { return false; } final int numDataPaths = mDataPaths.size(); for (int i = 0; i < numDataPaths; i++) { final PatternMatcher pe = mDataPaths.get(i); if (pe.getType() == path.getType() && pe.getPath().equals(path.getPath())) { return true; } } return false; } /** * Return an iterator over the filter's data paths. */ Loading services/core/java/com/android/server/IntentResolver.java +118 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,124 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } } private boolean filterEquals(IntentFilter f1, IntentFilter f2) { int s1 = f1.countActions(); int s2 = f2.countActions(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasAction(f1.getAction(i))) { return false; } } s1 = f1.countCategories(); s2 = f2.countCategories(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasCategory(f1.getCategory(i))) { return false; } } s1 = f1.countDataTypes(); s2 = f2.countDataTypes(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasExactDataType(f1.getDataType(i))) { return false; } } s1 = f1.countDataSchemes(); s2 = f2.countDataSchemes(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataScheme(f1.getDataScheme(i))) { return false; } } s1 = f1.countDataAuthorities(); s2 = f2.countDataAuthorities(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataAuthority(f1.getDataAuthority(i))) { return false; } } s1 = f1.countDataPaths(); s2 = f2.countDataPaths(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataPath(f1.getDataPath(i))) { return false; } } s1 = f1.countDataSchemeSpecificParts(); s2 = f2.countDataSchemeSpecificParts(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) { return false; } } return true; } private ArrayList<F> collectFilters(F[] array, IntentFilter matching) { ArrayList<F> res = null; if (array != null) { for (int i=0; i<array.length; i++) { F cur = array[i]; if (cur == null) { break; } if (filterEquals(cur, matching)) { if (res == null) { res = new ArrayList<F>(); } res.add(cur); } } } return res; } public ArrayList<F> findFilters(IntentFilter matching) { if (matching.countDataSchemes() == 1) { // Fast case. return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching); } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) { // Another fast case. return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching); } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0 && matching.countActions() == 1) { // Last fast case. return collectFilters(mActionToFilter.get(matching.getAction(0)), matching); } else { ArrayList<F> res = null; for (F cur : mFilters) { if (filterEquals(cur, matching)) { if (res == null) { res = new ArrayList<F>(); } res.add(cur); } } return res; } } public void removeFilter(F f) { removeFilterInternal(f); mFilters.remove(f); Loading services/core/java/com/android/server/pm/PackageManagerService.java +256 −4 Original line number Diff line number Diff line Loading @@ -191,6 +191,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_PACKAGE_SCANNING = false; private static final boolean DEBUG_APP_DIR_OBSERVER = false; private static final boolean DEBUG_VERIFY = false; private static final boolean DEBUG_FILTERS = false; private static final int RADIO_UID = Process.PHONE_UID; private static final int LOG_UID = Process.LOG_UID; Loading Loading @@ -5726,6 +5727,255 @@ public class PackageManagerService extends IPackageManager.Stub { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } /** * Finds a privileged activity that matches the specified activity names. */ private PackageParser.Activity findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { for (PackageParser.Activity sysActivity : activityList) { if (sysActivity.info.name.equals(activityInfo.name)) { return sysActivity; } if (sysActivity.info.name.equals(activityInfo.targetActivity)) { return sysActivity; } if (sysActivity.info.targetActivity != null) { if (sysActivity.info.targetActivity.equals(activityInfo.name)) { return sysActivity; } if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { return sysActivity; } } } return null; } public class IterGenerator<E> { public Iterator<E> generate(ActivityIntentInfo info) { return null; } } public class ActionIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.actionsIterator(); } } public class CategoriesIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.categoriesIterator(); } } public class SchemesIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.schemesIterator(); } } public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { @Override public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { return info.authoritiesIterator(); } } /** * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE * MODIFIED. Do not pass in a list that should not be changed. */ private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator) { // loop through the set of actions; every one must be found in the intent filter while (searchIterator.hasNext()) { // we must have at least one filter in the list to consider a match if (intentList.size() == 0) { break; } final T searchAction = searchIterator.next(); // loop through the set of intent filters final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); while (intentIter.hasNext()) { final ActivityIntentInfo intentInfo = intentIter.next(); boolean selectionFound = false; // loop through the intent filter's selection criteria; at least one // of them must match the searched criteria final Iterator<T> intentSelectionIter = generator.generate(intentInfo); while (intentSelectionIter != null && intentSelectionIter.hasNext()) { final T intentSelection = intentSelectionIter.next(); if (intentSelection != null && intentSelection.equals(searchAction)) { selectionFound = true; break; } } // the selection criteria wasn't found in this filter's set; this filter // is not a potential match if (!selectionFound) { intentIter.remove(); } } } } /** * Adjusts the priority of the given intent filter according to policy. * <p> * <ul> * <li>The priority for unbundled updates to system applications is capped to the * priority defined on the system partition</li> * </ul> */ private void adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { // nothing to do; priority is fine as-is if (intent.getPriority() <= 0) { return; } final ActivityInfo activityInfo = intent.activity.info; final ApplicationInfo applicationInfo = activityInfo.applicationInfo; final boolean systemApp = isSystemApp(applicationInfo); if (!systemApp) { // non-system applications can never define a priority >0 Slog.w(TAG, "Non-system app; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); intent.setPriority(0); return; } if (systemActivities == null) { // the system package is not disabled; we're parsing the system partition // apps on the system image get whatever priority they request return; } // system app unbundled update ... try to find the same activity final PackageParser.Activity foundActivity = findMatchingActivity(systemActivities, activityInfo); if (foundActivity == null) { // this is a new activity; it cannot obtain >0 priority if (DEBUG_FILTERS) { Slog.i(TAG, "New activity; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } // found activity, now check for filter equivalence // a shallow copy is enough; we modify the list, not its contents final List<ActivityIntentInfo> intentListCopy = new ArrayList<ActivityIntentInfo>(foundActivity.intents); final List<ActivityIntentInfo> foundFilters = findFilters(intent); // find matching action subsets final Iterator<String> actionsIterator = intent.actionsIterator(); if (actionsIterator != null) { getIntentListSubset( intentListCopy, new ActionIterGenerator(), actionsIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched action; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching category subsets final Iterator<String> categoriesIterator = intent.categoriesIterator(); if (categoriesIterator != null) { getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched category; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching schemes subsets final Iterator<String> schemesIterator = intent.schemesIterator(); if (schemesIterator != null) { getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched scheme; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching authorities subsets final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator = intent.authoritiesIterator(); if (authoritiesIterator != null) { getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(), authoritiesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched authority; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // we found matching filter(s); app gets the max priority of all intents int cappedPriority = 0; for (int i = intentListCopy.size() - 1; i >= 0; --i) { cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); } if (intent.getPriority() > cappedPriority) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found matching filter(s);" + " cap priority to " + cappedPriority + ";" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(cappedPriority); return; } // all this for nothing; the requested priority was <= what was on the system } public final void addActivity(PackageParser.Activity a, String type) { final boolean systemApp = isSystemApp(a.info.applicationInfo); mActivities.put(a.getComponentName(), a); Loading @@ -5738,10 +5988,12 @@ public class PackageManagerService extends IPackageManager.Stub { final int NI = a.intents.size(); for (int j=0; j<NI; j++) { PackageParser.ActivityIntentInfo intent = a.intents.get(j); if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { intent.setPriority(0); Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " + a.className + " with priority > 0, forcing to 0"); if ("activity".equals(type)) { final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); final List<PackageParser.Activity> systemActivities = ps != null && ps.pkg != null ? ps.pkg.activities : null; adjustPriority(systemActivities, intent); } if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); Loading Loading
core/java/android/content/IntentFilter.java +73 −1 Original line number Diff line number Diff line Loading @@ -564,6 +564,11 @@ public class IntentFilter implements Parcelable { return mDataTypes != null && findMimeType(type); } /** @hide */ public final boolean hasExactDataType(String type) { return mDataTypes != null && mDataTypes.contains(type); } /** * Return the number of data types in the filter. */ Loading Loading @@ -681,6 +686,29 @@ public class IntentFilter implements Parcelable { return mPort; } /** @hide */ public boolean match(AuthorityEntry other) { if (mWild != other.mWild) { return false; } if (!mHost.equals(other.mHost)) { return false; } if (mPort != other.mPort) { return false; } return true; } @Override public boolean equals(Object obj) { if (obj instanceof AuthorityEntry) { final AuthorityEntry other = (AuthorityEntry)obj; return match(other); } return false; } /** * Determine whether this AuthorityEntry matches the given data Uri. * <em>Note that this comparison is case-sensitive, unlike formal Loading Loading @@ -715,7 +743,7 @@ public class IntentFilter implements Parcelable { } return MATCH_CATEGORY_HOST; } }; } /** * Add a new Intent data "scheme specific part" to match against. The filter must Loading Loading @@ -792,6 +820,21 @@ public class IntentFilter implements Parcelable { return false; } /** @hide */ public final boolean hasDataSchemeSpecificPart(PatternMatcher ssp) { if (mDataSchemeSpecificParts == null) { return false; } final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size(); for (int i = 0; i < numDataSchemeSpecificParts; i++) { final PatternMatcher pe = mDataSchemeSpecificParts.get(i); if (pe.getType() == ssp.getType() && pe.getPath().equals(ssp.getPath())) { return true; } } return false; } /** * Return an iterator over the filter's data scheme specific parts. */ Loading Loading @@ -860,6 +903,20 @@ public class IntentFilter implements Parcelable { return matchDataAuthority(data) >= 0; } /** @hide */ public final boolean hasDataAuthority(AuthorityEntry auth) { if (mDataAuthorities == null) { return false; } final int numDataAuthorities = mDataAuthorities.size(); for (int i = 0; i < numDataAuthorities; i++) { if (mDataAuthorities.get(i).match(auth)) { return true; } } return false; } /** * Return an iterator over the filter's data authorities. */ Loading Loading @@ -942,6 +999,21 @@ public class IntentFilter implements Parcelable { return false; } /** @hide */ public final boolean hasDataPath(PatternMatcher path) { if (mDataPaths == null) { return false; } final int numDataPaths = mDataPaths.size(); for (int i = 0; i < numDataPaths; i++) { final PatternMatcher pe = mDataPaths.get(i); if (pe.getType() == path.getType() && pe.getPath().equals(path.getPath())) { return true; } } return false; } /** * Return an iterator over the filter's data paths. */ Loading
services/core/java/com/android/server/IntentResolver.java +118 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,124 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } } private boolean filterEquals(IntentFilter f1, IntentFilter f2) { int s1 = f1.countActions(); int s2 = f2.countActions(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasAction(f1.getAction(i))) { return false; } } s1 = f1.countCategories(); s2 = f2.countCategories(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasCategory(f1.getCategory(i))) { return false; } } s1 = f1.countDataTypes(); s2 = f2.countDataTypes(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasExactDataType(f1.getDataType(i))) { return false; } } s1 = f1.countDataSchemes(); s2 = f2.countDataSchemes(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataScheme(f1.getDataScheme(i))) { return false; } } s1 = f1.countDataAuthorities(); s2 = f2.countDataAuthorities(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataAuthority(f1.getDataAuthority(i))) { return false; } } s1 = f1.countDataPaths(); s2 = f2.countDataPaths(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataPath(f1.getDataPath(i))) { return false; } } s1 = f1.countDataSchemeSpecificParts(); s2 = f2.countDataSchemeSpecificParts(); if (s1 != s2) { return false; } for (int i=0; i<s1; i++) { if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) { return false; } } return true; } private ArrayList<F> collectFilters(F[] array, IntentFilter matching) { ArrayList<F> res = null; if (array != null) { for (int i=0; i<array.length; i++) { F cur = array[i]; if (cur == null) { break; } if (filterEquals(cur, matching)) { if (res == null) { res = new ArrayList<F>(); } res.add(cur); } } } return res; } public ArrayList<F> findFilters(IntentFilter matching) { if (matching.countDataSchemes() == 1) { // Fast case. return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching); } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) { // Another fast case. return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching); } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0 && matching.countActions() == 1) { // Last fast case. return collectFilters(mActionToFilter.get(matching.getAction(0)), matching); } else { ArrayList<F> res = null; for (F cur : mFilters) { if (filterEquals(cur, matching)) { if (res == null) { res = new ArrayList<F>(); } res.add(cur); } } return res; } } public void removeFilter(F f) { removeFilterInternal(f); mFilters.remove(f); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +256 −4 Original line number Diff line number Diff line Loading @@ -191,6 +191,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_PACKAGE_SCANNING = false; private static final boolean DEBUG_APP_DIR_OBSERVER = false; private static final boolean DEBUG_VERIFY = false; private static final boolean DEBUG_FILTERS = false; private static final int RADIO_UID = Process.PHONE_UID; private static final int LOG_UID = Process.LOG_UID; Loading Loading @@ -5726,6 +5727,255 @@ public class PackageManagerService extends IPackageManager.Stub { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } /** * Finds a privileged activity that matches the specified activity names. */ private PackageParser.Activity findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { for (PackageParser.Activity sysActivity : activityList) { if (sysActivity.info.name.equals(activityInfo.name)) { return sysActivity; } if (sysActivity.info.name.equals(activityInfo.targetActivity)) { return sysActivity; } if (sysActivity.info.targetActivity != null) { if (sysActivity.info.targetActivity.equals(activityInfo.name)) { return sysActivity; } if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { return sysActivity; } } } return null; } public class IterGenerator<E> { public Iterator<E> generate(ActivityIntentInfo info) { return null; } } public class ActionIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.actionsIterator(); } } public class CategoriesIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.categoriesIterator(); } } public class SchemesIterGenerator extends IterGenerator<String> { @Override public Iterator<String> generate(ActivityIntentInfo info) { return info.schemesIterator(); } } public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { @Override public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { return info.authoritiesIterator(); } } /** * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE * MODIFIED. Do not pass in a list that should not be changed. */ private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator) { // loop through the set of actions; every one must be found in the intent filter while (searchIterator.hasNext()) { // we must have at least one filter in the list to consider a match if (intentList.size() == 0) { break; } final T searchAction = searchIterator.next(); // loop through the set of intent filters final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); while (intentIter.hasNext()) { final ActivityIntentInfo intentInfo = intentIter.next(); boolean selectionFound = false; // loop through the intent filter's selection criteria; at least one // of them must match the searched criteria final Iterator<T> intentSelectionIter = generator.generate(intentInfo); while (intentSelectionIter != null && intentSelectionIter.hasNext()) { final T intentSelection = intentSelectionIter.next(); if (intentSelection != null && intentSelection.equals(searchAction)) { selectionFound = true; break; } } // the selection criteria wasn't found in this filter's set; this filter // is not a potential match if (!selectionFound) { intentIter.remove(); } } } } /** * Adjusts the priority of the given intent filter according to policy. * <p> * <ul> * <li>The priority for unbundled updates to system applications is capped to the * priority defined on the system partition</li> * </ul> */ private void adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { // nothing to do; priority is fine as-is if (intent.getPriority() <= 0) { return; } final ActivityInfo activityInfo = intent.activity.info; final ApplicationInfo applicationInfo = activityInfo.applicationInfo; final boolean systemApp = isSystemApp(applicationInfo); if (!systemApp) { // non-system applications can never define a priority >0 Slog.w(TAG, "Non-system app; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); intent.setPriority(0); return; } if (systemActivities == null) { // the system package is not disabled; we're parsing the system partition // apps on the system image get whatever priority they request return; } // system app unbundled update ... try to find the same activity final PackageParser.Activity foundActivity = findMatchingActivity(systemActivities, activityInfo); if (foundActivity == null) { // this is a new activity; it cannot obtain >0 priority if (DEBUG_FILTERS) { Slog.i(TAG, "New activity; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } // found activity, now check for filter equivalence // a shallow copy is enough; we modify the list, not its contents final List<ActivityIntentInfo> intentListCopy = new ArrayList<ActivityIntentInfo>(foundActivity.intents); final List<ActivityIntentInfo> foundFilters = findFilters(intent); // find matching action subsets final Iterator<String> actionsIterator = intent.actionsIterator(); if (actionsIterator != null) { getIntentListSubset( intentListCopy, new ActionIterGenerator(), actionsIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched action; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching category subsets final Iterator<String> categoriesIterator = intent.categoriesIterator(); if (categoriesIterator != null) { getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched category; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching schemes subsets final Iterator<String> schemesIterator = intent.schemesIterator(); if (schemesIterator != null) { getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched scheme; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching authorities subsets final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator = intent.authoritiesIterator(); if (authoritiesIterator != null) { getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(), authoritiesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched authority; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // we found matching filter(s); app gets the max priority of all intents int cappedPriority = 0; for (int i = intentListCopy.size() - 1; i >= 0; --i) { cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); } if (intent.getPriority() > cappedPriority) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found matching filter(s);" + " cap priority to " + cappedPriority + ";" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(cappedPriority); return; } // all this for nothing; the requested priority was <= what was on the system } public final void addActivity(PackageParser.Activity a, String type) { final boolean systemApp = isSystemApp(a.info.applicationInfo); mActivities.put(a.getComponentName(), a); Loading @@ -5738,10 +5988,12 @@ public class PackageManagerService extends IPackageManager.Stub { final int NI = a.intents.size(); for (int j=0; j<NI; j++) { PackageParser.ActivityIntentInfo intent = a.intents.get(j); if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { intent.setPriority(0); Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " + a.className + " with priority > 0, forcing to 0"); if ("activity".equals(type)) { final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); final List<PackageParser.Activity> systemActivities = ps != null && ps.pkg != null ? ps.pkg.activities : null; adjustPriority(systemActivities, intent); } if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); Loading