Merge "Sharesheet: Rank the first N apps, then show the rest alphabetically." into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-09 11:10:00 +00:00
committed by Android (Google) Code Review
3 changed files with 100 additions and 22 deletions

View File

@@ -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())
);
}

View File

@@ -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;

View File

@@ -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;