diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java index c00d16ca143e6..42fc7bd6e6fca 100644 --- a/core/java/com/android/internal/app/AbstractResolverComparator.java +++ b/core/java/com/android/internal/app/AbstractResolverComparator.java @@ -161,6 +161,11 @@ public abstract class AbstractResolverComparator implements Comparator 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(); + } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 85d27a1004f1a..91b4b7fb2ca1f 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -2035,6 +2035,7 @@ public class ResolverActivity extends Activity implements private final List mIntents = new ArrayList<>(); private final List 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, diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 10ac1bc6ac3d6..9a95e6411fa46 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -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. diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 06f68e8273f97..1b3fd7bbad652 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -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() { } } diff --git a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java index 03ed68cd1205e..04b8886237320 100644 --- a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java +++ b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java @@ -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(