Loading core/java/com/android/internal/app/ChooserActivity.java +86 −8 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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<>(); Loading @@ -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 { Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -1451,7 +1487,8 @@ public class ChooserActivity extends ResolverActivity { mPm, getTargetIntent(), getReferrerPackageName(), mLaunchedFromUid); mLaunchedFromUid ); } @VisibleForTesting Loading Loading @@ -1974,6 +2011,7 @@ public class ChooserActivity extends ResolverActivity { queryTargetServices(this); } updateAlphabeticalList(); } @Override Loading @@ -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() { Loading Loading @@ -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) { Loading @@ -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; } Loading @@ -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) { Loading @@ -2060,15 +2115,31 @@ 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; // 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 Loading Loading @@ -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++) { Loading Loading @@ -2204,6 +2278,7 @@ public class ChooserActivity extends ResolverActivity { } } private boolean isSendAction(Intent targetIntent) { if (targetIntent == null) { return false; Loading Loading @@ -2299,6 +2374,9 @@ public class ChooserActivity extends ResolverActivity { + Math.ceil( (float) mChooserListAdapter.getStandardTargetCount() / getMaxTargetsPerRow()) + Math.ceil( (float) mChooserListAdapter.getAlphaTargetCount() / getMaxTargetsPerRow()) ); } Loading core/java/com/android/internal/app/ResolverActivity.java +12 −14 Original line number Diff line number Diff line Loading @@ -1424,6 +1424,11 @@ public class ResolverActivity extends Activity { activity.startActivityAsUser(mResolvedIntent, options, user); return false; } } List<DisplayResolveInfo> getDisplayList() { return mAdapter.mDisplayList; } /** Loading Loading @@ -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; Loading Loading @@ -1709,6 +1714,7 @@ public class ResolverActivity extends Activity { } } private void processSortedList(List<ResolvedComponentInfo> sortedComponents) { int N; if (sortedComponents != null && (N = sortedComponents.size()) != 0) { Loading Loading @@ -1746,6 +1752,7 @@ public class ResolverActivity extends Activity { } } for (ResolvedComponentInfo rci : sortedComponents) { final ResolveInfo ri = rci.getResolveInfoAt(0); if (ri != null) { Loading @@ -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 Loading Loading @@ -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(); } Loading Loading @@ -1969,6 +1966,7 @@ public class ResolverActivity extends Activity { } } @VisibleForTesting public static final class ResolvedComponentInfo { public final ComponentName name; Loading core/java/com/android/internal/app/ResolverListController.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -262,6 +263,7 @@ public class ResolverListController { } } private static boolean isSameResolvedComponent(ResolveInfo a, ResolverActivity.ResolvedComponentInfo b) { final ActivityInfo ai = a.activityInfo; Loading Loading
core/java/com/android/internal/app/ChooserActivity.java +86 −8 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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<>(); Loading @@ -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 { Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -1451,7 +1487,8 @@ public class ChooserActivity extends ResolverActivity { mPm, getTargetIntent(), getReferrerPackageName(), mLaunchedFromUid); mLaunchedFromUid ); } @VisibleForTesting Loading Loading @@ -1974,6 +2011,7 @@ public class ChooserActivity extends ResolverActivity { queryTargetServices(this); } updateAlphabeticalList(); } @Override Loading @@ -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() { Loading Loading @@ -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) { Loading @@ -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; } Loading @@ -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) { Loading @@ -2060,15 +2115,31 @@ 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; // 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 Loading Loading @@ -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++) { Loading Loading @@ -2204,6 +2278,7 @@ public class ChooserActivity extends ResolverActivity { } } private boolean isSendAction(Intent targetIntent) { if (targetIntent == null) { return false; Loading Loading @@ -2299,6 +2374,9 @@ public class ChooserActivity extends ResolverActivity { + Math.ceil( (float) mChooserListAdapter.getStandardTargetCount() / getMaxTargetsPerRow()) + Math.ceil( (float) mChooserListAdapter.getAlphaTargetCount() / getMaxTargetsPerRow()) ); } Loading
core/java/com/android/internal/app/ResolverActivity.java +12 −14 Original line number Diff line number Diff line Loading @@ -1424,6 +1424,11 @@ public class ResolverActivity extends Activity { activity.startActivityAsUser(mResolvedIntent, options, user); return false; } } List<DisplayResolveInfo> getDisplayList() { return mAdapter.mDisplayList; } /** Loading Loading @@ -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; Loading Loading @@ -1709,6 +1714,7 @@ public class ResolverActivity extends Activity { } } private void processSortedList(List<ResolvedComponentInfo> sortedComponents) { int N; if (sortedComponents != null && (N = sortedComponents.size()) != 0) { Loading Loading @@ -1746,6 +1752,7 @@ public class ResolverActivity extends Activity { } } for (ResolvedComponentInfo rci : sortedComponents) { final ResolveInfo ri = rci.getResolveInfoAt(0); if (ri != null) { Loading @@ -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 Loading Loading @@ -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(); } Loading Loading @@ -1969,6 +1966,7 @@ public class ResolverActivity extends Activity { } } @VisibleForTesting public static final class ResolvedComponentInfo { public final ComponentName name; Loading
core/java/com/android/internal/app/ResolverListController.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -262,6 +263,7 @@ public class ResolverListController { } } private static boolean isSameResolvedComponent(ResolveInfo a, ResolverActivity.ResolvedComponentInfo b) { final ActivityInfo ai = a.activityInfo; Loading