Merge "Add assistant-provided snooze options to snooze menu"
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
index c0a48a8..93ba39c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
@@ -3,6 +3,7 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
@@ -48,7 +49,7 @@
     }
 
     public interface SnoozeListener {
-        public void snoozeNotification(StatusBarNotification sbn, long snoozeUntil);
+        public void snoozeNotification(StatusBarNotification sbn, SnoozeOption snoozeOption);
     }
 
     public static class MenuItem {
@@ -71,4 +72,19 @@
             return false;
         }
     }
+
+    public static class SnoozeOption {
+        public SnoozeCriterion criterion;
+        public int snoozeForMinutes;
+        public CharSequence description;
+        public CharSequence confirmation;
+
+        public SnoozeOption(SnoozeCriterion crit, int minsToSnoozeFor, CharSequence desc,
+                CharSequence confirm) {
+            criterion = crit;
+            snoozeForMinutes = minsToSnoozeFor;
+            description = desc;
+            confirmation = confirm;
+        }
+    }
 }
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7f4baa5..5d2117a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1390,6 +1390,8 @@
     <string name="snooze_option_30_min">30 minutes</string>
     <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]-->
     <string name="snooze_option_1_hour">1 hour</string>
+    <!-- Notification: Menu row: Snooze options: don't snooze option. [CHAR LIMIT=50] -->
+    <string name="snooze_option_dont_snooze">Don\'t snooze</string>
     <!-- Notification: Menu row: Snooze undo button label. [CHAR LIMIT=50]-->
     <string name="snooze_undo">UNDO</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 9a5e783..20f455a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -105,6 +105,7 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeGutsContent;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeListener;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeOption;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -120,7 +121,9 @@
 import com.android.systemui.util.NotificationChannels;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Collections;
+import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -1053,8 +1056,14 @@
         }, false /* afterKeyguardGone */);
     }
 
-    protected void setNotificationSnoozed(StatusBarNotification sbn, long snoozeUntil) {
-        mNotificationListener.snoozeNotification(sbn.getKey(), snoozeUntil);
+    protected void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
+        if (snoozeOption.criterion != null) {
+            mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
+        } else {
+            GregorianCalendar snoozeUntil = new GregorianCalendar();
+            snoozeUntil.add(Calendar.MINUTE, snoozeOption.snoozeForMinutes);
+            mNotificationListener.snoozeNotification(sbn.getKey(), snoozeUntil.getTimeInMillis());
+        }
     }
 
     public SnoozeListener getSnoozeListener() {
@@ -1077,6 +1086,7 @@
         if (item.gutsContent instanceof SnoozeGutsContent) {
             ((SnoozeGutsContent) item.gutsContent).setSnoozeListener(getSnoozeListener());
             ((SnoozeGutsContent) item.gutsContent).setStatusBarNotification(sbn);
+            ((NotificationSnooze) item.gutsContent).setSnoozeOptions(row.getEntry().snoozeCriteria);
         }
 
         if (item.gutsContent instanceof NotificationInfo) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 8c04a1a..e48c20e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -25,6 +25,7 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.NotificationListenerService.RankingMap;
+import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.view.View;
@@ -40,6 +41,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -71,6 +73,7 @@
         public RemoteViews cachedPublicContentView;
         public RemoteViews cachedAmbientContentView;
         public CharSequence remoteInputText;
+        public List<SnoozeCriterion> snoozeCriteria;
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
 
@@ -456,6 +459,14 @@
          return null;
     }
 
+    public List<SnoozeCriterion> getSnoozeCriteria(String key) {
+        if (mRankingMap != null) {
+            mRankingMap.getRanking(key, mTmpRanking);
+            return mTmpRanking.getSnoozeCriteria();
+        }
+        return null;
+    }
+
     public NotificationChannel getChannel(String key) {
         if (mRankingMap != null) {
             mRankingMap.getRanking(key, mTmpRanking);
@@ -478,6 +489,7 @@
                         mGroupManager.onEntryUpdated(entry, oldSbn);
                     }
                     entry.channel = getChannel(entry.key);
+                    entry.snoozeCriteria = getSnoozeCriteria(entry.key);
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 670d73e..1992b6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -17,17 +17,21 @@
 
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.GutsInteractionListener;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeListener;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeOption;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.View;
@@ -43,21 +47,17 @@
 public class NotificationSnooze extends LinearLayout
         implements NotificationMenuRowProvider.SnoozeGutsContent, View.OnClickListener {
 
+    private static final int MAX_ASSISTANT_SUGGESTIONS = 2;
     private GutsInteractionListener mGutsInteractionListener;
     private SnoozeListener mSnoozeListener;
     private StatusBarNotification mSbn;
 
-    private TextView mSelectedOption;
-    private TextView mUndo;
+    private TextView mSelectedOptionText;
+    private TextView mUndoButton;
     private ViewGroup mSnoozeOptionView;
+    private List<SnoozeOption> mSnoozeOptions;
 
-    private long mTimeToSnooze;
-
-    // Default is the first option in this list
-    private static final int[] SNOOZE_OPTIONS = {
-            R.string.snooze_option_15_min, R.string.snooze_option_30_min,
-            R.string.snooze_option_1_hour
-    };
+    private SnoozeOption mSelectedOption;
 
     public NotificationSnooze(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -67,60 +67,88 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         // Create the different options based on list
+        mSnoozeOptions = getDefaultSnoozeOptions();
         createOptionViews();
 
         // Snackbar
-        mSelectedOption = (TextView) findViewById(R.id.snooze_option_default);
-        mSelectedOption.setOnClickListener(this);
-        mUndo = (TextView) findViewById(R.id.undo);
-        mUndo.setOnClickListener(this);
+        mSelectedOptionText = (TextView) findViewById(R.id.snooze_option_default);
+        mSelectedOptionText.setOnClickListener(this);
+        mUndoButton = (TextView) findViewById(R.id.undo);
+        mUndoButton.setOnClickListener(this);
 
         // Default to first option in list
-        setTimeToSnooze(SNOOZE_OPTIONS[0]);
+        setSelected(mSnoozeOptions.get(0));
+    }
+
+    public void setSnoozeOptions(final List<SnoozeCriterion> snoozeList) {
+        if (snoozeList == null) {
+            return;
+        }
+        mSnoozeOptions.clear();
+        mSnoozeOptions = getDefaultSnoozeOptions();
+        final int count = Math.min(MAX_ASSISTANT_SUGGESTIONS, snoozeList.size());
+        for (int i = 0; i < count; i++) {
+            SnoozeCriterion sc = snoozeList.get(i);
+            mSnoozeOptions.add(new SnoozeOption(sc, 0, sc.getExplanation(), sc.getConfirmation()));
+        }
+        createOptionViews();
+    }
+
+    private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
+        ArrayList<SnoozeOption> options = new ArrayList<>();
+        options.add(createOption(R.string.snooze_option_15_min, 15));
+        options.add(createOption(R.string.snooze_option_30_min, 30));
+        options.add(createOption(R.string.snooze_option_1_hour, 60));
+        return options;
+    }
+
+    private SnoozeOption createOption(int descriptionResId, int minutes) {
+        Resources res = getResources();
+        String resultText = String.format(
+                res.getString(R.string.snoozed_for_time), res.getString(descriptionResId));
+        return new SnoozeOption(null, minutes, res.getString(descriptionResId), resultText);
     }
 
     private void createOptionViews() {
         mSnoozeOptionView = (ViewGroup) findViewById(R.id.snooze_options);
+        mSnoozeOptionView.removeAllViews();
         mSnoozeOptionView.setVisibility(View.GONE);
         final Resources res = getResources();
         final int textSize = res.getDimensionPixelSize(R.dimen.snooze_option_text_size);
         final int p = res.getDimensionPixelSize(R.dimen.snooze_option_padding);
-        for (int i = 0; i < SNOOZE_OPTIONS.length; i++) {
+
+        // Add all the options
+        for (int i = 0; i < mSnoozeOptions.size(); i++) {
+            SnoozeOption option = mSnoozeOptions.get(i);
             TextView tv = new TextView(getContext());
             tv.setTextColor(Color.WHITE);
             tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
             tv.setPadding(p, p, p, p);
             mSnoozeOptionView.addView(tv);
-            tv.setText(SNOOZE_OPTIONS[i]);
-            tv.setTag(SNOOZE_OPTIONS[i]);
+            tv.setText(option.description);
+            tv.setTag(option);
             tv.setOnClickListener(this);
         }
+
+        // Add the undo option as final item
+        TextView tv = new TextView(getContext());
+        tv.setTextColor(Color.WHITE);
+        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+        tv.setPadding(p, p, p, p);
+        mSnoozeOptionView.addView(tv);
+        tv.setText(R.string.snooze_option_dont_snooze);
+        tv.setOnClickListener(this);
     }
 
     private void showSnoozeOptions(boolean show) {
-        mSelectedOption.setVisibility(show ? View.GONE : View.VISIBLE);
-        mUndo.setVisibility(show ? View.GONE : View.VISIBLE);
+        mSelectedOptionText.setVisibility(show ? View.GONE : View.VISIBLE);
+        mUndoButton.setVisibility(show ? View.GONE : View.VISIBLE);
         mSnoozeOptionView.setVisibility(show ? View.VISIBLE : View.GONE);
     }
 
-    private void setTimeToSnooze(int optionId) {
-        long snoozeUntilMillis = Calendar.getInstance().getTimeInMillis();
-        switch (optionId) {
-            case R.string.snooze_option_15_min:
-                snoozeUntilMillis += TimeUnit.MINUTES.toMillis(15);
-                break;
-            case R.string.snooze_option_30_min:
-                snoozeUntilMillis += TimeUnit.MINUTES.toMillis(30);
-                break;
-            case R.string.snooze_option_1_hour:
-                snoozeUntilMillis += TimeUnit.MINUTES.toMillis(60);
-                break;
-        }
-        mTimeToSnooze = snoozeUntilMillis;
-        final Resources res = getResources();
-        String selectedString = String.format(
-                res.getString(R.string.snoozed_for_time), res.getString(optionId));
-        mSelectedOption.setText(selectedString);
+    private void setSelected(SnoozeOption option) {
+        mSelectedOption = option;
+        mSelectedOptionText.setText(option.confirmation);
         showSnoozeOptions(false);
     }
 
@@ -130,19 +158,22 @@
             mGutsInteractionListener.onInteraction(this);
         }
         final int id = v.getId();
-        final Integer tag = (Integer) v.getTag();
+        final SnoozeOption tag = (SnoozeOption) v.getTag();
         if (tag != null) {
-            // From the option list
-            setTimeToSnooze(tag);
+            setSelected(tag);
         } else if (id == R.id.snooze_option_default) {
             // Show more snooze options
             showSnoozeOptions(true);
-        } else if (id == R.id.undo) {
-            mTimeToSnooze = -1;
-            mGutsInteractionListener.closeGuts(this);
+        } else {
+            undoSnooze();
         }
     }
 
+    private void undoSnooze() {
+        mSelectedOption = null;
+        mGutsInteractionListener.closeGuts(this);
+    }
+
     @Override
     public View getContentView() {
         return this;
@@ -167,9 +198,13 @@
     public boolean handleCloseControls() {
         // When snooze is closed (i.e. there was interaction outside of the notification)
         // then we commit the snooze action.
-        if (mSnoozeListener != null && mTimeToSnooze != -1) {
-            mSnoozeListener.snoozeNotification(mSbn, mTimeToSnooze);
+        if (mSnoozeListener != null && mSelectedOption != null) {
+            mSnoozeListener.snoozeNotification(mSbn, mSelectedOption);
             return true;
+        } else {
+            // Reset the view once it's closed
+            setSelected(mSnoozeOptions.get(0));
+            showSnoozeOptions(false);
         }
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7d82477..6c2e27a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -142,6 +142,7 @@
 import com.android.systemui.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.BaseStatusBarHeader;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeListener;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeOption;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.recents.ScreenPinningRequest;
@@ -4866,7 +4867,7 @@
     }
 
     @Override
-    public void snoozeNotification(StatusBarNotification sbn, long snoozeUntil) {
-        setNotificationSnoozed(sbn, snoozeUntil);
+    public void snoozeNotification(StatusBarNotification sbn, SnoozeOption snoozeOption) {
+        setNotificationSnoozed(sbn, snoozeOption);
     }
 }