Skip to content

Commit a75537b

Browse files
Todd KennedyThe Android Automerger
authored andcommitted
DO NOT MERGE Fix intent filter priorities
Since this is a backport, there is only one rule that guards intent filter priorities: 1) Updates will NOT be granted a priority greater than the priority defined on the system image. Bug: 27450489 Change-Id: Ifcec4d7a59e684331399abc41eea1bd6876155a4
1 parent e7cf91a commit a75537b

2 files changed

Lines changed: 266 additions & 19 deletions

File tree

core/java/android/content/IntentFilter.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,15 @@ public boolean match(AuthorityEntry other) {
883883
return true;
884884
}
885885

886+
@Override
887+
public boolean equals(Object obj) {
888+
if (obj instanceof AuthorityEntry) {
889+
final AuthorityEntry other = (AuthorityEntry)obj;
890+
return match(other);
891+
}
892+
return false;
893+
}
894+
886895
/**
887896
* Determine whether this AuthorityEntry matches the given data Uri.
888897
* <em>Note that this comparison is case-sensitive, unlike formal
@@ -917,7 +926,7 @@ public int match(Uri data) {
917926
}
918927
return MATCH_CATEGORY_HOST;
919928
}
920-
};
929+
}
921930

922931
/**
923932
* Add a new Intent data "scheme specific part" to match against. The filter must

services/core/java/com/android/server/pm/PackageManagerService.java

Lines changed: 256 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)