Merge "Sharesheet: Rank the first N apps, then show the rest alphabetically." into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5a56c2d9cc
@@ -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())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user