From 6872117b988dbf42ab81f078c5c27f8182517d0a Mon Sep 17 00:00:00 2001 From: Andrey Yepin Date: Mon, 12 Aug 2024 10:53:47 -0700 Subject: Fix direct share row flashing upon Shareousel selection change. Upon payload selection change, copy direct share targets into the new adapters but keep the items disabled until the new set of shortcuts is loaded. To have all targets updated at once, publish the caller-provided targets together with the remaining direct shares. Fix: 343300158 Test: manual testing: using the ShareTest app, launch the Shareousel with a caller-provided targets and make the payload selection. Flag: com.android.intentresolver.fix_shortcuts_flashing Change-Id: Iff5ea6c892708daa9cca968a56a03aaaf80196f6 --- .../android/intentresolver/ChooserActivity.java | 24 ++++++++++++++- .../android/intentresolver/ChooserListAdapter.java | 35 ++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) (limited to 'java/src') diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index cc8e3a11..51d8785f 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -24,6 +24,7 @@ import static androidx.lifecycle.LifecycleKt.getCoroutineScope; import static com.android.intentresolver.ChooserActionFactory.EDIT_SOURCE; import static com.android.intentresolver.Flags.shareouselUpdateExcludeComponentsExtra; +import static com.android.intentresolver.Flags.fixShortcutsFlashing; import static com.android.intentresolver.ext.CreationExtrasExtKt.addDefaultArgs; import static com.android.intentresolver.profiles.MultiProfilePagerAdapter.PROFILE_PERSONAL; import static com.android.intentresolver.profiles.MultiProfilePagerAdapter.PROFILE_WORK; @@ -785,6 +786,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements } // Update the pager adapter but do not attach it to the view till the targets are reloaded, // see onChooserAppTargetsLoaded method. + ChooserMultiProfilePagerAdapter oldPagerAdapter = + mChooserMultiProfilePagerAdapter; mChooserMultiProfilePagerAdapter = createMultiProfilePagerAdapter( /* context = */ this, mProfilePagerResources, @@ -824,6 +827,19 @@ public class ChooserActivity extends Hilt_ChooserActivity implements postRebuildList( mChooserMultiProfilePagerAdapter.rebuildTabs( mProfiles.getWorkProfilePresent() || mProfiles.getPrivateProfilePresent())); + if (fixShortcutsFlashing() && oldPagerAdapter != null) { + for (int i = 0, count = mChooserMultiProfilePagerAdapter.getCount(); i < count; i++) { + ChooserListAdapter listAdapter = + mChooserMultiProfilePagerAdapter.getPageAdapterForIndex(i) + .getListAdapter(); + ChooserListAdapter oldListAdapter = + oldPagerAdapter.getListAdapterForUserHandle(listAdapter.getUserHandle()); + if (oldListAdapter != null) { + listAdapter.copyDirectTargetsFrom(oldListAdapter); + listAdapter.setDirectTargetsEnabled(false); + } + } + } setTabsViewEnabled(false); } @@ -2419,7 +2435,9 @@ public class ChooserActivity extends Hilt_ChooserActivity implements if (duration >= 0) { Log.d(TAG, "app target loading time " + duration + " ms"); } - addCallerChooserTargets(chooserListAdapter); + if (!fixShortcutsFlashing()) { + addCallerChooserTargets(chooserListAdapter); + } getEventLog().logSharesheetAppLoadComplete(); maybeQueryAdditionalPostProcessingTargets( listProfileUserHandle, @@ -2449,6 +2467,10 @@ public class ChooserActivity extends Hilt_ChooserActivity implements ChooserListAdapter adapter = mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(userHandle); if (adapter != null) { + if (fixShortcutsFlashing()) { + adapter.setDirectTargetsEnabled(true); + addCallerChooserTargets(adapter); + } for (ShortcutLoader.ShortcutResultInfo resultInfo : result.getShortcutsByApp()) { adapter.addServiceResults( resultInfo.getAppTarget(), diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java index 548cd6ac..26e2feeb 100644 --- a/java/src/com/android/intentresolver/ChooserListAdapter.java +++ b/java/src/com/android/intentresolver/ChooserListAdapter.java @@ -155,6 +155,7 @@ public class ChooserListAdapter extends ResolverListAdapter { private boolean mAnimateItems = true; private boolean mTargetsEnabled = true; + private boolean mDirectTargetsEnabled = true; public ChooserListAdapter( Context context, @@ -318,6 +319,18 @@ public class ChooserListAdapter extends ResolverListAdapter { } } + /** + * Set the enabled state for direct targets. + */ + public void setDirectTargetsEnabled(boolean isEnabled) { + if (mDirectTargetsEnabled != isEnabled) { + mDirectTargetsEnabled = isEnabled; + if (!mServiceTargets.isEmpty() && !isDirectTargetRowEmptyState()) { + notifyDataSetChanged(); + } + } + } + public void setAnimateItems(boolean animateItems) { mAnimateItems = animateItems; } @@ -365,7 +378,8 @@ public class ChooserListAdapter extends ResolverListAdapter { @VisibleForTesting @Override public void onBindView(View view, TargetInfo info, int position) { - view.setEnabled(!isDestroyed() && mTargetsEnabled); + final boolean isEnabled = !isDestroyed() && mTargetsEnabled; + view.setEnabled(isEnabled); final ViewHolder holder = (ViewHolder) view.getTag(); resetViewHolder(holder); @@ -390,6 +404,7 @@ public class ChooserListAdapter extends ResolverListAdapter { } if (info.isSelectableTargetInfo()) { + view.setEnabled(isEnabled && mDirectTargetsEnabled); // direct share targets should append the application name for a better readout DisplayResolveInfo rInfo = info.getDisplayResolveInfo(); CharSequence appName = @@ -747,7 +762,7 @@ public class ChooserListAdapter extends ResolverListAdapter { Map directShareToShortcutInfos, Map directShareToAppTargets) { // Avoid inserting any potentially late results. - if ((mServiceTargets.size() == 1) && mServiceTargets.get(0).isEmptyTargetInfo()) { + if (isDirectTargetRowEmptyState()) { return; } boolean isShortcutResult = targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER @@ -769,6 +784,22 @@ public class ChooserListAdapter extends ResolverListAdapter { } } + /** + * Copy direct targets from another ChooserListAdapter instance + */ + public void copyDirectTargetsFrom(ChooserListAdapter adapter) { + if (adapter.isDirectTargetRowEmptyState()) { + return; + } + + mServiceTargets.clear(); + mServiceTargets.addAll(adapter.mServiceTargets); + } + + private boolean isDirectTargetRowEmptyState() { + return (mServiceTargets.size() == 1) && mServiceTargets.get(0).isEmptyTargetInfo(); + } + /** * Use the scoring system along with artificial boosts to create up to 4 distinct buckets: *
    -- cgit v1.2.3-59-g8ed1b