Add filter ordering
Filter ordering allows automatic disambiguation between multiple filters that matching a pattern. Ordering currently only works for EphemeralResolveInfo objects. Bug: 30837021 Change-Id: Ia217218c7c7d159dbd75d7733c45556e690d06d2
This commit is contained in:
@@ -265,6 +265,7 @@ public class IntentFilter implements Parcelable {
|
||||
public static final String SCHEME_HTTPS = "https";
|
||||
|
||||
private int mPriority;
|
||||
private int mOrder;
|
||||
private final ArrayList<String> mActions;
|
||||
private ArrayList<String> mCategories = null;
|
||||
private ArrayList<String> mDataSchemes = null;
|
||||
@@ -425,6 +426,7 @@ public class IntentFilter implements Parcelable {
|
||||
*/
|
||||
public IntentFilter(IntentFilter o) {
|
||||
mPriority = o.mPriority;
|
||||
mOrder = o.mOrder;
|
||||
mActions = new ArrayList<String>(o.mActions);
|
||||
if (o.mCategories != null) {
|
||||
mCategories = new ArrayList<String>(o.mCategories);
|
||||
@@ -477,6 +479,16 @@ public class IntentFilter implements Parcelable {
|
||||
return mPriority;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public final void setOrder(int order) {
|
||||
mOrder = order;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public final int getOrder() {
|
||||
return mOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this filter will needs to be automatically verified against its data URIs or not.
|
||||
* The default is false.
|
||||
|
||||
@@ -364,6 +364,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
|
||||
buildResolveList(intent, categories, debug, defaultOnly,
|
||||
resolvedType, scheme, listCut.get(i), resultList, userId);
|
||||
}
|
||||
filterResults(resultList);
|
||||
sortResults(resultList);
|
||||
return resultList;
|
||||
}
|
||||
@@ -457,6 +458,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
|
||||
buildResolveList(intent, categories, debug, defaultOnly,
|
||||
resolvedType, scheme, schemeCut, finalList, userId);
|
||||
}
|
||||
filterResults(finalList);
|
||||
sortResults(finalList);
|
||||
|
||||
if (debug) {
|
||||
@@ -521,6 +523,12 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
|
||||
Collections.sort(results, mResolvePrioritySorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filtering to the results. This happens before the results are sorted.
|
||||
*/
|
||||
protected void filterResults(List<R> results) {
|
||||
}
|
||||
|
||||
protected void dumpFilter(PrintWriter out, String prefix, F filter) {
|
||||
out.print(prefix); out.println(filter);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,7 @@ import android.util.ExceptionUtils;
|
||||
import android.util.Log;
|
||||
import android.util.LogPrinter;
|
||||
import android.util.MathUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.PrintStreamPrinter;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -11229,6 +11230,19 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
|
||||
private static final class EphemeralIntentResolver
|
||||
extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
|
||||
/**
|
||||
* The result that has the highest defined order. Ordering applies on a
|
||||
* per-package basis. Mapping is from package name to Pair of order and
|
||||
* EphemeralResolveInfo.
|
||||
* <p>
|
||||
* NOTE: This is implemented as a field variable for convenience and efficiency.
|
||||
* By having a field variable, we're able to track filter ordering as soon as
|
||||
* a non-zero order is defined. Otherwise, multiple loops across the result set
|
||||
* would be needed to apply ordering. If the intent resolver becomes re-entrant,
|
||||
* this needs to be contained entirely within {@link #filterResults()}.
|
||||
*/
|
||||
final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
|
||||
|
||||
@Override
|
||||
protected EphemeralResolveIntentInfo[] newArray(int size) {
|
||||
return new EphemeralResolveIntentInfo[size];
|
||||
@@ -11245,7 +11259,51 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
if (!sUserManager.exists(userId)) {
|
||||
return null;
|
||||
}
|
||||
return info.getEphemeralResolveInfo();
|
||||
final String packageName = info.getEphemeralResolveInfo().getPackageName();
|
||||
final Integer order = info.getOrder();
|
||||
final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
|
||||
mOrderResult.get(packageName);
|
||||
// ordering is enabled and this item's order isn't high enough
|
||||
if (lastOrderResult != null && lastOrderResult.first >= order) {
|
||||
return null;
|
||||
}
|
||||
final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
|
||||
if (order > 0) {
|
||||
// non-zero order, enable ordering
|
||||
mOrderResult.put(packageName, new Pair<>(order, res));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filterResults(List<EphemeralResolveInfo> results) {
|
||||
// only do work if ordering is enabled [most of the time it won't be]
|
||||
if (mOrderResult.size() == 0) {
|
||||
return;
|
||||
}
|
||||
int resultSize = results.size();
|
||||
for (int i = 0; i < resultSize; i++) {
|
||||
final EphemeralResolveInfo info = results.get(i);
|
||||
final String packageName = info.getPackageName();
|
||||
final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
|
||||
if (savedInfo == null) {
|
||||
// package doesn't having ordering
|
||||
continue;
|
||||
}
|
||||
if (savedInfo.second == info) {
|
||||
// circled back to the highest ordered item; remove from order list
|
||||
mOrderResult.remove(savedInfo);
|
||||
if (mOrderResult.size() == 0) {
|
||||
// no more ordered items
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// item has a worse order, remove it from the result list
|
||||
results.remove(i);
|
||||
resultSize--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user