summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Geoffrey Pitsch <gpitsch@google.com> 2017-02-13 17:47:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-02-13 17:47:33 +0000
commit7c4f39b856b34ea138857ab1a0c7edb5f40450e3 (patch)
treee683a5bad8708c9922a4b09979d1d6887c4a2d8c
parent7517e27793e1e9236eef82743c148665c0c0cda6 (diff)
parentdf44b606f357bb67e7a3b44e58f551c1c731ce42 (diff)
Merge "Updated Inline Notification Controls"
-rw-r--r--core/java/android/app/INotificationManager.aidl3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java2
-rw-r--r--packages/SystemUI/res/layout/notification_guts_importance_text.xml38
-rw-r--r--packages/SystemUI/res/layout/notification_info.xml98
-rw-r--r--packages/SystemUI/res/values/colors.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml42
-rw-r--r--packages/SystemUI/res/values/styles.xml11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java205
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java)218
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java18
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java7
15 files changed, 351 insertions, 308 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index cc6f6e12710b..5ab767ba9676 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -20,6 +20,7 @@ package android.app;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Intent;
@@ -57,12 +58,14 @@ interface INotificationManager
void createNotificationChannelGroups(String pkg, in ParceledListSlice channelGroupList);
void createNotificationChannels(String pkg, in ParceledListSlice channelsList);
ParceledListSlice getNotificationChannelGroupsForPackage(String pkg, int uid, boolean includeDeleted);
+ NotificationChannelGroup getNotificationChannelGroupForPackage(String groupId, String pkg, int uid);
void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
NotificationChannel getNotificationChannel(String pkg, String channelId);
NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, boolean includeDeleted);
void deleteNotificationChannel(String pkg, String channelId);
ParceledListSlice getNotificationChannels(String pkg);
ParceledListSlice getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
+ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
// TODO: Remove this when callers have been migrated to the equivalent
// INotificationListener method.
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 93ba39cbba9d..41a0907c3228 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
@@ -39,7 +39,7 @@ public interface NotificationMenuRowProvider extends Plugin {
public View getContentView();
- public boolean handleCloseControls();
+ public boolean handleCloseControls(boolean save);
}
public interface SnoozeGutsContent extends GutsContent {
diff --git a/packages/SystemUI/res/layout/notification_guts_importance_text.xml b/packages/SystemUI/res/layout/notification_guts_importance_text.xml
deleted file mode 100644
index 5df4e0a96ba6..000000000000
--- a/packages/SystemUI/res/layout/notification_guts_importance_text.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2016, 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_inline_importance_height"
- android:paddingTop="4dp"
- android:orientation="vertical">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:singleLine="true"
- android:text="@string/high_importance"
- android:textAppearance="@style/TextAppearance.NotificationGuts.Primary" />
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:singleLine="true"
- android:text="@string/notification_importance_high"
- android:textAppearance="@style/TextAppearance.NotificationGuts.Secondary" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 9770eccfd2c1..31bd8b9e415b 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -28,89 +28,73 @@
android:background="@color/notification_guts_bg_color"
android:theme="@*android:style/Theme.DeviceDefault.Light">
- <!-- header -->
- <RelativeLayout
+ <!-- Package Info -->
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="20dp"
- android:paddingEnd="8dp"
- android:paddingBottom="15dp"
- android:id="@+id/notification_guts_header">
+ android:orientation="horizontal"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp" >
+ <ImageView
+ android:id="@+id/pkgicon"
+ android:layout_width="18dp"
+ android:layout_height="18dp"
+ android:layout_marginEnd="6dp"
+ android:contentDescription="@null"
+ android:scaleType="fitCenter" />
<TextView
android:id="@+id/pkgname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
style="@style/TextAppearance.NotificationGuts.Secondary" />
<TextView
- android:id="@+id/channel_name"
+ android:id="@+id/pkg_group_divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
- android:layout_below="@id/pkgname"
- style="@style/TextAppearance.NotificationGuts.Header" />
- <Switch
- android:id="@+id/channel_enabled_switch"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:text="@string/notification_header_divider_symbol_with_spaces"/>
+ <TextView
+ android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:background="@null" />
- </RelativeLayout>
- <!-- Importance radio buttons -->
+ style="@style/TextAppearance.NotificationGuts.Secondary" />
+ </LinearLayout>
+
+ <!-- Channel Info -->
<LinearLayout
- android:id="@+id/importance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:paddingBottom="8dp"
android:orientation="horizontal">
- <RadioGroup
- android:id="@+id/importance_buttons"
+ <TextView
+ android:id="@+id/channel_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingEnd="@*android:dimen/notification_content_margin_end">
- <RadioButton
- android:id="@+id/high_importance"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_inline_importance_height"
- style="@style/TextAppearance.NotificationGuts.Radio"
- android:buttonTint="@color/notification_guts_buttons" />
- <RadioButton
- android:id="@+id/default_importance"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_inline_importance_height"
- style="@style/TextAppearance.NotificationGuts.Radio"
- android:buttonTint="@color/notification_guts_buttons" />
- <RadioButton
- android:id="@+id/low_importance"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_inline_importance_height"
- style="@style/TextAppearance.NotificationGuts.Radio"
- android:buttonTint="@color/notification_guts_buttons" />
- <RadioButton
- android:id="@+id/min_importance"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_inline_importance_height"
- style="@style/TextAppearance.NotificationGuts.Radio"
- android:buttonTint="@color/notification_guts_buttons" />
- </RadioGroup>
- <LinearLayout
- android:id="@+id/importance_buttons_text"
- android:layout_width="match_parent"
+ android:layout_below="@id/pkgname"
+ style="@style/TextAppearance.NotificationGuts.Header" />
+ <Switch
+ android:id="@+id/channel_enabled_switch"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
- <include layout="@layout/notification_guts_importance_text"/>
- <include layout="@layout/notification_guts_importance_text"/>
- <include layout="@layout/notification_guts_importance_text"/>
- <include layout="@layout/notification_guts_importance_text"/>
- </LinearLayout>
+ android:layout_gravity="end"
+ android:layout_weight="1"
+ android:background="@null" />
</LinearLayout>
- <!-- Channel Disabled Text -->
+
+ <!-- Secondary Text - only one shows at a time -->
<TextView
android:id="@+id/channel_disabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/notification_channel_disabled"
+ style="@style/TextAppearance.NotificationGuts.SecondaryWarning" />
+ <TextView
+ android:id="@+id/num_channels_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
style="@style/TextAppearance.NotificationGuts.Secondary" />
+
<!-- Settings and Done buttons -->
<LinearLayout
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1249f44cfabf..7f30c8307682 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -96,10 +96,6 @@
<!-- The "inside" of a notification, reached via longpress -->
<color name="notification_guts_bg_color">#eeeeee</color>
- <color name="notification_guts_disabled_slider_color">@*android:color/material_grey_300</color>
- <color name="notification_guts_secondary_slider_color">#858383</color>
- <color name="notification_guts_icon_tint">#8a000000</color>
- <color name="notification_guts_disabled_icon_tint">#4d000000</color>
<!-- Colors of the snooze menu reached via snooze icon behind a notification -->
<color name="snooze_snackbar_bg">#FF4A4A4A</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e69c4a3ed22b..e737d2d6f007 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -317,9 +317,6 @@
<!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups -->
<dimen name="notification_divider_height_increased">6dp</dimen>
- <!-- The height of an importance selection in the inline notification controls -->
- <dimen name="notification_inline_importance_height">55dp</dimen>
-
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f7cf444d2350..67def4fa8ee0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1335,37 +1335,23 @@
<!-- Notification Inline Controls: Header for apps that are not yet using notification channels. -->
<string name="notification_header_default_channel">Notifications</string>
+ <!-- The divider symbol between different parts of the notification header including spaces. not translatable [CHAR LIMIT=3] -->
+ <string name="notification_header_divider_symbol_with_spaces" translatable="false">" • "</string>
+
<!-- Notification Inline Controls: Shown when a channel's notifications are currently blocked -->
<string name="notification_channel_disabled">You won\'t get these notifications anymore.</string>
- <!-- Notification Inline Controls: Header text for describing from which app this notification
- originates. The line below this in the layout will display the channel name.
- Note for localization: For languages in which the two separate lines cannot be a continuous
- sentence, translate this as a separate statement: "[Calendar] notifications" -->
- <string name="notification_importance_header_app"><xliff:g id="app" example="Calendar">%s</xliff:g> notifications for</string>
-
- <!-- Notification importance title, min status-->
- <string name="min_importance">Low</string>
- <!-- Notification importance title, low status-->
- <string name="low_importance">Medium</string>
- <!-- Notification importance title, normal status-->
- <string name="default_importance">High</string>
- <!-- Notification importance title, high status-->
- <string name="high_importance">Urgent</string>
-
- <!-- [CHAR LIMIT=100] Notification Importance slider: min importance level description -->
- <string name="notification_importance_min">No sound or visual interruption</string>
-
- <!-- [CHAR LIMIT=100] Notification Importance slider: low importance level description -->
- <string name="notification_importance_low">Show silently</string>
-
- <!-- [CHAR LIMIT=100] Notification Importance slider: normal importance level description -->
- <string name="notification_importance_default">Make sound</string>
-
- <!-- [CHAR LIMIT=100] Notification Importance slider: high importance level description -->
- <string name="notification_importance_high">Make sound and pop on screen</string>
-
- <!-- Notification: Control panel: Label for button that launches notification settings. [CHAR LIMIT=NONE] -->
+ <!-- Notification: Control panel: Label that shows how many channels this application has
+ defined, describing the current notification channel as "1 out of n". -->
+ <plurals name="notification_num_channels_desc">
+ <item quantity="one">1 out of <xliff:g id="number">%d</xliff:g> category from this app</item>
+ <item quantity="other">1 out of <xliff:g id="number">%d</xliff:g> categories from this app</item>
+ </plurals>
+ <!-- Notification: Control panel: Label for button that launches notification settings. Used
+ when this app has defined more than a single channel for notifications. -->
+ <string name="notification_all_categories">All Categories</string>
+ <!-- Notification: Control panel: Label for button that launches notification settings. Used
+ when this app has only defined a single channel for notifications. -->
<string name="notification_more_settings">More settings</string>
<!-- Notification: Control panel: Label for button that dismisses control panel. [CHAR LIMIT=NONE] -->
<string name="notification_done">Done</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index c5a5518226d9..48b76648e7a3 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -362,17 +362,12 @@
<style name="TextAppearance.NotificationGuts.Secondary">
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:alpha">.38</item>
<item name="android:textSize">12sp</item>
</style>
- <style name="TextAppearance.NotificationGuts.Primary">
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:textSize">16sp</item>
- </style>
-
- <style name="TextAppearance.NotificationGuts.Radio">
- <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <style name="TextAppearance.NotificationGuts.SecondaryWarning">
+ <item name="android:textColor">@color/system_warning_color</item>
+ <item name="android:textSize">12sp</item>
</style>
<style name="TextAppearance.NotificationGuts.Button">
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index f6056ddab093..b36cfdca1a46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -39,12 +39,9 @@ import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
-import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
@@ -170,14 +167,14 @@ public class NotificationGuts extends FrameLayout
void onClick(View v, int appUid);
}
- public void closeControls(int x, int y, boolean saveImportance) {
+ public void closeControls(int x, int y, boolean save) {
if (getWindowToken() == null) {
if (mListener != null) {
mListener.onGutsClosed(this);
}
return;
}
- if (mGutsContent == null || !mGutsContent.handleCloseControls()) {
+ if (mGutsContent == null || !mGutsContent.handleCloseControls(save)) {
animateClose(x, y);
}
setExposed(false, mNeedsFalsingProtection);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index bdbc9b32cbce..cfaa9e6238e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -1,5 +1,3 @@
-package com.android.systemui.statusbar;
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -16,15 +14,19 @@ package com.android.systemui.statusbar;
* limitations under the License
*/
+package com.android.systemui.statusbar;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.INotificationManager;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -43,8 +45,6 @@ import android.view.View.OnClickListener;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
@@ -77,13 +77,9 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
private TextView mImportanceTitle;
private boolean mAuto;
- private View mImportanceGroup;
- private View mChannelDisabled;
+ private TextView mNumChannelsView;
+ private View mChannelDisabledView;
private Switch mChannelEnabledSwitch;
- private RadioButton mMinImportanceButton;
- private RadioButton mLowImportanceButton;
- private RadioButton mDefaultImportanceButton;
- private RadioButton mHighImportanceButton;
private GutsInteractionListener mGutsInteractionListener;
@@ -124,6 +120,19 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
// app is gone, just show package name and generic icon
pkgicon = pm.getDefaultActivityIcon();
}
+ ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
+
+ int numChannels = 1;
+ try {
+ numChannels = iNotificationManager.getNumNotificationChannelsForPackage(
+ pkg, appUid, false /* includeDeleted */);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+
+ mNumChannelsView = (TextView) (findViewById(R.id.num_channels_desc));
+ mNumChannelsView.setText(String.format(mContext.getResources().getQuantityString(
+ R.plurals.notification_num_channels_desc, numChannels), numChannels));
// If this is the placeholder channel, don't use our channel-specific text.
String appNameText;
@@ -138,24 +147,31 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
((TextView) findViewById(R.id.pkgname)).setText(appNameText);
((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
- // Settings button.
- final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
- if (appUid >= 0 && onSettingsClick != null) {
- final int appUidF = appUid;
- settingsButton.setOnClickListener(
- (View view) -> {
- onSettingsClick.onClick(view, appUidF);
- });
- settingsButton.setText(R.string.notification_more_settings);
+ // Set group information if this channel has an associated group.
+ CharSequence groupName = null;
+ if (channel.getGroup() != null) {
+ try {
+ final NotificationChannelGroup notificationChannelGroup =
+ iNotificationManager.getNotificationChannelGroupForPackage(
+ channel.getGroup(), pkg, appUid);
+ if (notificationChannelGroup != null) {
+ groupName = notificationChannelGroup.getName();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+ TextView groupNameView = ((TextView) findViewById(R.id.group_name));
+ TextView groupDividerView = ((TextView) findViewById(R.id.pkg_group_divider));
+ if (groupName != null) {
+ groupNameView.setText(groupName);
+ groupNameView.setVisibility(View.VISIBLE);
+ groupDividerView.setVisibility(View.VISIBLE);
} else {
- settingsButton.setVisibility(View.GONE);
+ groupNameView.setVisibility(View.GONE);
+ groupDividerView.setVisibility(View.GONE);
}
- // Done button.
- final TextView doneButton = (TextView) findViewById(R.id.done);
- doneButton.setText(R.string.notification_done);
- doneButton.setOnClickListener(onDoneClick);
-
boolean nonBlockable = false;
try {
final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
@@ -167,53 +183,41 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
nonBlockable |= nonBlockablePkgs.contains(pkg);
}
- final View importanceButtons = findViewById(R.id.importance_buttons);
- bindToggles(importanceButtons, mStartingUserImportance, nonBlockable);
-
- // Importance Text (hardcoded to 4 importance levels)
- final ViewGroup importanceTextGroup = (ViewGroup) findViewById(
- R.id.importance_buttons_text);
- final int size = importanceTextGroup.getChildCount();
- for (int i = 0; i < size; i++) {
- int importanceNameResId = 0;
- int importanceDescResId = 0;
- switch (i) {
- case 0:
- importanceNameResId = R.string.high_importance;
- importanceDescResId = R.string.notification_importance_high;
- break;
- case 1:
- importanceNameResId = R.string.default_importance;
- importanceDescResId = R.string.notification_importance_default;
- break;
- case 2:
- importanceNameResId = R.string.low_importance;
- importanceDescResId = R.string.notification_importance_low;
- break;
- case 3:
- importanceNameResId = R.string.min_importance;
- importanceDescResId = R.string.notification_importance_min;
- break;
- default:
- Log.e(TAG, "Too many importance groups in this layout.");
- break;
+ bindButtons(nonBlockable);
+
+ // Top-level importance group
+ mChannelDisabledView = findViewById(R.id.channel_disabled);
+ updateImportanceDisplay();
+
+ // Settings button.
+ final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
+ if (appUid >= 0 && onSettingsClick != null) {
+ final int appUidF = appUid;
+ settingsButton.setOnClickListener(
+ (View view) -> {
+ onSettingsClick.onClick(view, appUidF);
+ });
+ if (numChannels > 1) {
+ settingsButton.setText(R.string.notification_all_categories);
+ } else {
+ settingsButton.setText(R.string.notification_more_settings);
}
- final ViewGroup importanceChildGroup = (ViewGroup) importanceTextGroup.getChildAt(i);
- ((TextView) importanceChildGroup.getChildAt(0)).setText(importanceNameResId);
- ((TextView) importanceChildGroup.getChildAt(1)).setText(importanceDescResId);
+
+ } else {
+ settingsButton.setVisibility(View.GONE);
}
- // Top-level importance group
- mImportanceGroup = findViewById(R.id.importance);
- mChannelDisabled = findViewById(R.id.channel_disabled);
- updateImportanceGroup();
+ // Done button.
+ final TextView doneButton = (TextView) findViewById(R.id.done);
+ doneButton.setText(R.string.notification_done);
+ doneButton.setOnClickListener(onDoneClick);
}
public boolean hasImportanceChanged() {
return mStartingUserImportance != getSelectedImportance();
}
- public void saveImportance() {
+ private void saveImportance() {
int selectedImportance = getSelectedImportance();
if (selectedImportance == mStartingUserImportance) {
return;
@@ -233,73 +237,37 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
private int getSelectedImportance() {
if (!mChannelEnabledSwitch.isChecked()) {
return NotificationManager.IMPORTANCE_NONE;
- } else if (mMinImportanceButton.isChecked()) {
- return NotificationManager.IMPORTANCE_MIN;
- } else if (mLowImportanceButton.isChecked()) {
- return NotificationManager.IMPORTANCE_LOW;
- } else if (mDefaultImportanceButton.isChecked()) {
- return NotificationManager.IMPORTANCE_DEFAULT;
- } else if (mHighImportanceButton.isChecked()) {
- return NotificationManager.IMPORTANCE_HIGH;
} else {
- return NotificationManager.IMPORTANCE_UNSPECIFIED;
+ return mStartingUserImportance;
}
}
- private void bindToggles(final View importanceButtons, final int importance,
- final boolean nonBlockable) {
+ private void bindButtons(final boolean nonBlockable) {
// Enabled Switch
mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
- mChannelEnabledSwitch.setChecked(importance != NotificationManager.IMPORTANCE_NONE);
+ mChannelEnabledSwitch.setChecked(
+ mStartingUserImportance != NotificationManager.IMPORTANCE_NONE);
mChannelEnabledSwitch.setVisibility(nonBlockable ? View.INVISIBLE : View.VISIBLE);
- // Importance Buttons
- mMinImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.min_importance);
- mLowImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.low_importance);
- mDefaultImportanceButton = (RadioButton) importanceButtons
- .findViewById(R.id.default_importance);
- mHighImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.high_importance);
-
- // Set to current importance setting
- switch (importance) {
- case NotificationManager.IMPORTANCE_UNSPECIFIED:
- case NotificationManager.IMPORTANCE_NONE:
- break;
- case NotificationManager.IMPORTANCE_MIN:
- mMinImportanceButton.setChecked(true);
- break;
- case NotificationManager.IMPORTANCE_LOW:
- mLowImportanceButton.setChecked(true);
- break;
- case NotificationManager.IMPORTANCE_DEFAULT:
- mDefaultImportanceButton.setChecked(true);
- break;
- case NotificationManager.IMPORTANCE_HIGH:
- case NotificationManager.IMPORTANCE_MAX:
- mHighImportanceButton.setChecked(true);
- break;
- }
-
// Callback when checked.
mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
- mGutsInteractionListener.onInteraction(NotificationInfo.this);
- updateImportanceGroup();
+ if (mGutsInteractionListener != null) {
+ mGutsInteractionListener.onInteraction(NotificationInfo.this);
+ }
+ updateImportanceDisplay();
});
- ((RadioGroup) importanceButtons).setOnCheckedChangeListener(
- (buttonView, isChecked) -> {
- mGutsInteractionListener.onInteraction(NotificationInfo.this);
- });
}
- private void updateImportanceGroup() {
+ private void updateImportanceDisplay() {
final boolean disabled = getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
- mImportanceGroup.setVisibility(disabled ? View.GONE : View.VISIBLE);
- mChannelDisabled.setVisibility(disabled ? View.VISIBLE : View.GONE);
- }
-
- public void closeControls() {
- if (mGutsInteractionListener != null) {
- mGutsInteractionListener.closeGuts(this);
+ mChannelDisabledView.setVisibility(disabled ? View.VISIBLE : View.GONE);
+ if (disabled) {
+ // To be replaced by disabled text.
+ mNumChannelsView.setVisibility(View.GONE);
+ } else if (mNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+ mNumChannelsView.setVisibility(View.INVISIBLE);
+ } else {
+ mNumChannelsView.setVisibility(View.VISIBLE);
}
}
@@ -314,7 +282,10 @@ public class NotificationInfo extends LinearLayout implements GutsContent {
}
@Override
- public boolean handleCloseControls() {
+ public boolean handleCloseControls(boolean save) {
+ if (save) {
+ saveImportance();
+ }
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 1992b6c9ccdd..0657dc1e86f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -195,7 +195,7 @@ public class NotificationSnooze extends LinearLayout
}
@Override
- public boolean handleCloseControls() {
+ public boolean handleCloseControls(boolean save) {
// When snooze is closed (i.e. there was interaction outside of the notification)
// then we commit the snooze action.
if (mSnoozeListener != null && mSelectedOption != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 365d99165121..bc43663ba261 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -5807,7 +5807,6 @@ public class StatusBar extends SystemUI implements DemoMode,
private void saveAndCloseNotificationMenu(NotificationInfo info,
ExpandableNotificationRow row, NotificationGuts guts, View done) {
guts.resetFalsingCheck();
- info.saveImportance();
int[] rowLocation = new int[2];
int[] doneLocation = new int[2];
row.getLocationOnScreen(rowLocation);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 3e0d15d3cb69..0491fc40a865 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -20,6 +20,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
@@ -32,38 +33,42 @@ import static org.mockito.Mockito.when;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
import android.graphics.drawable.Drawable;
import android.service.notification.StatusBarNotification;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
-import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
+import com.android.internal.util.CharSequences;
import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.mockito.Mockito;
+import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class NotificationGutsTest {
+public class NotificationInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
private static final String TEST_CHANNEL = "test_channel";
private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
- private NotificationGuts mNotificationGuts;
private NotificationInfo mNotificationInfo;
private final INotificationManager mMockINotificationManager = mock(INotificationManager.class);
private final PackageManager mMockPackageManager = mock(PackageManager.class);
@@ -76,12 +81,9 @@ public class NotificationGutsTest {
public void setUp() throws Exception {
// Inflate the layout
final LayoutInflater layoutInflater =
- LayoutInflater.from(InstrumentationRegistry.getTargetContext());
+ LayoutInflater.from(mContext);
mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
null);
- mNotificationGuts = (NotificationGuts) layoutInflater.inflate(R.layout.notification_guts,
- null);
- mNotificationInfo.setInteractionListener(mNotificationGuts);
// PackageManager must return a packageInfo and applicationInfo.
final PackageInfo packageInfo = new PackageInfo();
@@ -96,6 +98,20 @@ public class NotificationGutsTest {
mNotificationChannel = new NotificationChannel(
TEST_CHANNEL, TEST_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
when(mMockStatusBarNotification.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+ when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(1);
+ }
+
+ private CharSequence getStringById(int resId) {
+ return mContext.getString(resId);
+ }
+
+ private CharSequence getNumChannelsString(int numChannels) {
+ return String.format(
+ mContext.getResources().getQuantityString(
+ R.plurals.notification_num_channels_desc, numChannels),
+ numChannels);
}
@Test
@@ -110,6 +126,49 @@ public class NotificationGutsTest {
@Test
@UiThreadTest
+ public void testBindNotification_SetsPackageIcon() throws Exception {
+ final Drawable iconDrawable = mock(Drawable.class);
+ when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
+ .thenReturn(iconDrawable);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
+ assertEquals(iconDrawable, iconView.getDrawable());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
+ assertEquals(View.GONE, groupNameView.getVisibility());
+ final TextView groupDividerView =
+ (TextView) mNotificationInfo.findViewById(R.id.pkg_group_divider);
+ assertEquals(View.GONE, groupDividerView.getVisibility());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testBindNotification_SetsGroupNameIfNonNull() throws Exception {
+ mNotificationChannel.setGroup("test_group_id");
+ final NotificationChannelGroup notificationChannelGroup =
+ new NotificationChannelGroup("test_group_id", "Test Group Name");
+ when(mMockINotificationManager.getNotificationChannelGroupForPackage(
+ eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt()))
+ .thenReturn(notificationChannelGroup);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
+ assertEquals(View.VISIBLE, groupNameView.getVisibility());
+ assertEquals("Test Group Name", groupNameView.getText());
+ final TextView groupDividerView =
+ (TextView) mNotificationInfo.findViewById(R.id.pkg_group_divider);
+ assertEquals(View.VISIBLE, groupDividerView.getVisibility());
+ }
+
+ @Test
+ @UiThreadTest
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -125,7 +184,7 @@ public class NotificationGutsTest {
mMockStatusBarNotification, mNotificationChannel,
(View v, int appUid) -> { latch.countDown(); }, null, null);
- final TextView settingsButton =
+ final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
settingsButton.performClick();
// Verify that listener was triggered.
@@ -134,6 +193,30 @@ public class NotificationGutsTest {
@Test
@UiThreadTest
+ public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, (View v, int appUid) -> {}, null,
+ null);
+ final TextView settingsButton =
+ (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testBindNotification_SettingsTextWithMultipleChannels() throws Exception {
+ when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, (View v, int appUid) -> {}, null,
+ null);
+ final TextView settingsButton =
+ (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText());
+ }
+
+ @Test
+ @UiThreadTest
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -149,33 +232,85 @@ public class NotificationGutsTest {
@Test
@UiThreadTest
- public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
+ public void testBindNotification_NumChannelsTextHiddenWhenDefaultChannel() throws Exception {
+ final NotificationChannel defaultChannel = new NotificationChannel(
+ NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, defaultChannel, null, null, null);
+ final TextView numChannelsView =
+ (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+ assertTrue(numChannelsView.getVisibility() != View.VISIBLE);
+ }
+
+ @Test
+ @UiThreadTest
+ public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
+ throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- assertFalse(mNotificationInfo.hasImportanceChanged());
+ final TextView numChannelsView =
+ (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+ assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
+ assertEquals(getNumChannelsString(1), numChannelsView.getText());
}
@Test
@UiThreadTest
- public void testHasImportanceChanged_ReturnsTrueAfterButtonChecked() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ public void testBindNotification_NumChannelsTextScalesWithNumberOfChannels()
+ throws Exception {
+ when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- // Find the high button and check it.
- RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
- highButton.setChecked(true);
- assertTrue(mNotificationInfo.hasImportanceChanged());
+ final TextView numChannelsView =
+ (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+ assertEquals(getNumChannelsString(2), numChannelsView.getText());
}
@Test
@UiThreadTest
- public void testImportanceButtonCheckedBasedOnInitialImportance() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_HIGH);
+ public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ final TextView channelDisabledView =
+ (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
+ assertEquals(channelDisabledView.getVisibility(), View.GONE);
+ }
- RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
- assertTrue(highButton.isChecked());
+ @Test
+ @UiThreadTest
+ public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ final TextView channelDisabledView =
+ (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
+ assertEquals(channelDisabledView.getVisibility(), View.VISIBLE);
+ // Replaces the numChannelsView
+ final TextView numChannelsView =
+ (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+ assertEquals(numChannelsView.getVisibility(), View.GONE);
+ }
+
+ @Test
+ @UiThreadTest
+ public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ assertFalse(mNotificationInfo.hasImportanceChanged());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ // Find the high button and check it.
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
+ assertTrue(mNotificationInfo.hasImportanceChanged());
}
@Test
@@ -194,60 +329,57 @@ public class NotificationGutsTest {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
- highButton.setChecked(true);
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@Test
@UiThreadTest
- public void testSaveImportance_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception {
+ public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
+ throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- mNotificationInfo.saveImportance();
+ mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@Test
@UiThreadTest
- public void testSaveImportance_DoesNotUpdateNotificationChannelIfUnspecified()
+ public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- mNotificationInfo.saveImportance();
+ mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@Test
@UiThreadTest
- public void testSaveImportance_CallsUpdateNotificationChannelIfChanged() throws Exception {
+ public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
- RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
- highButton.setChecked(true);
- mNotificationInfo.saveImportance();
- verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
- eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
- assertEquals(NotificationManager.IMPORTANCE_HIGH, mNotificationChannel.getImportance());
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ assertTrue(enabledSwitch.isChecked());
}
@Test
@UiThreadTest
- public void testEnabledSwitchOnByDefault() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertTrue(enabledSwitch.isChecked());
+ assertFalse(enabledSwitch.isChecked());
}
@Test
@@ -283,23 +415,23 @@ public class NotificationGutsTest {
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
- mNotificationInfo.saveImportance();
+ mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
@Test
@UiThreadTest
- public void testEnabledSwitchOverridesOtherButtons() throws Exception {
+ public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- mMockStatusBarNotification, mNotificationChannel, null, null, null);
+ mMockStatusBarNotification, mNotificationChannel, null, null,
+ Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- RadioButton lowButton = (RadioButton) mNotificationInfo.findViewById(R.id.low_importance);
- lowButton.setChecked(true);
enabledSwitch.setChecked(false);
- mNotificationInfo.saveImportance();
- assertEquals(NotificationManager.IMPORTANCE_NONE, mNotificationChannel.getImportance());
+ mNotificationInfo.handleCloseControls(false);
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cc3fc003c918..19c9d9b0edb3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1678,11 +1678,19 @@ public class NotificationManagerService extends SystemService {
@Override
public ParceledListSlice<NotificationChannel> getNotificationChannelsForPackage(String pkg,
int uid, boolean includeDeleted) {
- checkCallerIsSystem();
+ enforceSystemOrSystemUI("getNotificationChannelsForPackage");
return mRankingHelper.getNotificationChannels(pkg, uid, includeDeleted);
}
@Override
+ public int getNumNotificationChannelsForPackage(String pkg, int uid,
+ boolean includeDeleted) {
+ enforceSystemOrSystemUI("getNumNotificationChannelsForPackage");
+ return mRankingHelper.getNotificationChannels(pkg, uid, includeDeleted)
+ .getList().size();
+ }
+
+ @Override
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
String pkg, int uid, boolean includeDeleted) {
checkCallerIsSystem();
@@ -1690,13 +1698,19 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ public NotificationChannelGroup getNotificationChannelGroupForPackage(
+ String groupId, String pkg, int uid) {
+ enforceSystemOrSystemUI("getNotificationChannelGroupForPackage");
+ return mRankingHelper.getNotificationChannelGroup(groupId, pkg, uid);
+ }
+
+ @Override
public ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg) {
checkCallerIsSystemOrSameApp(pkg);
return mRankingHelper.getNotificationChannels(
pkg, Binder.getCallingUid(), false /* includeDeleted */);
}
-
@Override
public void clearData(String packageName, int uid, boolean fromApp) throws RemoteException {
checkCallerIsSystem();
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 46c449bcab8e..76890b1dc79d 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -670,6 +670,13 @@ public class RankingHelper implements RankingConfig {
}
}
+ public NotificationChannelGroup getNotificationChannelGroup(String groupId, String pkg,
+ int uid) {
+ Preconditions.checkNotNull(pkg);
+ Record r = getRecord(pkg, uid);
+ return r.groups.get(groupId);
+ }
+
@Override
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid, boolean includeDeleted) {