From 510a818521f38aeaac31897b0531235e7e0bb196 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Wed, 30 Mar 2022 17:46:09 +0000 Subject: [PATCH] Show an 'Undo' snackbar when users dismiss a predicted hotseat item. Bug: 200841778 Test: Hard-coded the flag to be true, and verified that the snack bar is shown with the correct text. Also verified that talkback announces "Item Removed" properly and that the correct log event is produced by the AppEventProducer which AiAi needs to process the user action. Change-Id: Ifbb9cf7aecf26cd4bcebf48d4fb07fb3d5af46bb --- .../launcher3/model/AppEventProducer.java | 4 ++++ .../launcher3/SecondaryDropTarget.java | 23 +++++++++++++++---- .../launcher3/config/FeatureFlags.java | 4 ++++ .../launcher3/logging/StatsLogManager.java | 5 +++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java index 3f29e433d9..5c669441c7 100644 --- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java +++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java @@ -18,6 +18,7 @@ package com.android.launcher3.model; import static android.app.prediction.AppTargetEvent.ACTION_DISMISS; import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH; import static android.app.prediction.AppTargetEvent.ACTION_PIN; +import static android.app.prediction.AppTargetEvent.ACTION_UNDISMISS; import static android.app.prediction.AppTargetEvent.ACTION_UNPIN; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; @@ -25,6 +26,7 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICT import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION; import static com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers.ContainerCase.DEVICE_SEARCH_RESULT_CONTAINER; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED; @@ -176,6 +178,8 @@ public class AppEventProducer implements StatsLogConsumer { mContext.getPackageName(), Process.myUserHandle()) .build(); sendEvent(target, atomInfo, ACTION_LAUNCH, CONTAINER_PREDICTION); + } else if (event == LAUNCHER_DISMISS_PREDICTION_UNDO) { + sendEvent(atomInfo, ACTION_UNDISMISS, CONTAINER_HOTSEAT_PREDICTION); } } diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java index cd06414d3f..5b037e4db8 100644 --- a/src/com/android/launcher3/SecondaryDropTarget.java +++ b/src/com/android/launcher3/SecondaryDropTarget.java @@ -8,6 +8,7 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION; import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE; import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.UNINSTALL; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_UNINSTALL; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_UNINSTALL_CANCELLED; @@ -46,6 +47,7 @@ import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PendingRequestArgs; +import com.android.launcher3.views.Snackbar; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import java.net.URISyntaxException; @@ -220,7 +222,8 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList @Override public void completeDrop(final DragObject d) { - ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo); + ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo, + d.logInstanceId); if (d.dragSource instanceof DeferredOnComplete) { DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource; if (target != null) { @@ -264,7 +267,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList * Performs the drop action and returns the target component for the dragObject or null if * the action was not performed. */ - protected ComponentName performDropAction(View view, ItemInfo info) { + protected ComponentName performDropAction(View view, ItemInfo info, InstanceId instanceId) { if (mCurrentAccessibilityAction == RECONFIGURE) { int widgetId = getReconfigurableWidgetId(view); if (widgetId != INVALID_APPWIDGET_ID) { @@ -276,7 +279,16 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList return null; } if (mCurrentAccessibilityAction == DISMISS_PREDICTION) { - // We sent the log event, nothing else left to do + if (FeatureFlags.ENABLE_DISMISS_PREDICTION_UNDO.get()) { + mLauncher.getDragLayer() + .announceForAccessibility(getContext().getString(R.string.item_removed)); + Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, () -> { }, () -> { + mStatsLogManager.logger() + .withInstanceId(instanceId) + .withItemInfo(info) + .log(LAUNCHER_DISMISS_PREDICTION_UNDO); + }); + } return null; } // else: mCurrentAccessibilityAction == UNINSTALL @@ -303,8 +315,9 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList @Override public void onAccessibilityDrop(View view, ItemInfo item) { - doLog(new InstanceIdSequence().newInstanceId(), item); - performDropAction(view, item); + InstanceId instanceId = new InstanceIdSequence().newInstanceId(); + doLog(instanceId, item); + performDropAction(view, item, instanceId); } /** diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 420180b049..626e15cbff 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -265,6 +265,10 @@ public final class FeatureFlags { "USE_LOCAL_ICON_OVERRIDES", true, "Use inbuilt monochrome icons if app doesn't provide one"); + public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag( + "ENABLE_DISMISS_PREDICTION_UNDO", false, + "Show an 'Undo' snackbar when users dismiss a predicted hotseat item"); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java index b8ecec1541..7e6f81cf49 100644 --- a/src/com/android/launcher3/logging/StatsLogManager.java +++ b/src/com/android/launcher3/logging/StatsLogManager.java @@ -579,7 +579,10 @@ public class StatsLogManager implements ResourceBasedOverride { LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS(1010), @UiEvent(doc = "User tapped taskbar a11y button") - LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS(1011); + LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS(1011), + + @UiEvent(doc = "Show an 'Undo' snackbar when users dismiss a predicted hotseat item") + LAUNCHER_DISMISS_PREDICTION_UNDO(1035); // ADD MORE