Loading core/java/android/content/IntentFilter.java +10 −1 Original line number Diff line number Diff line Loading @@ -883,6 +883,15 @@ public class IntentFilter implements Parcelable { 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 @@ -917,7 +926,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 services/core/java/com/android/server/pm/PackageManagerService.java +256 −18 Original line number Diff line number Diff line Loading @@ -297,6 +297,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_PACKAGE_SCANNING = false; private static final boolean DEBUG_VERIFY = false; private static final boolean DEBUG_DEXOPT = false; private static final boolean DEBUG_FILTERS = false; private static final boolean DEBUG_ABI_SELECTION = false; static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; Loading Loading @@ -8744,6 +8745,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 = applicationInfo.isSystemApp(); 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<>(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 = a.info.applicationInfo.isSystemApp(); mActivities.put(a.getComponentName(), a); Loading @@ -8756,10 +9006,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 @@ -8913,18 +9165,6 @@ public class PackageManagerService extends IPackageManager.Stub { out.println(); } // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); // final List<ResolveInfo> retList = Lists.newArrayList(); // while (i.hasNext()) { // final ResolveInfo resolveInfo = i.next(); // if (isEnabledLP(resolveInfo.activityInfo)) { // retList.add(resolveInfo); // } // } // return retList; // } // Keys are String (activity class name), values are Activity. private final ArrayMap<ComponentName, PackageParser.Activity> mActivities = new ArrayMap<ComponentName, PackageParser.Activity>(); Loading Loading @@ -10974,8 +11214,6 @@ public class PackageManagerService extends IPackageManager.Stub { * Called after the source arguments are copied. This is used mostly for * MoveParams when it needs to read the source file to put it in the * destination. * * @return */ int doPostCopy(int uid) { return PackageManager.INSTALL_SUCCEEDED; Loading Loading
core/java/android/content/IntentFilter.java +10 −1 Original line number Diff line number Diff line Loading @@ -883,6 +883,15 @@ public class IntentFilter implements Parcelable { 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 @@ -917,7 +926,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
services/core/java/com/android/server/pm/PackageManagerService.java +256 −18 Original line number Diff line number Diff line Loading @@ -297,6 +297,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_PACKAGE_SCANNING = false; private static final boolean DEBUG_VERIFY = false; private static final boolean DEBUG_DEXOPT = false; private static final boolean DEBUG_FILTERS = false; private static final boolean DEBUG_ABI_SELECTION = false; static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; Loading Loading @@ -8744,6 +8745,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 = applicationInfo.isSystemApp(); 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<>(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 = a.info.applicationInfo.isSystemApp(); mActivities.put(a.getComponentName(), a); Loading @@ -8756,10 +9006,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 @@ -8913,18 +9165,6 @@ public class PackageManagerService extends IPackageManager.Stub { out.println(); } // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); // final List<ResolveInfo> retList = Lists.newArrayList(); // while (i.hasNext()) { // final ResolveInfo resolveInfo = i.next(); // if (isEnabledLP(resolveInfo.activityInfo)) { // retList.add(resolveInfo); // } // } // return retList; // } // Keys are String (activity class name), values are Activity. private final ArrayMap<ComponentName, PackageParser.Activity> mActivities = new ArrayMap<ComponentName, PackageParser.Activity>(); Loading Loading @@ -10974,8 +11214,6 @@ public class PackageManagerService extends IPackageManager.Stub { * Called after the source arguments are copied. This is used mostly for * MoveParams when it needs to read the source file to put it in the * destination. * * @return */ int doPostCopy(int uid) { return PackageManager.INSTALL_SUCCEEDED; Loading