@@ -297,6 +297,7 @@ public class PackageManagerService extends IPackageManager.Stub {
297297 private static final boolean DEBUG_PACKAGE_SCANNING = false;
298298 private static final boolean DEBUG_VERIFY = false;
299299 private static final boolean DEBUG_DEXOPT = false;
300+ private static final boolean DEBUG_FILTERS = false;
300301 private static final boolean DEBUG_ABI_SELECTION = false;
301302
302303 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
@@ -8744,6 +8745,255 @@ public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedTyp
87448745 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
87458746 }
87468747
8748+ /**
8749+ * Finds a privileged activity that matches the specified activity names.
8750+ */
8751+ private PackageParser.Activity findMatchingActivity(
8752+ List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
8753+ for (PackageParser.Activity sysActivity : activityList) {
8754+ if (sysActivity.info.name.equals(activityInfo.name)) {
8755+ return sysActivity;
8756+ }
8757+ if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
8758+ return sysActivity;
8759+ }
8760+ if (sysActivity.info.targetActivity != null) {
8761+ if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
8762+ return sysActivity;
8763+ }
8764+ if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
8765+ return sysActivity;
8766+ }
8767+ }
8768+ }
8769+ return null;
8770+ }
8771+
8772+ public class IterGenerator<E> {
8773+ public Iterator<E> generate(ActivityIntentInfo info) {
8774+ return null;
8775+ }
8776+ }
8777+
8778+ public class ActionIterGenerator extends IterGenerator<String> {
8779+ @Override
8780+ public Iterator<String> generate(ActivityIntentInfo info) {
8781+ return info.actionsIterator();
8782+ }
8783+ }
8784+
8785+ public class CategoriesIterGenerator extends IterGenerator<String> {
8786+ @Override
8787+ public Iterator<String> generate(ActivityIntentInfo info) {
8788+ return info.categoriesIterator();
8789+ }
8790+ }
8791+
8792+ public class SchemesIterGenerator extends IterGenerator<String> {
8793+ @Override
8794+ public Iterator<String> generate(ActivityIntentInfo info) {
8795+ return info.schemesIterator();
8796+ }
8797+ }
8798+
8799+ public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
8800+ @Override
8801+ public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
8802+ return info.authoritiesIterator();
8803+ }
8804+ }
8805+
8806+ /**
8807+ * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
8808+ * MODIFIED. Do not pass in a list that should not be changed.
8809+ */
8810+ private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
8811+ IterGenerator<T> generator, Iterator<T> searchIterator) {
8812+ // loop through the set of actions; every one must be found in the intent filter
8813+ while (searchIterator.hasNext()) {
8814+ // we must have at least one filter in the list to consider a match
8815+ if (intentList.size() == 0) {
8816+ break;
8817+ }
8818+
8819+ final T searchAction = searchIterator.next();
8820+
8821+ // loop through the set of intent filters
8822+ final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
8823+ while (intentIter.hasNext()) {
8824+ final ActivityIntentInfo intentInfo = intentIter.next();
8825+ boolean selectionFound = false;
8826+
8827+ // loop through the intent filter's selection criteria; at least one
8828+ // of them must match the searched criteria
8829+ final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
8830+ while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
8831+ final T intentSelection = intentSelectionIter.next();
8832+ if (intentSelection != null && intentSelection.equals(searchAction)) {
8833+ selectionFound = true;
8834+ break;
8835+ }
8836+ }
8837+
8838+ // the selection criteria wasn't found in this filter's set; this filter
8839+ // is not a potential match
8840+ if (!selectionFound) {
8841+ intentIter.remove();
8842+ }
8843+ }
8844+ }
8845+ }
8846+
8847+ /**
8848+ * Adjusts the priority of the given intent filter according to policy.
8849+ * <p>
8850+ * <ul>
8851+ * <li>The priority for unbundled updates to system applications is capped to the
8852+ * priority defined on the system partition</li>
8853+ * </ul>
8854+ */
8855+ private void adjustPriority(
8856+ List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
8857+ // nothing to do; priority is fine as-is
8858+ if (intent.getPriority() <= 0) {
8859+ return;
8860+ }
8861+
8862+ final ActivityInfo activityInfo = intent.activity.info;
8863+ final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
8864+
8865+ final boolean systemApp = applicationInfo.isSystemApp();
8866+ if (!systemApp) {
8867+ // non-system applications can never define a priority >0
8868+ Slog.w(TAG, "Non-system app; cap priority to 0;"
8869+ + " package: " + applicationInfo.packageName
8870+ + " activity: " + intent.activity.className
8871+ + " origPrio: " + intent.getPriority());
8872+ intent.setPriority(0);
8873+ return;
8874+ }
8875+
8876+ if (systemActivities == null) {
8877+ // the system package is not disabled; we're parsing the system partition
8878+ // apps on the system image get whatever priority they request
8879+ return;
8880+ }
8881+
8882+ // system app unbundled update ... try to find the same activity
8883+ final PackageParser.Activity foundActivity =
8884+ findMatchingActivity(systemActivities, activityInfo);
8885+ if (foundActivity == null) {
8886+ // this is a new activity; it cannot obtain >0 priority
8887+ if (DEBUG_FILTERS) {
8888+ Slog.i(TAG, "New activity; cap priority to 0;"
8889+ + " package: " + applicationInfo.packageName
8890+ + " activity: " + intent.activity.className
8891+ + " origPrio: " + intent.getPriority());
8892+ }
8893+ intent.setPriority(0);
8894+ return;
8895+ }
8896+
8897+ // found activity, now check for filter equivalence
8898+
8899+ // a shallow copy is enough; we modify the list, not its contents
8900+ final List<ActivityIntentInfo> intentListCopy =
8901+ new ArrayList<>(foundActivity.intents);
8902+ final List<ActivityIntentInfo> foundFilters = findFilters(intent);
8903+
8904+ // find matching action subsets
8905+ final Iterator<String> actionsIterator = intent.actionsIterator();
8906+ if (actionsIterator != null) {
8907+ getIntentListSubset(
8908+ intentListCopy, new ActionIterGenerator(), actionsIterator);
8909+ if (intentListCopy.size() == 0) {
8910+ // no more intents to match; we're not equivalent
8911+ if (DEBUG_FILTERS) {
8912+ Slog.i(TAG, "Mismatched action; cap priority to 0;"
8913+ + " package: " + applicationInfo.packageName
8914+ + " activity: " + intent.activity.className
8915+ + " origPrio: " + intent.getPriority());
8916+ }
8917+ intent.setPriority(0);
8918+ return;
8919+ }
8920+ }
8921+
8922+ // find matching category subsets
8923+ final Iterator<String> categoriesIterator = intent.categoriesIterator();
8924+ if (categoriesIterator != null) {
8925+ getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
8926+ categoriesIterator);
8927+ if (intentListCopy.size() == 0) {
8928+ // no more intents to match; we're not equivalent
8929+ if (DEBUG_FILTERS) {
8930+ Slog.i(TAG, "Mismatched category; cap priority to 0;"
8931+ + " package: " + applicationInfo.packageName
8932+ + " activity: " + intent.activity.className
8933+ + " origPrio: " + intent.getPriority());
8934+ }
8935+ intent.setPriority(0);
8936+ return;
8937+ }
8938+ }
8939+
8940+ // find matching schemes subsets
8941+ final Iterator<String> schemesIterator = intent.schemesIterator();
8942+ if (schemesIterator != null) {
8943+ getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
8944+ schemesIterator);
8945+ if (intentListCopy.size() == 0) {
8946+ // no more intents to match; we're not equivalent
8947+ if (DEBUG_FILTERS) {
8948+ Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
8949+ + " package: " + applicationInfo.packageName
8950+ + " activity: " + intent.activity.className
8951+ + " origPrio: " + intent.getPriority());
8952+ }
8953+ intent.setPriority(0);
8954+ return;
8955+ }
8956+ }
8957+
8958+ // find matching authorities subsets
8959+ final Iterator<IntentFilter.AuthorityEntry>
8960+ authoritiesIterator = intent.authoritiesIterator();
8961+ if (authoritiesIterator != null) {
8962+ getIntentListSubset(intentListCopy,
8963+ new AuthoritiesIterGenerator(),
8964+ authoritiesIterator);
8965+ if (intentListCopy.size() == 0) {
8966+ // no more intents to match; we're not equivalent
8967+ if (DEBUG_FILTERS) {
8968+ Slog.i(TAG, "Mismatched authority; cap priority to 0;"
8969+ + " package: " + applicationInfo.packageName
8970+ + " activity: " + intent.activity.className
8971+ + " origPrio: " + intent.getPriority());
8972+ }
8973+ intent.setPriority(0);
8974+ return;
8975+ }
8976+ }
8977+
8978+ // we found matching filter(s); app gets the max priority of all intents
8979+ int cappedPriority = 0;
8980+ for (int i = intentListCopy.size() - 1; i >= 0; --i) {
8981+ cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
8982+ }
8983+ if (intent.getPriority() > cappedPriority) {
8984+ if (DEBUG_FILTERS) {
8985+ Slog.i(TAG, "Found matching filter(s);"
8986+ + " cap priority to " + cappedPriority + ";"
8987+ + " package: " + applicationInfo.packageName
8988+ + " activity: " + intent.activity.className
8989+ + " origPrio: " + intent.getPriority());
8990+ }
8991+ intent.setPriority(cappedPriority);
8992+ return;
8993+ }
8994+ // all this for nothing; the requested priority was <= what was on the system
8995+ }
8996+
87478997 public final void addActivity(PackageParser.Activity a, String type) {
87488998 final boolean systemApp = a.info.applicationInfo.isSystemApp();
87498999 mActivities.put(a.getComponentName(), a);
@@ -8756,10 +9006,12 @@ public final void addActivity(PackageParser.Activity a, String type) {
87569006 final int NI = a.intents.size();
87579007 for (int j=0; j<NI; j++) {
87589008 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
8759- if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
8760- intent.setPriority(0);
8761- Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
8762- + a.className + " with priority > 0, forcing to 0");
9009+ if ("activity".equals(type)) {
9010+ final PackageSetting ps =
9011+ mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
9012+ final List<PackageParser.Activity> systemActivities =
9013+ ps != null && ps.pkg != null ? ps.pkg.activities : null;
9014+ adjustPriority(systemActivities, intent);
87639015 }
87649016 if (DEBUG_SHOW_INFO) {
87659017 Log.v(TAG, " IntentFilter:");
@@ -8913,18 +9165,6 @@ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int
89139165 out.println();
89149166 }
89159167
8916- // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
8917- // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
8918- // final List<ResolveInfo> retList = Lists.newArrayList();
8919- // while (i.hasNext()) {
8920- // final ResolveInfo resolveInfo = i.next();
8921- // if (isEnabledLP(resolveInfo.activityInfo)) {
8922- // retList.add(resolveInfo);
8923- // }
8924- // }
8925- // return retList;
8926- // }
8927-
89289168 // Keys are String (activity class name), values are Activity.
89299169 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
89309170 = new ArrayMap<ComponentName, PackageParser.Activity>();
@@ -10974,8 +11214,6 @@ int doPreCopy() {
1097411214 * Called after the source arguments are copied. This is used mostly for
1097511215 * MoveParams when it needs to read the source file to put it in the
1097611216 * destination.
10977- *
10978- * @return
1097911217 */
1098011218 int doPostCopy(int uid) {
1098111219 return PackageManager.INSTALL_SUCCEEDED;
0 commit comments