diff --git a/packages/SystemUI/res/drawable/ic_snooze.xml b/packages/SystemUI/res/drawable/ic_snooze.xml new file mode 100644 index 0000000000000..b0b03a99f4a5f --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_snooze.xml @@ -0,0 +1,12 @@ + + + + diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml new file mode 100644 index 0000000000000..5bd64defd2d13 --- /dev/null +++ b/packages/SystemUI/res/layout/notification_snooze.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 30408143e30d7..1ec611a43b56a 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -103,6 +103,10 @@ #8a000000 #4d000000 + + #FF4A4A4A + #FFA6BAFF + #ffffff #77000000 diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a453c20e83fe1..ddcc4baf8350f 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -112,6 +112,15 @@ 20dp + + 48dp + + + 14sp + + + 8dp + 17dp diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 17a560445803a..b05cc009a2fae 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1381,6 +1381,21 @@ notification controls + + notification snooze options + + + 15 minutes + + 30 minutes + + 1 hour + + UNDO + + + Snoozed for %1$s + Battery usage diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 6535a81d076b1..c5a5518226d94 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -383,6 +383,20 @@ ?android:attr/colorAccent + + + + diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 4573d60a48753..a95713fb017e5 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -286,7 +286,7 @@ public class SwipeHelper implements Gefingerpoken { final int x = (int) ev.getRawX() - mTmpPos[0]; final int y = (int) ev.getRawY() - mTmpPos[1]; mLongPressListener.onLongPress(mCurrView, x, y, - NotificationMenuRow.getSettingsMenuItem(mContext)); + NotificationMenuRow.getLongpressMenuItem(mContext)); } } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java index b4ed16a7a2b22..fad63dd4f7008 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java @@ -85,7 +85,7 @@ public class NotificationMenuRow extends FrameLayout PluginManager.getInstance(getContext()).addPluginListener( NotificationMenuRowProvider.ACTION, this, NotificationMenuRowProvider.VERSION, false /* Allow multiple */); - mMenuItems.add(getSettingsMenuItem(context)); + mMenuItems.addAll(getDefaultNotificationMenuItems()); } @Override @@ -99,22 +99,43 @@ public class NotificationMenuRow extends FrameLayout updateMenu(false /* notify */); } - public static MenuItem getSettingsMenuItem(Context context) { - Drawable d = context.getResources().getDrawable(R.drawable.ic_settings); - String s = context.getResources().getString(R.string.notification_menu_gear_description); - NotificationInfo content = (NotificationInfo) LayoutInflater.from(context).inflate( + public static MenuItem getLongpressMenuItem(Context context) { + Resources res = context.getResources(); + Drawable settingsIcon = res.getDrawable(R.drawable.ic_settings); + String settingsDescription = res.getString(R.string.notification_menu_gear_description); + NotificationInfo settingsContent = (NotificationInfo) LayoutInflater.from(context).inflate( R.layout.notification_info, null, false); - MenuItem settings = new MenuItem(d, s, content); + MenuItem settings = new MenuItem(settingsIcon, settingsDescription, settingsContent); return settings; } + public ArrayList getDefaultNotificationMenuItems() { + ArrayList items = new ArrayList(); + Resources res = getResources(); + + Drawable snoozeIcon = res.getDrawable(R.drawable.ic_snooze); + NotificationSnooze content = (NotificationSnooze) LayoutInflater.from(mContext) + .inflate(R.layout.notification_snooze, null, false); + String snoozeDescription = res.getString(R.string.notification_menu_snooze_description); + MenuItem snooze = new MenuItem(snoozeIcon, snoozeDescription, content); + items.add(snooze); + + Drawable settingsIcon = res.getDrawable(R.drawable.ic_settings); + String settingsDescription = res.getString(R.string.notification_menu_gear_description); + NotificationInfo settingsContent = (NotificationInfo) LayoutInflater.from(mContext).inflate( + R.layout.notification_info, null, false); + MenuItem settings = new MenuItem(settingsIcon, settingsDescription, settingsContent); + items.add(settings); + return items; + } + private void updateMenu(boolean notify) { removeAllViews(); mMenuItems.clear(); if (mMenuProvider != null) { mMenuItems.addAll(mMenuProvider.getMenuItems(getContext())); } - mMenuItems.add(getSettingsMenuItem(getContext())); + mMenuItems.addAll(getDefaultNotificationMenuItems()); for (int i = 0; i < mMenuItems.size(); i++) { final View v = createMenuView(mMenuItems.get(i)); mMenuItems.get(i).menuView = v; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java new file mode 100644 index 0000000000000..670d73efcbee1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java @@ -0,0 +1,176 @@ +package com.android.systemui.statusbar; +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +import java.util.ArrayList; +import java.util.Calendar; +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 android.content.Context; +import android.content.res.Resources; +import android.graphics.Color; +import android.service.notification.StatusBarNotification; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioGroup; +import android.widget.RadioGroup.OnCheckedChangeListener; +import android.widget.TextView; +import android.widget.Toast; +import com.android.systemui.R; + +public class NotificationSnooze extends LinearLayout + implements NotificationMenuRowProvider.SnoozeGutsContent, View.OnClickListener { + + private GutsInteractionListener mGutsInteractionListener; + private SnoozeListener mSnoozeListener; + private StatusBarNotification mSbn; + + private TextView mSelectedOption; + private TextView mUndo; + private ViewGroup mSnoozeOptionView; + + 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 + }; + + public NotificationSnooze(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + // Create the different options based on list + createOptionViews(); + + // Snackbar + mSelectedOption = (TextView) findViewById(R.id.snooze_option_default); + mSelectedOption.setOnClickListener(this); + mUndo = (TextView) findViewById(R.id.undo); + mUndo.setOnClickListener(this); + + // Default to first option in list + setTimeToSnooze(SNOOZE_OPTIONS[0]); + } + + private void createOptionViews() { + mSnoozeOptionView = (ViewGroup) findViewById(R.id.snooze_options); + 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++) { + 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.setOnClickListener(this); + } + } + + private void showSnoozeOptions(boolean show) { + mSelectedOption.setVisibility(show ? View.GONE : View.VISIBLE); + mUndo.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); + showSnoozeOptions(false); + } + + @Override + public void onClick(View v) { + if (mGutsInteractionListener != null) { + mGutsInteractionListener.onInteraction(this); + } + final int id = v.getId(); + final Integer tag = (Integer) v.getTag(); + if (tag != null) { + // From the option list + setTimeToSnooze(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); + } + } + + @Override + public View getContentView() { + return this; + } + + @Override + public void setStatusBarNotification(StatusBarNotification sbn) { + mSbn = sbn; + } + + @Override + public void setInteractionListener(GutsInteractionListener listener) { + mGutsInteractionListener = listener; + } + + @Override + public void setSnoozeListener(SnoozeListener listener) { + mSnoozeListener = listener; + } + + @Override + 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); + return true; + } + return false; + } +}