diff options
3 files changed, 100 insertions, 22 deletions
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 94be25f00e4c..fcb32d54122c 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -117,12 +117,18 @@ import com.google.android.collect.Lists; import java.io.IOException; import java.lang.annotation.Retention; +import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +/** + * The Chooser Activity handles intent resolution specifically for sharing intents - + * for example, those generated by @see android.content.Intent#createChooser(Intent, CharSequence). + * + */ public class ChooserActivity extends ResolverActivity { private static final String TAG = "ChooserActivity"; @@ -200,6 +206,8 @@ public class ChooserActivity extends ResolverActivity { /** {@link ChooserActivity#getBaseScore} */ private static final float SHORTCUT_TARGET_SCORE_BOOST = 10.f; private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment"; + // TODO: Update to handle landscape instead of using static value + private static final int MAX_RANKED_TARGETS = 4; private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>(); @@ -216,6 +224,7 @@ public class ChooserActivity extends ResolverActivity { private boolean mListViewDataChanged = false; + @Retention(SOURCE) @IntDef({CONTENT_PREVIEW_FILE, CONTENT_PREVIEW_IMAGE, CONTENT_PREVIEW_TEXT}) private @interface ContentPreviewType { @@ -228,6 +237,9 @@ public class ChooserActivity extends ResolverActivity { private static final int CONTENT_PREVIEW_TEXT = 3; protected MetricsLogger mMetricsLogger; + // Sorted list of DisplayResolveInfos for the alphabetical app section. + private List<ResolverActivity.DisplayResolveInfo> mSortedList = new ArrayList<>(); + private final Handler mChooserHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -1405,6 +1417,30 @@ public class ChooserActivity extends ResolverActivity { } } + private void updateAlphabeticalList() { + if (getDisplayList().size() > MAX_RANKED_TARGETS) { + mSortedList.clear(); + mSortedList.addAll(getDisplayList()); + Collections.sort(mSortedList, new AzInfoComparator(ChooserActivity.this)); + } + } + + /** + * Sort intents alphabetically based on display label. + */ + class AzInfoComparator implements Comparator<ResolverActivity.DisplayResolveInfo> { + Collator mCollator; + AzInfoComparator(Context context) { + mCollator = Collator.getInstance(context.getResources().getConfiguration().locale); + } + + @Override + public int compare(ResolverActivity.DisplayResolveInfo lhsp, + ResolverActivity.DisplayResolveInfo rhsp) { + return mCollator.compare(lhsp.getDisplayLabel(), rhsp.getDisplayLabel()); + } + } + protected MetricsLogger getMetricsLogger() { if (mMetricsLogger == null) { mMetricsLogger = new MetricsLogger(); @@ -1451,7 +1487,8 @@ public class ChooserActivity extends ResolverActivity { mPm, getTargetIntent(), getReferrerPackageName(), - mLaunchedFromUid); + mLaunchedFromUid + ); } @VisibleForTesting @@ -1974,6 +2011,7 @@ public class ChooserActivity extends ResolverActivity { queryTargetServices(this); } + updateAlphabeticalList(); } @Override @@ -1983,13 +2021,17 @@ public class ChooserActivity extends ResolverActivity { @Override public int getCount() { - return super.getCount() + getSelectableServiceTargetCount() + getCallerTargetCount(); + return getStandardTargetCount() + getAlphaTargetCount() + + getSelectableServiceTargetCount() + getCallerTargetCount(); } @Override public int getUnfilteredCount() { - return super.getUnfilteredCount() + getSelectableServiceTargetCount() - + getCallerTargetCount(); + int appTargets = super.getUnfilteredCount(); + if (appTargets > MAX_RANKED_TARGETS) { + appTargets = appTargets + MAX_RANKED_TARGETS; + } + return appTargets + getSelectableServiceTargetCount() + getCallerTargetCount(); } public int getCallerTargetCount() { @@ -2018,7 +2060,13 @@ public class ChooserActivity extends ResolverActivity { } public int getStandardTargetCount() { - return super.getCount(); + int standardCount = super.getCount(); + return standardCount > MAX_RANKED_TARGETS ? MAX_RANKED_TARGETS : standardCount; + } + + int getAlphaTargetCount() { + int standardCount = super.getCount(); + return standardCount > MAX_RANKED_TARGETS ? standardCount : 0; } public int getPositionTargetType(int position) { @@ -2036,7 +2084,7 @@ public class ChooserActivity extends ResolverActivity { } offset += callerTargetCount; - final int standardTargetCount = super.getCount(); + final int standardTargetCount = getStandardTargetCount(); if (position - offset < standardTargetCount) { return TARGET_STANDARD; } @@ -2049,10 +2097,17 @@ public class ChooserActivity extends ResolverActivity { return targetInfoForPosition(position, true); } + + /** + * Find target info for a given position. + * Since ChooserActivity displays several sections of content, determine which + * section provides this item. + */ @Override public TargetInfo targetInfoForPosition(int position, boolean filtered) { int offset = 0; + // Direct share targets final int serviceTargetCount = filtered ? getServiceTargetCount() : getSelectableServiceTargetCount(); if (position < serviceTargetCount) { @@ -2060,16 +2115,32 @@ public class ChooserActivity extends ResolverActivity { } offset += serviceTargetCount; + // Targets provided by calling app final int callerTargetCount = getCallerTargetCount(); if (position - offset < callerTargetCount) { return mCallerTargets.get(position - offset); } offset += callerTargetCount; - return filtered ? super.getItem(position - offset) - : getDisplayResolveInfo(position - offset); + // Ranked app targets + if (position - offset < MAX_RANKED_TARGETS) { + return filtered ? super.getItem(position - offset) + : getDisplayResolveInfo(position - offset); + } + offset += MAX_RANKED_TARGETS; + + // Alphabetical complete app target list. + Log.e(TAG, mSortedList.toString()); + if (position - offset < mSortedList.size()) { + return mSortedList.get(position - offset); + } + + return null; + } + + /** * Evaluate targets for inclusion in the direct share area. May not be included * if score is too low. @@ -2100,6 +2171,9 @@ public class ChooserActivity extends ResolverActivity { final float baseScore = getBaseScore(origTarget, isShortcutResult); Collections.sort(targets, mBaseTargetComparator); + + + float lastScore = 0; boolean shouldNotify = false; for (int i = 0, N = Math.min(targets.size(), MAX_TARGETS_PER_SERVICE); i < N; i++) { @@ -2204,6 +2278,7 @@ public class ChooserActivity extends ResolverActivity { } } + private boolean isSendAction(Intent targetIntent) { if (targetIntent == null) { return false; @@ -2299,6 +2374,9 @@ public class ChooserActivity extends ResolverActivity { + Math.ceil( (float) mChooserListAdapter.getStandardTargetCount() / getMaxTargetsPerRow()) + + Math.ceil( + (float) mChooserListAdapter.getAlphaTargetCount() + / getMaxTargetsPerRow()) ); } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index f671a753493e..47b965d2e245 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -1424,6 +1424,11 @@ public class ResolverActivity extends Activity { activity.startActivityAsUser(mResolvedIntent, options, user); return false; } + + } + + List<DisplayResolveInfo> getDisplayList() { + return mAdapter.mDisplayList; } /** @@ -1523,12 +1528,12 @@ public class ResolverActivity extends Activity { private final List<ResolveInfo> mBaseResolveList; protected ResolveInfo mLastChosen; private DisplayResolveInfo mOtherProfile; - private boolean mHasExtendedInfo; private ResolverListController mResolverListController; private int mPlaceholderCount; protected final LayoutInflater mInflater; + // This one is the list that the Adapter will actually present. List<DisplayResolveInfo> mDisplayList; List<ResolvedComponentInfo> mUnfilteredResolveList; @@ -1709,6 +1714,7 @@ public class ResolverActivity extends Activity { } } + private void processSortedList(List<ResolvedComponentInfo> sortedComponents) { int N; if (sortedComponents != null && (N = sortedComponents.size()) != 0) { @@ -1746,6 +1752,7 @@ public class ResolverActivity extends Activity { } } + for (ResolvedComponentInfo rci : sortedComponents) { final ResolveInfo ri = rci.getResolveInfoAt(0); if (ri != null) { @@ -1755,9 +1762,12 @@ public class ResolverActivity extends Activity { } } + postListReadyRunnable(); } + + /** * Some necessary methods for creating the list are initiated in onCreate and will also * determine the layout known. We therefore can't update the UI inline and post to the @@ -1891,19 +1901,6 @@ public class ResolverActivity extends Activity { return position; } - public boolean hasExtendedInfo() { - return mHasExtendedInfo; - } - - public boolean hasResolvedTarget(ResolveInfo info) { - for (int i = 0, N = mDisplayList.size(); i < N; i++) { - if (resolveInfoMatch(info, mDisplayList.get(i).getResolveInfo())) { - return true; - } - } - return false; - } - public int getDisplayResolveInfoCount() { return mDisplayList.size(); } @@ -1969,6 +1966,7 @@ public class ResolverActivity extends Activity { } } + @VisibleForTesting public static final class ResolvedComponentInfo { public final ComponentName name; diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 156baf03f563..d12c51b56b46 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -253,6 +253,7 @@ public class ResolverListController { isComputed = true; } Collections.sort(inputList, mResolverComparator); + long afterRank = System.currentTimeMillis(); if (DEBUG) { Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank)); @@ -262,6 +263,7 @@ public class ResolverListController { } } + private static boolean isSameResolvedComponent(ResolveInfo a, ResolverActivity.ResolvedComponentInfo b) { final ActivityInfo ai = a.activityInfo; |