Add assistant-provided snooze options to snooze menu

Test: manual via Assistant app
Change-Id: Ie77181601a20e46774d009c7ecea65e99434ebd3
This commit is contained in:
Mady Mellor
2017-01-25 15:29:39 -08:00
parent c710accde0
commit 754d8226c9
6 changed files with 126 additions and 50 deletions

View File

@@ -3,6 +3,7 @@ package com.android.systemui.plugins.statusbar;
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 NotificationMenuRowProvider extends Plugin {
}
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 @@ public interface NotificationMenuRowProvider extends Plugin {
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;
}
}
}

View File

@@ -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>

View File

@@ -105,6 +105,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider;
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;
@@ -119,7 +120,9 @@ import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
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;
@@ -1052,8 +1055,14 @@ public abstract class BaseStatusBar extends SystemUI implements
}, 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() {
@@ -1076,6 +1085,7 @@ public abstract class BaseStatusBar extends SystemUI implements
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) {

View File

@@ -25,6 +25,7 @@ import android.os.SystemClock;
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.io.PrintWriter;
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 class NotificationData {
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 @@ public class NotificationData {
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 @@ public class NotificationData {
mGroupManager.onEntryUpdated(entry, oldSbn);
}
entry.channel = getChannel(entry.key);
entry.snoozeCriteria = getSnoozeCriteria(entry.key);
}
}
}

View File

@@ -17,17 +17,21 @@ package com.android.systemui.statusbar;
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 @@ import com.android.systemui.R;
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 @@ public class NotificationSnooze extends LinearLayout
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 @@ public class NotificationSnooze extends LinearLayout
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 class NotificationSnooze extends LinearLayout
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;
}

View File

@@ -142,6 +142,7 @@ import com.android.systemui.plugins.qs.QS;
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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
public void snoozeNotification(StatusBarNotification sbn, long snoozeUntil) {
setNotificationSnoozed(sbn, snoozeUntil);
public void snoozeNotification(StatusBarNotification sbn, SnoozeOption snoozeOption) {
setNotificationSnoozed(sbn, snoozeOption);
}
}