Add Smart Suggestions to heads up notifications.

Add smart replies and actions to Heads-up notifications (HUN).

Note: only one line of text is shown in HUNs with messaging templates.
Thus the user might not see the full message to respond to even when the
smart replies/actions are displayed.

Screenshot: https://screenshot.googleplex.com/3R5GVZGXGNg.png

Bug: 117257685
Test: Use cinek@'s Notify app to display HUN with smart replies/actions.
Change-Id: I10d2c87b445de8f471ad0978829cede9ac6a6663
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 8214ea6..8bed366 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
@@ -1098,6 +1098,10 @@
         mHeadsUpManager = headsUpManager;
     }
 
+    public HeadsUpManager getHeadsUpManager() {
+        return mHeadsUpManager;
+    }
+
     public void setGutsView(MenuItem item) {
         if (mGuts != null && item.getGutsView() instanceof NotificationGuts.GutsContent) {
             ((NotificationGuts.GutsContent) item.getGutsView()).setGutsParent(mGuts);
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 689d6d5..edd54ca 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
@@ -91,6 +91,7 @@
 
     private SmartReplyConstants mSmartReplyConstants;
     private SmartReplyView mExpandedSmartReplyView;
+    private SmartReplyView mHeadsUpSmartReplyView;
     private SmartReplyController mSmartReplyController;
 
     private NotificationViewWrapper mContractedWrapper;
@@ -253,6 +254,9 @@
         }
         if (mHeadsUpChild != null) {
             int maxHeight = mHeadsUpHeight;
+            if (mHeadsUpSmartReplyView != null) {
+                maxHeight += mHeadsUpSmartReplyView.getHeightUpperLimit();
+            }
             maxHeight += mHeadsUpWrapper.getExtraMeasureHeight();
             int size = maxHeight;
             ViewGroup.LayoutParams layoutParams = mHeadsUpChild.getLayoutParams();
@@ -955,6 +959,9 @@
         if (mExpandedSmartReplyView != null) {
             mExpandedSmartReplyView.setBackgroundTintColor(color);
         }
+        if (mHeadsUpSmartReplyView != null) {
+            mHeadsUpSmartReplyView.setBackgroundTintColor(color);
+        }
     }
 
     public int getVisibleType() {
@@ -1472,6 +1479,10 @@
                         entry, smartRepliesAndActions.smartReplies.choices.length);
             }
         }
+        if (mHeadsUpChild != null) {
+            mHeadsUpSmartReplyView =
+                    applySmartReplyView(mHeadsUpChild, smartRepliesAndActions, entry);
+        }
     }
 
     private SmartReplyView applySmartReplyView(View view,
@@ -1520,7 +1531,8 @@
             }
             if (smartRepliesAndActions.smartActions != null) {
                 smartReplyView.addSmartActions(
-                        smartRepliesAndActions.smartActions, mSmartReplyController, entry);
+                        smartRepliesAndActions.smartActions, mSmartReplyController, entry,
+                        mContainingNotification.getHeadsUpManager());
             }
             smartReplyContainer.setVisibility(View.VISIBLE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 2a4336e..913b2ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -16,6 +16,8 @@
 import android.graphics.drawable.InsetDrawable;
 import android.graphics.drawable.RippleDrawable;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.text.Layout;
 import android.text.TextPaint;
 import android.text.method.TransformationMethod;
@@ -61,6 +63,7 @@
 
     private final SmartReplyConstants mConstants;
     private final KeyguardDismissUtil mKeyguardDismissUtil;
+    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
 
     /**
      * The upper bound for the height of this view in pixels. Notifications are automatically
@@ -209,13 +212,15 @@
      * notification are shown.
      */
     public void addSmartActions(SmartActions smartActions,
-            SmartReplyController smartReplyController, NotificationData.Entry entry) {
+            SmartReplyController smartReplyController, NotificationData.Entry entry,
+            HeadsUpManager headsUpManager) {
         int numSmartActions = smartActions.actions.size();
         for (int n = 0; n < numSmartActions; n++) {
             Notification.Action action = smartActions.actions.get(n);
             if (action.actionIntent != null) {
                 Button actionButton = inflateActionButton(
-                        getContext(), this, n, smartActions, smartReplyController, entry);
+                        getContext(), this, n, smartActions, smartReplyController, entry,
+                        headsUpManager);
                 addView(actionButton);
             }
         }
@@ -274,7 +279,7 @@
     @VisibleForTesting
     Button inflateActionButton(Context context, ViewGroup root, int actionIndex,
             SmartActions smartActions, SmartReplyController smartReplyController,
-            NotificationData.Entry entry) {
+            NotificationData.Entry entry, HeadsUpManager headsUpManager) {
         Notification.Action action = smartActions.actions.get(actionIndex);
         Button button = (Button) LayoutInflater.from(context).inflate(
                 R.layout.smart_action_button, root, false);
@@ -290,8 +295,12 @@
         button.setOnClickListener(view ->
                 getActivityStarter().startPendingIntentDismissingKeyguard(
                         action.actionIntent,
-                        () -> smartReplyController.smartActionClicked(
-                                entry, actionIndex, action, smartActions.fromAssistant)));
+                        () -> {
+                            smartReplyController.smartActionClicked(
+                                    entry, actionIndex, action, smartActions.fromAssistant);
+                            postOnUiThread(() ->
+                                    headsUpManager.removeNotification(entry.key, true));
+                        }));
 
         // TODO(b/119010281): handle accessibility
 
@@ -301,6 +310,10 @@
         return button;
     }
 
+    private void postOnUiThread(Runnable runnable) {
+        mMainThreadHandler.post(runnable);
+    }
+
     @Override
     public LayoutParams generateLayoutParams(AttributeSet attrs) {
         return new LayoutParams(mContext, attrs);