Merge "Add customs accessibility actions to snooze, allow it to be focused" into oc-dr1-dev

This commit is contained in:
TreeHugger Robot
2017-06-21 18:31:28 +00:00
committed by Android (Google) Code Review
5 changed files with 173 additions and 38 deletions

View File

@@ -22,6 +22,7 @@ import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@ProvidesInterface(version = NotificationSwipeActionHelper.VERSION)
@DependsOn(target = SnoozeOption.class)
@@ -56,19 +57,17 @@ public interface NotificationSwipeActionHelper {
public boolean swipedFastEnough(float translation, float velocity);
@ProvidesInterface(version = SnoozeOption.VERSION)
public static class SnoozeOption {
public static final int VERSION = 1;
public int snoozeForMinutes;
public SnoozeCriterion criterion;
public CharSequence description;
public CharSequence confirmation;
public interface SnoozeOption {
public static final int VERSION = 2;
public SnoozeOption(SnoozeCriterion crit, int minsToSnoozeFor, CharSequence desc,
CharSequence confirm) {
criterion = crit;
snoozeForMinutes = minsToSnoozeFor;
description = desc;
confirmation = confirm;
}
public SnoozeCriterion getSnoozeCriterion();
public CharSequence getDescription();
public CharSequence getConfirmation();
public int getMinutesToSnoozeFor();
public AccessibilityAction getAccessibilityAction();
}
}

View File

@@ -20,12 +20,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:background="@color/notification_guts_bg_color"
android:theme="@*android:style/Theme.DeviceDefault.Light">
<RelativeLayout
android:layout_width="match_parent"
android:id="@+id/notification_snooze"
android:layout_width="match_parent"
android:layout_height="@dimen/snooze_snackbar_min_height">
<TextView

View File

@@ -78,5 +78,13 @@
<item type="id" name="action_move_tl_50" />
<item type="id" name="action_move_tl_30" />
<item type="id" name="action_move_rb_full" />
<!-- Accessibility actions for the notification menu -->
<item type="id" name="action_snooze_undo"/>
<item type="id" name="action_snooze_15_min"/>
<item type="id" name="action_snooze_30_min"/>
<item type="id" name="action_snooze_1_hour"/>
<item type="id" name="action_snooze_2_hours"/>
<item type="id" name="action_snooze_assistant_suggestion_1"/>
</resources>

View File

@@ -21,11 +21,14 @@ import java.util.List;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.os.Bundle;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.text.SpannableString;
@@ -35,6 +38,9 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -45,6 +51,10 @@ import com.android.systemui.R;
public class NotificationSnooze extends LinearLayout
implements NotificationGuts.GutsContent, View.OnClickListener {
/**
* If this changes more number increases, more assistant action resId's should be defined for
* accessibility purposes, see {@link #setSnoozeOptions(List)}
*/
private static final int MAX_ASSISTANT_SUGGESTIONS = 1;
private NotificationGuts mGutsContainer;
private NotificationSwipeActionHelper mSnoozeListener;
@@ -79,16 +89,60 @@ public class NotificationSnooze extends LinearLayout
mDivider = findViewById(R.id.divider);
mDivider.setAlpha(0f);
mSnoozeOptionContainer = (ViewGroup) findViewById(R.id.snooze_options);
mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
mSnoozeOptionContainer.setAlpha(0f);
// Create the different options based on list
mSnoozeOptions = getDefaultSnoozeOptions();
createOptionViews();
// Default to first option in list
setSelected(mDefaultOption);
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
if (mGutsContainer != null && mGutsContainer.isExposed()) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
event.getText().add(mSelectedOptionText.getText());
}
}
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.addAction(new AccessibilityAction(R.id.action_snooze_undo,
getResources().getString(R.string.snooze_undo)));
int count = mSnoozeOptions.size();
for (int i = 0; i < count; i++) {
AccessibilityAction action = mSnoozeOptions.get(i).getAccessibilityAction();
if (action != null) {
info.addAction(action);
}
}
}
@Override
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
if (super.performAccessibilityActionInternal(action, arguments)) {
return true;
}
if (action == R.id.action_snooze_undo) {
undoSnooze(mUndoButton);
return true;
}
for (int i = 0; i < mSnoozeOptions.size(); i++) {
SnoozeOption so = mSnoozeOptions.get(i);
if (so.getAccessibilityAction() != null
&& so.getAccessibilityAction().getId() == action) {
setSelected(so);
return true;
}
}
return false;
}
public void setSnoozeOptions(final List<SnoozeCriterion> snoozeList) {
if (snoozeList == null) {
return;
@@ -98,7 +152,10 @@ public class NotificationSnooze extends LinearLayout
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()));
AccessibilityAction action = new AccessibilityAction(
R.id.action_snooze_assistant_suggestion_1, sc.getExplanation());
mSnoozeOptions.add(new NotificationSnoozeOption(sc, 0, sc.getExplanation(),
sc.getConfirmation(), action));
}
createOptionViews();
}
@@ -117,15 +174,16 @@ public class NotificationSnooze extends LinearLayout
private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
ArrayList<SnoozeOption> options = new ArrayList<>();
options.add(createOption(15 /* minutes */));
options.add(createOption(30 /* minutes */));
mDefaultOption = createOption(60 /* minutes */);
options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min));
options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min));
mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour);
options.add(mDefaultOption);
options.add(createOption(60 * 2 /* minutes */));
options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours));
return options;
}
private SnoozeOption createOption(int minutes) {
private SnoozeOption createOption(int minutes, int accessibilityActionId) {
Resources res = getResources();
boolean showInHours = minutes >= 60;
int pluralResId = showInHours
@@ -137,7 +195,9 @@ public class NotificationSnooze extends LinearLayout
SpannableString string = new SpannableString(resultText);
string.setSpan(new StyleSpan(Typeface.BOLD),
resultText.length() - description.length(), resultText.length(), 0 /* flags */);
return new SnoozeOption(null, minutes, description, string);
AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
return new NotificationSnoozeOption(null, minutes, description, string,
action);
}
private void createOptionViews() {
@@ -149,7 +209,7 @@ public class NotificationSnooze extends LinearLayout
TextView tv = (TextView) inflater.inflate(R.layout.notification_snooze_option,
mSnoozeOptionContainer, false);
mSnoozeOptionContainer.addView(tv);
tv.setText(option.description);
tv.setText(option.getDescription());
tv.setTag(option);
tv.setOnClickListener(this);
}
@@ -184,18 +244,36 @@ public class NotificationSnooze extends LinearLayout
mDivider.getAlpha(), show ? 1f : 0f);
ObjectAnimator optionAnim = ObjectAnimator.ofFloat(mSnoozeOptionContainer, View.ALPHA,
mSnoozeOptionContainer.getAlpha(), show ? 1f : 0f);
mSnoozeOptionContainer.setVisibility(View.VISIBLE);
mExpandAnimation = new AnimatorSet();
mExpandAnimation.playTogether(dividerAnim, optionAnim);
mExpandAnimation.setDuration(150);
mExpandAnimation.setInterpolator(show ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
mExpandAnimation.addListener(new AnimatorListenerAdapter() {
boolean cancelled = false;
@Override
public void onAnimationCancel(Animator animation) {
cancelled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
if (!show && !cancelled) {
mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
mSnoozeOptionContainer.setAlpha(0f);
}
}
});
mExpandAnimation.start();
}
private void setSelected(SnoozeOption option) {
mSelectedOption = option;
mSelectedOptionText.setText(option.confirmation);
mSelectedOptionText.setText(option.getConfirmation());
showSnoozeOptions(false);
hideSelectedOption();
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
@Override
@@ -212,20 +290,24 @@ public class NotificationSnooze extends LinearLayout
showSnoozeOptions(!mExpanded);
} else {
// Undo snooze was selected
mSelectedOption = null;
int[] parentLoc = new int[2];
int[] targetLoc = new int[2];
mGutsContainer.getLocationOnScreen(parentLoc);
v.getLocationOnScreen(targetLoc);
final int centerX = v.getWidth() / 2;
final int centerY = v.getHeight() / 2;
final int x = targetLoc[0] - parentLoc[0] + centerX;
final int y = targetLoc[1] - parentLoc[1] + centerY;
showSnoozeOptions(false);
mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
undoSnooze(v);
}
}
private void undoSnooze(View v) {
mSelectedOption = null;
int[] parentLoc = new int[2];
int[] targetLoc = new int[2];
mGutsContainer.getLocationOnScreen(parentLoc);
v.getLocationOnScreen(targetLoc);
final int centerX = v.getWidth() / 2;
final int centerY = v.getHeight() / 2;
final int x = targetLoc[0] - parentLoc[0] + centerX;
final int y = targetLoc[1] - parentLoc[1] + centerY;
showSnoozeOptions(false);
mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
}
@Override
public int getActualHeight() {
return mExpanded ? getHeight() : mCollapsedHeight;
@@ -270,4 +352,48 @@ public class NotificationSnooze extends LinearLayout
public boolean isLeavebehind() {
return true;
}
public class NotificationSnoozeOption implements SnoozeOption {
private SnoozeCriterion mCriterion;
private int mMinutesToSnoozeFor;
private CharSequence mDescription;
private CharSequence mConfirmation;
private AccessibilityAction mAction;
public NotificationSnoozeOption(SnoozeCriterion sc, int minToSnoozeFor,
CharSequence description,
CharSequence confirmation, AccessibilityAction action) {
mCriterion = sc;
mMinutesToSnoozeFor = minToSnoozeFor;
mDescription = description;
mConfirmation = confirmation;
mAction = action;
}
@Override
public SnoozeCriterion getSnoozeCriterion() {
return mCriterion;
}
@Override
public CharSequence getDescription() {
return mDescription;
}
@Override
public CharSequence getConfirmation() {
return mConfirmation;
}
@Override
public int getMinutesToSnoozeFor() {
return mMinutesToSnoozeFor;
}
@Override
public AccessibilityAction getAccessibilityAction() {
return mAction;
}
}
}

View File

@@ -6071,11 +6071,12 @@ public class StatusBar extends SystemUI implements DemoMode,
}
public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
if (snoozeOption.criterion != null) {
mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
if (snoozeOption.getSnoozeCriterion() != null) {
mNotificationListener.snoozeNotification(sbn.getKey(),
snoozeOption.getSnoozeCriterion().getId());
} else {
mNotificationListener.snoozeNotification(sbn.getKey(),
snoozeOption.snoozeForMinutes * 60 * 1000);
snoozeOption.getMinutesToSnoozeFor() * 60 * 1000);
}
}