diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 495a5fbb66657..6d0a8646b3a77 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -81,6 +81,12 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String SSIN_MAX_NUM_ACTIONS = "ssin_max_num_actions";
+ /**
+ * (int) The amount of time (ms) before smart suggestions are clickable, since the suggestions
+ * were added.
+ */
+ public static final String SSIN_ONCLICK_INIT_DELAY = "ssin_onclick_init_delay";
+
/**
* The default component of
* {@link android.service.notification.NotificationAssistantService}.
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index d6906f3988cda..73386879a20d7 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -469,6 +469,10 @@
-->
-1
+
+ 200
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index efdcd053bc54c..6b2efaab0a644 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -100,6 +100,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -3194,6 +3195,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mAmbientGoingAway = goingAway;
}
+ /**
+ * Returns the Smart Suggestions backing the smart suggestion buttons in the notification.
+ */
+ public SmartRepliesAndActions getExistingSmartRepliesAndActions() {
+ return mPrivateLayout.getCurrentSmartRepliesAndActions();
+ }
+
@VisibleForTesting
protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
mChildrenContainer = childrenContainer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 18dcf4c55d21e..396cd73f9a225 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -44,6 +44,7 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.InflatedSmartReplies;
+import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions;
import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.util.Assert;
@@ -282,7 +283,8 @@ public class NotificationContentInflater {
mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
mRedactAmbient, packageContext);
result = inflateSmartReplyViews(result, reInflateFlags, mRow.getEntry(),
- mRow.getContext(), mRow.getHeadsUpManager());
+ mRow.getContext(), mRow.getHeadsUpManager(),
+ mRow.getExistingSmartRepliesAndActions());
apply(
inflateSynchronously,
result,
@@ -344,20 +346,20 @@ public class NotificationContentInflater {
private static InflationProgress inflateSmartReplyViews(InflationProgress result,
@InflationFlag int reInflateFlags, NotificationEntry entry, Context context,
- HeadsUpManager headsUpManager) {
+ HeadsUpManager headsUpManager, SmartRepliesAndActions previousSmartRepliesAndActions) {
SmartReplyConstants smartReplyConstants = Dependency.get(SmartReplyConstants.class);
SmartReplyController smartReplyController = Dependency.get(SmartReplyController.class);
if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 && result.newExpandedView != null) {
result.expandedInflatedSmartReplies =
InflatedSmartReplies.inflate(
context, entry, smartReplyConstants, smartReplyController,
- headsUpManager);
+ headsUpManager, previousSmartRepliesAndActions);
}
if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0 && result.newHeadsUpView != null) {
result.headsUpInflatedSmartReplies =
InflatedSmartReplies.inflate(
context, entry, smartReplyConstants, smartReplyController,
- headsUpManager);
+ headsUpManager, previousSmartRepliesAndActions);
}
return result;
}
@@ -905,7 +907,8 @@ public class NotificationContentInflater {
mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
mRedactAmbient, packageContext);
return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mRow.getEntry(),
- mRow.getContext(), mRow.getHeadsUpManager());
+ mRow.getContext(), mRow.getHeadsUpManager(),
+ mRow.getExistingSmartRepliesAndActions());
} catch (Exception e) {
mError = e;
return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 78500357f41f3..b81d81438ea39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -93,6 +93,7 @@ public class NotificationContentView extends FrameLayout {
private SmartReplyController mSmartReplyController;
private InflatedSmartReplies mExpandedInflatedSmartReplies;
private InflatedSmartReplies mHeadsUpInflatedSmartReplies;
+ private SmartRepliesAndActions mCurrentSmartRepliesAndActions;
private NotificationViewWrapper mContractedWrapper;
private NotificationViewWrapper mExpandedWrapper;
@@ -1259,18 +1260,18 @@ public class NotificationContentView extends FrameLayout {
// the same SmartRepliesAndActions to avoid discrepancies between the two views. We here
// reuse that object for our local SmartRepliesAndActions to avoid discrepancies between
// this class and the InflatedSmartReplies classes.
- SmartRepliesAndActions smartRepliesAndActions = mExpandedInflatedSmartReplies != null
+ mCurrentSmartRepliesAndActions = mExpandedInflatedSmartReplies != null
? mExpandedInflatedSmartReplies.getSmartRepliesAndActions()
: mHeadsUpInflatedSmartReplies.getSmartRepliesAndActions();
if (DEBUG) {
Log.d(TAG, String.format("Adding suggestions for %s, %d actions, and %d replies.",
entry.notification.getKey(),
- smartRepliesAndActions.smartActions == null ? 0 :
- smartRepliesAndActions.smartActions.actions.size(),
- smartRepliesAndActions.smartReplies == null ? 0 :
- smartRepliesAndActions.smartReplies.choices.length));
+ mCurrentSmartRepliesAndActions.smartActions == null ? 0 :
+ mCurrentSmartRepliesAndActions.smartActions.actions.size(),
+ mCurrentSmartRepliesAndActions.smartReplies == null ? 0 :
+ mCurrentSmartRepliesAndActions.smartReplies.choices.length));
}
- applySmartReplyView(smartRepliesAndActions, entry);
+ applySmartReplyView(mCurrentSmartRepliesAndActions, entry);
}
private void applyRemoteInput(NotificationEntry entry, boolean hasFreeformRemoteInput) {
@@ -1472,6 +1473,13 @@ public class NotificationContentView extends FrameLayout {
}
}
+ /**
+ * Returns the smart replies and actions currently shown in the notification.
+ */
+ @Nullable public SmartRepliesAndActions getCurrentSmartRepliesAndActions() {
+ return mCurrentSmartRepliesAndActions;
+ }
+
public void closeRemoteInput() {
if (mHeadsUpRemoteInput != null) {
mHeadsUpRemoteInput.close();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
index 5b2e398b66e14..ee78a723a49c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
@@ -28,15 +28,19 @@ import android.util.Log;
import android.util.Pair;
import android.widget.Button;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.systemui.Dependency;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -79,29 +83,52 @@ public class InflatedSmartReplies {
NotificationEntry entry,
SmartReplyConstants smartReplyConstants,
SmartReplyController smartReplyController,
- HeadsUpManager headsUpManager) {
- SmartRepliesAndActions smartRepliesAndActions =
+ HeadsUpManager headsUpManager,
+ SmartRepliesAndActions existingSmartRepliesAndActions) {
+ SmartRepliesAndActions newSmartRepliesAndActions =
chooseSmartRepliesAndActions(smartReplyConstants, entry);
- if (!shouldShowSmartReplyView(entry, smartRepliesAndActions)) {
+ if (!shouldShowSmartReplyView(entry, newSmartRepliesAndActions)) {
return new InflatedSmartReplies(null /* smartReplyView */,
- null /* smartSuggestionButtons */, smartRepliesAndActions);
+ null /* smartSuggestionButtons */, newSmartRepliesAndActions);
}
+ // Only block clicks if the smart buttons are different from the previous set - to avoid
+ // scenarios where a user incorrectly cannot click smart buttons because the notification is
+ // updated.
+ boolean delayOnClickListener =
+ !areSuggestionsSimilar(existingSmartRepliesAndActions, newSmartRepliesAndActions);
+
SmartReplyView smartReplyView = SmartReplyView.inflate(context);
List