diff options
| author | 2015-07-06 16:57:56 -0700 | |
|---|---|---|
| committer | 2015-07-06 18:39:34 -0700 | |
| commit | a182e45c6851a8db89e8b0900f0812806ff295d4 (patch) | |
| tree | d3b9f9241132d743f012cd186237810851060033 | |
| parent | 441fc0fc68140368d5438a6eb5b896b4a9d6ad4e (diff) | |
Sort and limit ChooserActivity targets from ChooserTargetServices
Apply an automated decay factor if apps decide to claim all of their
targets are SUPER IMPORTANT. Apply the multiplier from the apps
themselves as well as a penalty for apps that come in late - let's see
how fast developers get their ChooserTargetServices to start!
Also fix a bug with ResolverDrawerLayout where dragging from the title
area wouldn't always work properly.
Bug 22302285
Change-Id: Ib6eb2b6fb92608790b2267c0f671c9ae59b2907e
4 files changed, 86 insertions, 12 deletions
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 1b55557e8dd7..c4f57c7c38bf 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -59,6 +59,8 @@ import com.android.internal.R; import com.android.internal.logging.MetricsLogger; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; public class ChooserActivity extends ResolverActivity { @@ -97,7 +99,10 @@ public class ChooserActivity extends ResolverActivity { + " Have you considered returning results faster?"); break; } - mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets); + if (sri.resultTargets != null) { + mChooserListAdapter.addServiceResults(sri.originalTarget, + sri.resultTargets); + } unbindService(sri.connection); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { @@ -485,10 +490,13 @@ public class ChooserActivity extends ResolverActivity { private Drawable mDisplayIcon; private final Intent mFillInIntent; private final int mFillInFlags; + private final float mModifiedScore; - public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget) { + public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget, + float modifiedScore) { mSourceInfo = sourceInfo; mChooserTarget = chooserTarget; + mModifiedScore = modifiedScore; if (sourceInfo != null) { final ResolveInfo ri = sourceInfo.getResolveInfo(); if (ri != null) { @@ -520,6 +528,11 @@ public class ChooserActivity extends ResolverActivity { mDisplayIcon = other.mDisplayIcon; mFillInIntent = fillInIntent; mFillInFlags = flags; + mModifiedScore = other.mModifiedScore; + } + + public float getModifiedScore() { + return mModifiedScore; } @Override @@ -632,9 +645,16 @@ public class ChooserActivity extends ResolverActivity { public static final int TARGET_SERVICE = 1; public static final int TARGET_STANDARD = 2; + private static final int MAX_SERVICE_TARGETS = 8; + private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); private final List<TargetInfo> mCallerTargets = new ArrayList<>(); + private float mLateFee = 1.f; + + private final BaseChooserTargetComparator mBaseTargetComparator + = new BaseChooserTargetComparator(); + public ChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) { @@ -703,12 +723,12 @@ public class ChooserActivity extends ResolverActivity { @Override public int getCount() { - return super.getCount() + mServiceTargets.size() + mCallerTargets.size(); + return super.getCount() + getServiceTargetCount() + getCallerTargetCount(); } @Override public int getUnfilteredCount() { - return super.getUnfilteredCount() + mServiceTargets.size() + mCallerTargets.size(); + return super.getUnfilteredCount() + getServiceTargetCount() + getCallerTargetCount(); } public int getCallerTargetCount() { @@ -716,7 +736,7 @@ public class ChooserActivity extends ResolverActivity { } public int getServiceTargetCount() { - return mServiceTargets.size(); + return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS); } public int getStandardTargetCount() { @@ -726,13 +746,13 @@ public class ChooserActivity extends ResolverActivity { public int getPositionTargetType(int position) { int offset = 0; - final int callerTargetCount = mCallerTargets.size(); + final int callerTargetCount = getCallerTargetCount(); if (position < callerTargetCount) { return TARGET_CALLER; } offset += callerTargetCount; - final int serviceTargetCount = mServiceTargets.size(); + final int serviceTargetCount = getServiceTargetCount(); if (position - offset < serviceTargetCount) { return TARGET_SERVICE; } @@ -755,13 +775,13 @@ public class ChooserActivity extends ResolverActivity { public TargetInfo targetInfoForPosition(int position, boolean filtered) { int offset = 0; - final int callerTargetCount = mCallerTargets.size(); + final int callerTargetCount = getCallerTargetCount(); if (position < callerTargetCount) { return mCallerTargets.get(position); } offset += callerTargetCount; - final int serviceTargetCount = mServiceTargets.size(); + final int serviceTargetCount = getServiceTargetCount(); if (position - offset < serviceTargetCount) { return mServiceTargets.get(position - offset); } @@ -774,15 +794,49 @@ public class ChooserActivity extends ResolverActivity { public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) { if (DEBUG) Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size() + " targets"); + final float parentScore = getScore(origTarget); + Collections.sort(targets, mBaseTargetComparator); + float lastScore = 0; for (int i = 0, N = targets.size(); i < N; i++) { - mServiceTargets.add(new ChooserTargetInfo(origTarget, targets.get(i))); + final ChooserTarget target = targets.get(i); + float targetScore = target.getScore(); + targetScore *= parentScore; + targetScore *= mLateFee; + if (i > 0 && targetScore >= lastScore) { + // Apply a decay so that the top app can't crowd out everything else. + // This incents ChooserTargetServices to define what's truly better. + targetScore = lastScore * 0.95f; + } + insertServiceTarget(new ChooserTargetInfo(origTarget, target, targetScore)); + + if (DEBUG) { + Log.d(TAG, " => " + target.toString() + " score=" + targetScore + + " base=" + target.getScore() + + " lastScore=" + lastScore + + " parentScore=" + parentScore + + " lateFee=" + mLateFee); + } + + lastScore = targetScore; } - // TODO: Maintain sort by ranking scores. + mLateFee *= 0.95f; notifyDataSetChanged(); } + private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) { + final float newScore = chooserTargetInfo.getModifiedScore(); + for (int i = 0, N = mServiceTargets.size(); i < N; i++) { + final ChooserTargetInfo serviceTarget = mServiceTargets.get(i); + if (newScore > serviceTarget.getModifiedScore()) { + mServiceTargets.add(i, chooserTargetInfo); + return; + } + } + mServiceTargets.add(chooserTargetInfo); + } + private void pruneServiceTargets() { if (DEBUG) Log.d(TAG, "pruneServiceTargets"); for (int i = mServiceTargets.size() - 1; i >= 0; i--) { @@ -795,6 +849,14 @@ public class ChooserActivity extends ResolverActivity { } } + static class BaseChooserTargetComparator implements Comparator<ChooserTarget> { + @Override + public int compare(ChooserTarget lhs, ChooserTarget rhs) { + // Descending order + return (int) Math.signum(lhs.getScore() - rhs.getScore()); + } + } + class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index e5ff51c4822b..7bc18f39c8af 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -1142,6 +1142,10 @@ public class ResolverActivity extends Activity { return mFilterLastUsed && mLastChosenPosition >= 0; } + public float getScore(DisplayResolveInfo target) { + return mResolverComparator.getScore(target.getResolvedComponentName()); + } + private void rebuildList() { List<ResolvedComponentInfo> currentResolveList = null; diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java index 585cdf163b8c..31556e29bc32 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverComparator.java @@ -191,6 +191,14 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { return mCollator.compare(sa.toString().trim(), sb.toString().trim()); } + public float getScore(ComponentName name) { + final ScoredTarget target = mScoredTargets.get(name); + if (target != null) { + return target.score; + } + return 0; + } + static class ScoredTarget { public final ComponentInfo componentInfo; public float score; diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 1071e12cb6e3..fc9a1a50801e 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -231,7 +231,7 @@ public class ResolverDrawerLayout extends ViewGroup { mInitialTouchY = mLastTouchY = y; mActivePointerId = ev.getPointerId(0); final boolean hitView = findChildUnder(mInitialTouchX, mInitialTouchY) != null; - handled = (!hitView && mOnDismissedListener != null) || mCollapsibleHeight > 0; + handled = mOnDismissedListener != null || mCollapsibleHeight > 0; mIsDragging = hitView && handled; abortAnimation(); } |