Show nearby share as normal app target and in first item always

Show nearby share as a normal app target instead of action button. And
always put it as the first item in App prediction Row. The change is
gaurded by lowRamDevice flag and experiment flag. by default, there is
no change to current behavior. One needs to run command 'adb shell
device_config put systemui is_nearby_share_first_target_in_ranked_app true' on
Android Go devices to see the effect.

Bug: 197241083
Test: atest ResolverListControllerTest
Test: atest AbstractResolverComparatorTest
Test: atest ResolverActivityTest
Test: atest ChooserActivityTest (no new failure)

Change-Id: I22106e382e0d96fc760e4a9fb94be3ae293c8497
This commit is contained in:
Zhen Zhang
2021-08-10 22:30:39 -07:00
committed by Mark White
parent 1ab3bdf551
commit 8077327624
6 changed files with 89 additions and 11 deletions

View File

@@ -161,6 +161,11 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
final boolean lFixedAtTop = lhsp.isFixedAtTop();
final boolean rFixedAtTop = rhsp.isFixedAtTop();
if (lFixedAtTop && !rFixedAtTop) return -1;
if (!lFixedAtTop && rFixedAtTop) return 1;
// We want to put the one targeted to another user at the end of the dialog.
if (lhs.targetUserId != UserHandle.USER_CURRENT) {
return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;

View File

@@ -240,6 +240,12 @@ public class ChooserActivity extends ResolverActivity implements
SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
DEFAULT_SALT_EXPIRATION_DAYS);
private static final boolean DEFAULT_IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP = false;
private boolean mIsNearbyShareFirstTargetInRankedApp =
DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP,
DEFAULT_IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP);
private Bundle mReplacementExtras;
private IntentSender mChosenComponentSender;
private IntentSender mRefinementIntentSender;
@@ -600,10 +606,11 @@ public class ChooserActivity extends ResolverActivity implements
// Exclude out Nearby from main list if chip is present, to avoid duplication
ComponentName nearbySharingComponent = getNearbySharingComponent();
boolean hasNearby = nearbySharingComponent != null;
boolean shouldFilterNearby = !shouldNearbyShareBeFirstInRankedRow()
&& nearbySharingComponent != null;
if (pa != null) {
ComponentName[] names = new ComponentName[pa.length + (hasNearby ? 1 : 0)];
ComponentName[] names = new ComponentName[pa.length + (shouldFilterNearby ? 1 : 0)];
for (int i = 0; i < pa.length; i++) {
if (!(pa[i] instanceof ComponentName)) {
Log.w(TAG, "Filtered component #" + i + " not a ComponentName: " + pa[i]);
@@ -612,12 +619,12 @@ public class ChooserActivity extends ResolverActivity implements
}
names[i] = (ComponentName) pa[i];
}
if (hasNearby) {
if (shouldFilterNearby) {
names[names.length - 1] = nearbySharingComponent;
}
mFilteredComponentNames = names;
} else if (hasNearby) {
} else if (shouldFilterNearby) {
mFilteredComponentNames = new ComponentName[1];
mFilteredComponentNames[0] = nearbySharingComponent;
}
@@ -1240,7 +1247,9 @@ public class ChooserActivity extends ResolverActivity implements
final ViewGroup actionRow =
(ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
addActionButton(actionRow, createCopyButton());
addActionButton(actionRow, createNearbyButton(targetIntent));
if (shouldNearbyShareBeIncludedAsActionButton()) {
addActionButton(actionRow, createNearbyButton(targetIntent));
}
CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
if (sharingText == null) {
@@ -1291,7 +1300,9 @@ public class ChooserActivity extends ResolverActivity implements
final ViewGroup actionRow =
(ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
//TODO: addActionButton(actionRow, createCopyButton());
addActionButton(actionRow, createNearbyButton(targetIntent));
if (shouldNearbyShareBeIncludedAsActionButton()) {
addActionButton(actionRow, createNearbyButton(targetIntent));
}
addActionButton(actionRow, createEditButton(targetIntent));
mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
@@ -1411,8 +1422,9 @@ public class ChooserActivity extends ResolverActivity implements
final ViewGroup actionRow =
(ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
//TODO(b/120417119): addActionButton(actionRow, createCopyButton());
addActionButton(actionRow, createNearbyButton(targetIntent));
if (shouldNearbyShareBeIncludedAsActionButton()) {
addActionButton(actionRow, createNearbyButton(targetIntent));
}
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
@@ -1713,7 +1725,6 @@ public class ChooserActivity extends ResolverActivity implements
super.startSelected(which, always, filtered);
if (currentListAdapter.getCount() > 0) {
// Log the index of which type of target the user picked.
// Lower values mean the ranking was better.
@@ -2303,6 +2314,12 @@ public class ChooserActivity extends ResolverActivity implements
public boolean isComponentPinned(ComponentName name) {
return mPinnedSharedPrefs.getBoolean(name.flattenToString(), false);
}
@Override
public boolean isFixedAtTop(ComponentName name) {
return name != null && name.equals(getNearbySharingComponent())
&& shouldNearbyShareBeFirstInRankedRow();
}
}
@VisibleForTesting
@@ -2838,7 +2855,7 @@ public class ChooserActivity extends ResolverActivity implements
.targetInfoForPosition(mListPosition, /* filtered */ true);
// This should always be the case for ItemViewHolder, check for validity
if (ti instanceof DisplayResolveInfo) {
if (ti instanceof DisplayResolveInfo && shouldShowTargetDetails(ti)) {
showTargetDetails((DisplayResolveInfo) ti);
}
return true;
@@ -2847,6 +2864,13 @@ public class ChooserActivity extends ResolverActivity implements
}
}
private boolean shouldShowTargetDetails(TargetInfo ti) {
ComponentName nearbyShare = getNearbySharingComponent();
// Suppress target details for nearby share to hide pin/unpin action
return !(nearbyShare != null && nearbyShare.equals(ti.getResolvedComponentName())
&& shouldNearbyShareBeFirstInRankedRow());
}
/**
* Add a footer to the list, to support scrolling behavior below the navbar.
*/
@@ -3212,7 +3236,7 @@ public class ChooserActivity extends ResolverActivity implements
final TargetInfo ti = mChooserListAdapter.targetInfoForPosition(
holder.getItemIndex(column), true);
// This should always be the case for non-DS targets, check for validity
if (ti instanceof DisplayResolveInfo) {
if (ti instanceof DisplayResolveInfo && shouldShowTargetDetails(ti)) {
showTargetDetails((DisplayResolveInfo) ti);
}
return true;
@@ -3861,4 +3885,12 @@ public class ChooserActivity extends ResolverActivity implements
protected void maybeLogProfileChange() {
getChooserActivityLogger().logShareheetProfileChanged();
}
private boolean shouldNearbyShareBeFirstInRankedRow() {
return ActivityManager.isLowRamDeviceStatic() && mIsNearbyShareFirstTargetInRankedApp;
}
private boolean shouldNearbyShareBeIncludedAsActionButton() {
return !shouldNearbyShareBeFirstInRankedRow();
}
}

View File

@@ -2035,6 +2035,7 @@ public class ResolverActivity extends Activity implements
private final List<Intent> mIntents = new ArrayList<>();
private final List<ResolveInfo> mResolveInfos = new ArrayList<>();
private boolean mPinned;
private boolean mFixedAtTop;
public ResolvedComponentInfo(ComponentName name, Intent intent, ResolveInfo info) {
this.name = name;
@@ -2083,6 +2084,14 @@ public class ResolverActivity extends Activity implements
public void setPinned(boolean pinned) {
mPinned = pinned;
}
public boolean isFixedAtTop() {
return mFixedAtTop;
}
public void setFixedAtTop(boolean isFixedAtTop) {
mFixedAtTop = isFixedAtTop;
}
}
class ItemClickListener implements AdapterView.OnItemClickListener,

View File

@@ -181,6 +181,7 @@ public class ResolverListController {
final ResolverActivity.ResolvedComponentInfo rci =
new ResolverActivity.ResolvedComponentInfo(name, intent, newInfo);
rci.setPinned(isComponentPinned(name));
rci.setFixedAtTop(isFixedAtTop(name));
into.add(rci);
}
}
@@ -195,6 +196,14 @@ public class ResolverListController {
return false;
}
/**
* Whether this component is fixed at top in the ranked apps list. Always false for Resolver;
* overridden in Chooser.
*/
public boolean isFixedAtTop(ComponentName name) {
return false;
}
// Filter out any activities that the launched uid does not have permission for.
// To preserve the inputList, optionally will return the original list if any modification has
// been made.

View File

@@ -495,6 +495,12 @@ public final class SystemUiDeviceConfigFlags {
public static final String SHORTCUT_APPSEARCH_INTEGRATION =
"shortcut_appsearch_integration";
/**
* (boolean) Whether nearby share should be the first target in ranked apps.
*/
public static final String IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP =
"is_nearby_share_first_target_in_ranked_app";
private SystemUiDeviceConfigFlags() {
}
}

View File

@@ -33,6 +33,23 @@ import java.util.List;
public class AbstractResolverComparatorTest {
@Test
public void testPositionFixed() {
ResolverActivity.ResolvedComponentInfo r1 = new ResolverActivity.ResolvedComponentInfo(
new ComponentName("package", "class"), new Intent(), new ResolveInfo()
);
r1.setFixedAtTop(true);
ResolverActivity.ResolvedComponentInfo r2 = new ResolverActivity.ResolvedComponentInfo(
new ComponentName("zackage", "zlass"), new Intent(), new ResolveInfo()
);
r2.setPinned(true);
Context context = InstrumentationRegistry.getTargetContext();
AbstractResolverComparator comparator = getTestComparator(context);
assertEquals("FixedAtTop ranks over pinned", -1, comparator.compare(r1, r2));
assertEquals("Pinned ranks under fixedAtTop", 1, comparator.compare(r2, r1));
}
@Test
public void testPinned() {
ResolverActivity.ResolvedComponentInfo r1 = new ResolverActivity.ResolvedComponentInfo(