summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulia Reynolds <juliacr@google.com>2018-01-03 12:27:24 -0500
committerJulia Reynolds <juliacr@google.com>2018-01-10 12:56:57 -0500
commit437cdb146498cbfabd6ed0c2466fc5349b0f1d65 (patch)
tree9bd4b70839591b1413550c86891355e4db3a3749
parent41eae630b38e49fd031d5ee14a06a9bb62a77d49 (diff)
Inline noti blocking is now in the form of a question
And has an 'undo' flow that matches snoozing. Test: runtest systemui Bug: 63927402 Change-Id: Idc17b8d950bc3da7ec9fe035dc8a65146d12c456
-rw-r--r--core/res/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/res/drawable/ic_info.xml25
-rw-r--r--packages/SystemUI/res/layout/notification_info.xml148
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/res/values/strings.xml45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java363
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java635
-rw-r--r--tests/testables/src/android/testing/PollingCheck.java94
9 files changed, 537 insertions, 790 deletions
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index a659b370560f..14d4c02a8d39 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -193,10 +193,10 @@
<dimen name="notification_header_background_height">49.5dp</dimen>
<!-- The top padding for the notification header -->
- <dimen name="notification_header_padding_top">14dp</dimen>
+ <dimen name="notification_header_padding_top">16dp</dimen>
<!-- The bottom padding for the notification header -->
- <dimen name="notification_header_padding_bottom">13dp</dimen>
+ <dimen name="notification_header_padding_bottom">16dp</dimen>
<!-- The margin at the bottom of the notification header. -->
<dimen name="notification_header_margin_bottom">5dp</dimen>
diff --git a/packages/SystemUI/res/drawable/ic_info.xml b/packages/SystemUI/res/drawable/ic_info.xml
new file mode 100644
index 000000000000..1eb4004ac778
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_info.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2018 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
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M22,34h4L26,22h-4v12zM24,4C12.95,4 4,12.95 4,24s8.95,20 20,20 20,-8.95 20,-20S35.05,4 24,4zM24,40c-8.82,0 -16,-7.18 -16,-16S15.18,8 24,8s16,7.18 16,16 -7.18,16 -16,16zM22,18h4v-4h-4v4z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 2e35d8673635..6b5bd1260acc 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -23,23 +23,22 @@
android:clickable="true"
android:orientation="vertical"
android:paddingStart="@*android:dimen/notification_content_margin_start"
+ android:paddingEnd="@*android:dimen/notification_content_margin_end"
android:background="@color/notification_guts_bg_color"
android:theme="@*android:style/Theme.DeviceDefault.Light">
<!-- Package Info -->
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
- android:layout_height="@*android:dimen/notification_header_height"
+ android:layout_height="@dimen/notification_guts_header_height"
android:clipChildren="false"
- android:paddingTop="@*android:dimen/notification_header_padding_top"
- android:paddingBottom="@*android:dimen/notification_header_padding_bottom"
- android:gravity="center_vertical"
- android:orientation="horizontal" >
+ android:clipToPadding="false"
+ android:layout_marginTop="@*android:dimen/notification_header_padding_top" >
<ImageView
android:id="@+id/pkgicon"
- android:layout_width="@*android:dimen/notification_header_icon_size"
- android:layout_height="@*android:dimen/notification_header_icon_size"
- android:layout_marginEnd="3dp"/>
+ android:layout_width="@dimen/notification_guts_header_height"
+ android:layout_height="@dimen/notification_guts_header_height"
+ android:layout_marginEnd="3dp" />
<TextView
android:id="@+id/pkgname"
android:layout_width="wrap_content"
@@ -47,7 +46,9 @@
android:textAppearance="@*android:style/TextAppearance.Material.Notification.Info"
android:layout_marginStart="3dp"
android:layout_marginEnd="2dp"
- android:singleLine="true"/>
+ android:singleLine="true"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/pkgicon" />
<TextView
android:id="@+id/pkg_group_divider"
android:layout_width="wrap_content"
@@ -55,7 +56,9 @@
android:textAppearance="@*android:style/TextAppearance.Material.Notification.Info"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
- android:text="@*android:string/notification_header_divider_symbol"/>
+ android:text="@*android:string/notification_header_divider_symbol"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/pkgname" />
<TextView
android:id="@+id/group_name"
android:layout_width="wrap_content"
@@ -64,82 +67,103 @@
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
- android:maxLines="1"/>
- </LinearLayout>
+ android:maxLines="1"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/pkg_group_divider" />
+ <ImageButton
+ android:id="@+id/info"
+ android:src="@drawable/ic_info"
+ android:tint="?android:attr/colorAccent"
+ android:layout_width="@dimen/notification_guts_header_height"
+ android:layout_height="@dimen/notification_guts_header_height"
+ android:contentDescription="@string/notification_more_settings"
+ android:background="@drawable/ripple_drawable"
+ android:layout_alignParentEnd="true" />
+ </RelativeLayout>
- <!-- Channel Info Block -->
<LinearLayout
+ android:id="@+id/prompt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="20dp"
- android:layout_marginEnd="@*android:dimen/notification_content_margin_end"
+ android:layout_marginBottom="@dimen/notification_guts_button_spacing"
+ android:layout_marginTop="@*android:dimen/notification_header_padding_top"
android:orientation="vertical">
- <!-- Channel Text -->
+
+ <!-- Channel Info Block -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:orientation="vertical">
<!-- Channel Name -->
<TextView
android:id="@+id/channel_name"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginBottom="6dp"
style="@style/TextAppearance.NotificationInfo.Primary" />
- <!-- Ban Channel Switch -->
- <Switch
- android:id="@+id/channel_enabled_switch"
+ <!-- Question prompt -->
+ <TextView
+ android:id="@+id/block_prompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="end|center_vertical"
- android:contentDescription="@string/notification_channel_switch_accessibility"
- android:background="@null" />
+ style="@style/TextAppearance.NotificationInfo.Secondary" />
</LinearLayout>
- <!-- Secondary Text - only one shows at a time -->
- <TextView
- android:id="@+id/channel_disabled"
- android:layout_width="wrap_content"
+
+ <!-- Settings and Done buttons -->
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/notification_channel_disabled"
- style="@style/TextAppearance.NotificationInfo.Secondary.Warning" />
+ android:orientation="horizontal"
+ android:layout_marginTop="@dimen/notification_guts_button_spacing"
+ android:gravity="end" >
+
+ <!-- Optional link to app. Only appears if the channel is not disabled and the app
+ asked for it -->
+ <TextView
+ android:id="@+id/app_settings"
+ android:text="@string/notification_app_settings"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:ellipsize="end"
+ android:maxLines="1"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/block"
+ android:text="@string/inline_stop_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/keep"
+ android:text="@string/inline_keep_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="-8dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ </LinearLayout>
+ </LinearLayout>
+ <RelativeLayout
+ android:id="@+id/confirmation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_guts_button_spacing"
+ android:layout_marginTop="@*android:dimen/notification_header_padding_top"
+ android:visibility="gone"
+ android:orientation="horizontal" >
<TextView
- android:id="@+id/num_channels_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/notification_channel_disabled"
- style="@style/TextAppearance.NotificationInfo.Secondary" />
- <!-- Optional link to app. Only appears if the channel is not disabled -->
+ style="@style/TextAppearance.NotificationInfo.Secondary.Warning"/>
<TextView
- android:id="@+id/app_settings"
+ android:id="@+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:visibility="gone"
- android:ellipsize="end"
- android:maxLines="1"
- style="@style/TextAppearance.NotificationInfo.Secondary.Link"/>
- </LinearLayout>
-
- <!-- Settings and Done buttons -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="48dp"
- android:orientation="horizontal"
- android:gravity="end"
- android:layout_marginEnd="@*android:dimen/notification_content_margin_end"
- android:layout_marginBottom="8dp" >
- <TextView
- android:id="@+id/more_settings"
- android:text="@string/notification_more_settings"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginEnd="8dp"
+ android:text="@string/inline_undo"
+ android:layout_alignParentEnd="true"
+ android:layout_marginEnd="-8dp"
style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/done"
- android:text="@string/notification_done"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </LinearLayout>
+ </RelativeLayout>
</com.android.systemui.statusbar.NotificationInfo>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 60e9ebf4ba5d..8f2068111cd8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -148,6 +148,12 @@
<!-- The space around a notification menu item -->
<dimen name="notification_menu_icon_padding">20dp</dimen>
+ <!-- The veritical space around the buttons in the inline settings -->
+ <dimen name="notification_guts_button_spacing">20dp</dimen>
+
+ <!-- The height of the header in inline settings -->
+ <dimen name="notification_guts_header_height">24dp</dimen>
+
<!-- The minimum height for the snackbar shown after the snooze option has been chosen. -->
<dimen name="snooze_snackbar_min_height">56dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 98537a102e1a..a19917d91667 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1445,38 +1445,22 @@
<string name="notification_header_default_channel">Notifications</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>
+ <string name="notification_channel_disabled">You won\'t see these notifications anymore</string>
- <!-- Notification: Control panel: Label that shows how many channels are included in this bundle
- of notifications. Replaces the channel name and only appears when there is more than one channel. -->
- <string name="notification_num_channels"> <xliff:g id="number">%d</xliff:g> notification categories</string>
+ <!-- Notification Inline controls: continue receiving notifications prompt, channel level -->
+ <string name="inline_keep_showing">Keep showing these notifications?</string>
- <!-- Notification: Control panel: Label that shows when an app has not upgraded to use channels.
- Hints that the user's only option is to block all of the app's notifications. -->
- <string name="notification_default_channel_desc">This app doesn\'t have notification categories</string>
+ <!-- Notification inline controls: block notifications button -->
+ <string name="inline_stop_button">Stop notifications</string>
- <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
- <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string>
+ <!-- Notification inline controls: keep getting notifications button -->
+ <string name="inline_keep_button">Keep showing</string>
- <!-- Notification: Control panel: Label that shows how many channels this application has
- defined, describing the current notification channel as "1 out of n notification categories from this app". -->
- <plurals name="notification_num_channels_desc">
- <item quantity="one">1 out of <xliff:g id="number">%s</xliff:g> notification category from this app</item>
- <item quantity="other">1 out of <xliff:g id="number">%s</xliff:g> notification categories from this app</item>
- </plurals>
+ <!-- Notification Inline controls: continue receiving notifications prompt, app level -->
+ <string name="inline_keep_showing_app">Keep showing notifications from this app?</string>
- <!-- Notification: Control panel: For bundles of notifications, this label that lists the
- channels used by the contained notifications. The first two channels are listed by name,
- followed by "and N others"
- Example: "Friend requests, Friend confirmations"
- Example: "Friend requests, Friend confirmations, and 1 other"
- Example: "Friend requests, Friend confirmations, and 2 others"
- -->
- <string name="notification_channels_list_desc_2"><xliff:g id="channel_name_1">%1$s</xliff:g>, <xliff:g id="channel_name_2">%2$s</xliff:g></string>
- <plurals name="notification_channels_list_desc_2_and_others">
- <item quantity="one"><xliff:g id="channel_name_1">%1$s</xliff:g>, <xliff:g id="channel_name_2">%2$s</xliff:g>, and <xliff:g id="number">%3$d</xliff:g> other</item>
- <item quantity="other"><xliff:g id="channel_name_1">%1$s</xliff:g>, <xliff:g id="channel_name_2">%2$s</xliff:g>, and <xliff:g id="number">%3$d</xliff:g> others</item>
- </plurals>
+ <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
+ <string name="notification_unblockable_desc">These notifications can\'t be turned off</string>
<!-- Notification: Control panel: Accessibility description for expanded inline controls view, used
to control settings about notifications related to the current notification. -->
@@ -1488,16 +1472,15 @@
or disable notifications from this channel -->
<string name="notification_channel_switch_accessibility">Allow notifications from this channel</string>
<!-- 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 a link that launches notification settings in the
app that sent the notification. -->
- <string name="notification_app_settings">Customize: <xliff:g id="sub_category" example="Work chats">%1$s</xliff:g></string>
+ <string name="notification_app_settings">Customize</string>
<!-- Notification: Control panel: Label for button that dismisses control panel. [CHAR LIMIT=NONE] -->
<string name="notification_done">Done</string>
+ <!-- Notification: inline controls: undo block button -->
+ <string name="inline_undo">Undo</string>
<!-- Notification: Menu row: Content description for menu items. [CHAR LIMIT=NONE] -->
<string name="notification_menu_accessibility"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> <xliff:g id="menu_description" example="notification controls">%2$s</xliff:g></string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
index 87ad6f6bc948..441c18431894 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
@@ -229,10 +229,9 @@ public class NotificationGutsManager implements Dumpable {
}
}
try {
- info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels),
- row.getEntry().channel.getImportance(), sbn, onSettingsClick,
- onAppSettingsClick, onDoneClick, mCheckSaveListener,
- mNonBlockablePkgs);
+ info.bindNotification(pmUser, iNotificationManager, pkg, row.getEntry().channel,
+ channels.size(), sbn, mCheckSaveListener, onSettingsClick,
+ onAppSettingsClick, mNonBlockablePkgs);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 8d1bb5fe940d..6279fdc46599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -18,6 +18,10 @@ package com.android.systemui.statusbar;
import static android.app.NotificationManager.IMPORTANCE_NONE;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -38,12 +42,12 @@ import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.Switch;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import java.lang.IllegalArgumentException;
@@ -57,25 +61,37 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private static final String TAG = "InfoGuts";
private INotificationManager mINotificationManager;
+ private PackageManager mPm;
+
private String mPkg;
private String mAppName;
private int mAppUid;
- private List<NotificationChannel> mNotificationChannels;
+ private int mNumNotificationChannels;
private NotificationChannel mSingleNotificationChannel;
+ private int mStartingUserImportance;
+ private int mChosenImportance;
private boolean mIsSingleDefaultChannel;
+ private boolean mNonblockable;
private StatusBarNotification mSbn;
- private int mStartingUserImportance;
+ private AnimatorSet mExpandAnimation;
- private TextView mNumChannelsView;
- private View mChannelDisabledView;
- private TextView mSettingsLinkView;
- private Switch mChannelEnabledSwitch;
private CheckSaveListener mCheckSaveListener;
+ private OnSettingsClickListener mOnSettingsClickListener;
private OnAppSettingsClickListener mAppSettingsClickListener;
- private PackageManager mPm;
-
private NotificationGuts mGutsContainer;
+ private OnClickListener mOnKeepShowing = v -> {
+ closeControls(v);
+ };
+
+ private OnClickListener mOnStopNotifications = v -> {
+ swapContent(false);
+ };
+
+ private OnClickListener mOnUndo = v -> {
+ swapContent(true);
+ };
+
public NotificationInfo(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -98,141 +114,93 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
public void bindNotification(final PackageManager pm,
final INotificationManager iNotificationManager,
final String pkg,
- final List<NotificationChannel> notificationChannels,
- int startingUserImportance,
+ final NotificationChannel notificationChannel,
+ final int numChannels,
final StatusBarNotification sbn,
- OnSettingsClickListener onSettingsClick,
- OnAppSettingsClickListener onAppSettingsClick,
- OnClickListener onDoneClick,
- CheckSaveListener checkSaveListener,
+ final CheckSaveListener checkSaveListener,
+ final OnSettingsClickListener onSettingsClick,
+ final OnAppSettingsClickListener onAppSettingsClick,
final Set<String> nonBlockablePkgs)
throws RemoteException {
mINotificationManager = iNotificationManager;
mPkg = pkg;
- mNotificationChannels = notificationChannels;
- mCheckSaveListener = checkSaveListener;
+ mNumNotificationChannels = numChannels;
mSbn = sbn;
mPm = pm;
mAppSettingsClickListener = onAppSettingsClick;
- mStartingUserImportance = startingUserImportance;
mAppName = mPkg;
- Drawable pkgicon = null;
- CharSequence channelNameText = "";
- ApplicationInfo info = null;
- try {
- info = pm.getApplicationInfo(mPkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (info != null) {
- mAppUid = sbn.getUid();
- mAppName = String.valueOf(pm.getApplicationLabel(info));
- pkgicon = pm.getApplicationIcon(info);
- }
- } catch (PackageManager.NameNotFoundException e) {
- // app is gone, just show package name and generic icon
- pkgicon = pm.getDefaultActivityIcon();
- }
- ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
+ mCheckSaveListener = checkSaveListener;
+ mOnSettingsClickListener = onSettingsClick;
+ mSingleNotificationChannel = notificationChannel;
+ mStartingUserImportance = mChosenImportance = mSingleNotificationChannel.getImportance();
- int numTotalChannels = iNotificationManager.getNumNotificationChannelsForPackage(
+ int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */);
- if (mNotificationChannels.isEmpty()) {
+ if (mNumNotificationChannels == 0) {
throw new IllegalArgumentException("bindNotification requires at least one channel");
} else {
- if (mNotificationChannels.size() == 1) {
- mSingleNotificationChannel = mNotificationChannels.get(0);
- // Special behavior for the Default channel if no other channels have been defined.
- mIsSingleDefaultChannel =
- (mSingleNotificationChannel.getId()
- .equals(NotificationChannel.DEFAULT_CHANNEL_ID) &&
- numTotalChannels <= 1);
- } else {
- mSingleNotificationChannel = null;
- mIsSingleDefaultChannel = false;
- }
+ // Special behavior for the Default channel if no other channels have been defined.
+ mIsSingleDefaultChannel = mNumNotificationChannels == 1
+ && mSingleNotificationChannel.getId()
+ .equals(NotificationChannel.DEFAULT_CHANNEL_ID)
+ && numTotalChannels <= 1;
}
- boolean nonBlockable = false;
try {
final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) {
- final int numChannels = mNotificationChannels.size();
- for (int i = 0; i < numChannels; i++) {
- final NotificationChannel notificationChannel = mNotificationChannels.get(i);
- // If any of the system channels is not blockable, the bundle is nonblockable
- if (!notificationChannel.isBlockableSystem()) {
- nonBlockable = true;
- break;
- }
+ if (mSingleNotificationChannel != null
+ && !mSingleNotificationChannel.isBlockableSystem()) {
+ mNonblockable = true;
}
}
} catch (PackageManager.NameNotFoundException e) {
// unlikely.
}
if (nonBlockablePkgs != null) {
- nonBlockable |= nonBlockablePkgs.contains(pkg);
+ mNonblockable |= nonBlockablePkgs.contains(pkg);
}
+ mNonblockable |= (mNumNotificationChannels > 1);
- String channelsDescText;
- mNumChannelsView = findViewById(R.id.num_channels_desc);
- if (nonBlockable) {
- channelsDescText = mContext.getString(R.string.notification_unblockable_desc);
- } else if (mIsSingleDefaultChannel) {
- channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
- } else {
- switch (mNotificationChannels.size()) {
- case 1:
- channelsDescText = String.format(mContext.getResources().getQuantityString(
- R.plurals.notification_num_channels_desc, numTotalChannels),
- numTotalChannels);
- break;
- case 2:
- channelsDescText = mContext.getString(
- R.string.notification_channels_list_desc_2,
- mNotificationChannels.get(0).getName(),
- mNotificationChannels.get(1).getName());
- break;
- default:
- final int numOthers = mNotificationChannels.size() - 2;
- channelsDescText = String.format(
- mContext.getResources().getQuantityString(
- R.plurals.notification_channels_list_desc_2_and_others,
- numOthers),
- mNotificationChannels.get(0).getName(),
- mNotificationChannels.get(1).getName(),
- numOthers);
+ bindHeader();
+ bindPrompt();
+ bindButtons();
+ }
+
+ private void bindHeader() throws RemoteException {
+ // Package name
+ Drawable pkgicon = null;
+ ApplicationInfo info;
+ try {
+ info = mPm.getApplicationInfo(mPkg,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE);
+ if (info != null) {
+ mAppUid = mSbn.getUid();
+ mAppName = String.valueOf(mPm.getApplicationLabel(info));
+ pkgicon = mPm.getApplicationIcon(info);
}
+ } catch (PackageManager.NameNotFoundException e) {
+ // app is gone, just show package name and generic icon
+ pkgicon = mPm.getDefaultActivityIcon();
}
- mNumChannelsView.setText(channelsDescText);
-
- if (mSingleNotificationChannel == null) {
- // Multiple channels don't use a channel name for the title.
- channelNameText = mContext.getString(R.string.notification_num_channels,
- mNotificationChannels.size());
- } else if (mIsSingleDefaultChannel || nonBlockable) {
- // If this is the default channel or the app is unblockable,
- // don't use our channel-specific text.
- channelNameText = mContext.getString(R.string.notification_header_default_channel);
- } else {
- channelNameText = mSingleNotificationChannel.getName();
- }
+ ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
((TextView) findViewById(R.id.pkgname)).setText(mAppName);
- ((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
// Set group information if this channel has an associated group.
CharSequence groupName = null;
if (mSingleNotificationChannel != null && mSingleNotificationChannel.getGroup() != null) {
final NotificationChannelGroup notificationChannelGroup =
- iNotificationManager.getNotificationChannelGroupForPackage(
- mSingleNotificationChannel.getGroup(), pkg, mAppUid);
+ mINotificationManager.getNotificationChannelGroupForPackage(
+ mSingleNotificationChannel.getGroup(), mPkg, mAppUid);
if (notificationChannelGroup != null) {
groupName = notificationChannelGroup.getName();
}
}
- TextView groupNameView = ((TextView) findViewById(R.id.group_name));
- TextView groupDividerView = ((TextView) findViewById(R.id.pkg_group_divider));
+ TextView groupNameView = findViewById(R.id.group_name);
+ TextView groupDividerView = findViewById(R.id.pkg_group_divider);
if (groupName != null) {
groupNameView.setText(groupName);
groupNameView.setVisibility(View.VISIBLE);
@@ -242,53 +210,55 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
groupDividerView.setVisibility(View.GONE);
}
- bindButtons(nonBlockable);
-
- // Top-level importance group
- mChannelDisabledView = findViewById(R.id.channel_disabled);
- updateSecondaryText();
-
// Settings button.
- final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
- if (mAppUid >= 0 && onSettingsClick != null) {
+ final View settingsButton = findViewById(R.id.info);
+ if (mAppUid >= 0 && mOnSettingsClickListener != null) {
settingsButton.setVisibility(View.VISIBLE);
final int appUidF = mAppUid;
settingsButton.setOnClickListener(
(View view) -> {
- onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
+ mOnSettingsClickListener.onClick(view,
+ mNumNotificationChannels > 1 ? null : mSingleNotificationChannel,
+ appUidF);
});
- if (numTotalChannels <= 1 || nonBlockable) {
- settingsButton.setText(R.string.notification_more_settings);
- } else {
- settingsButton.setText(R.string.notification_all_categories);
- }
} else {
settingsButton.setVisibility(View.GONE);
}
+ }
- // Done button.
- final TextView doneButton = (TextView) findViewById(R.id.done);
- doneButton.setText(R.string.notification_done);
- doneButton.setOnClickListener(onDoneClick);
+ private void bindPrompt() {
+ final TextView channelName = findViewById(R.id.channel_name);
+ final TextView blockPrompt = findViewById(R.id.block_prompt);
+ if (mNonblockable) {
+ if (mIsSingleDefaultChannel || mNumNotificationChannels > 1) {
+ channelName.setVisibility(View.GONE);
+ } else {
+ channelName.setText(mSingleNotificationChannel.getName());
+ }
- // Optional settings link
- updateAppSettingsLink();
+ blockPrompt.setText(R.string.notification_unblockable_desc);
+ } else {
+ if (mIsSingleDefaultChannel || mNumNotificationChannels > 1) {
+ channelName.setVisibility(View.GONE);
+ blockPrompt.setText(R.string.inline_keep_showing_app);
+ } else {
+ channelName.setText(mSingleNotificationChannel.getName());
+ blockPrompt.setText(R.string.inline_keep_showing);
+ }
+ }
}
private boolean hasImportanceChanged() {
- return mSingleNotificationChannel != null &&
- mChannelEnabledSwitch != null &&
- mStartingUserImportance != getSelectedImportance();
+ return mSingleNotificationChannel != null && mStartingUserImportance != mChosenImportance;
}
private void saveImportance() {
- if (!hasImportanceChanged()) {
+ if (mNonblockable || !hasImportanceChanged()) {
return;
}
- final int selectedImportance = getSelectedImportance();
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
- selectedImportance - mStartingUserImportance);
- mSingleNotificationChannel.setImportance(selectedImportance);
+ mChosenImportance - mStartingUserImportance);
+ mSingleNotificationChannel.setImportance(mChosenImportance);
mSingleNotificationChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
try {
mINotificationManager.updateNotificationChannelForPackage(
@@ -298,30 +268,78 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
- private int getSelectedImportance() {
- if (!mChannelEnabledSwitch.isChecked()) {
- return IMPORTANCE_NONE;
+ private void bindButtons() {
+ View block = findViewById(R.id.block);
+ block.setOnClickListener(mOnStopNotifications);
+ TextView keep = findViewById(R.id.keep);
+ keep.setOnClickListener(mOnKeepShowing);
+ findViewById(R.id.undo).setOnClickListener(mOnUndo);
+
+ if (mNonblockable) {
+ keep.setText(R.string.notification_done);
+ block.setVisibility(GONE);
+ }
+
+ // app settings link
+ TextView settingsLinkView = findViewById(R.id.app_settings);
+ Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel,
+ mSbn.getId(), mSbn.getTag());
+ if (settingsIntent != null
+ && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
+ settingsLinkView.setVisibility(View.VISIBLE);
+ settingsLinkView.setText(mContext.getString(R.string.notification_app_settings,
+ mSbn.getNotification().getSettingsText()));
+ settingsLinkView.setOnClickListener((View view) -> {
+ mAppSettingsClickListener.onClick(view, settingsIntent);
+ });
} else {
- return mStartingUserImportance;
+ settingsLinkView.setVisibility(View.GONE);
}
}
- private void bindButtons(final boolean nonBlockable) {
- // Enabled Switch
- mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
- mChannelEnabledSwitch.setChecked(
- mStartingUserImportance != IMPORTANCE_NONE);
- final boolean visible = !nonBlockable && mSingleNotificationChannel != null;
- mChannelEnabledSwitch.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-
- // Callback when checked.
- mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
- if (mGutsContainer != null) {
- mGutsContainer.resetFalsingCheck();
+ private void swapContent(boolean showPrompt) {
+ if (mExpandAnimation != null) {
+ mExpandAnimation.cancel();
+ }
+
+ if (showPrompt) {
+ mChosenImportance = mStartingUserImportance;
+ } else {
+ mChosenImportance = IMPORTANCE_NONE;
+ }
+
+ View prompt = findViewById(R.id.prompt);
+ View confirmation = findViewById(R.id.confirmation);
+ ObjectAnimator promptAnim = ObjectAnimator.ofFloat(prompt, View.ALPHA,
+ prompt.getAlpha(), showPrompt ? 1f : 0f);
+ promptAnim.setInterpolator(showPrompt ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+ ObjectAnimator confirmAnim = ObjectAnimator.ofFloat(confirmation, View.ALPHA,
+ confirmation.getAlpha(), showPrompt ? 0f : 1f);
+ confirmAnim.setInterpolator(showPrompt ? Interpolators.ALPHA_OUT : Interpolators.ALPHA_IN);
+
+ prompt.setVisibility(showPrompt ? VISIBLE : GONE);
+ confirmation.setVisibility(showPrompt ? GONE : VISIBLE);
+
+ mExpandAnimation = new AnimatorSet();
+ mExpandAnimation.playTogether(promptAnim, confirmAnim);
+ mExpandAnimation.setDuration(150);
+ mExpandAnimation.addListener(new AnimatorListenerAdapter() {
+ boolean cancelled = false;
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ cancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!cancelled) {
+ prompt.setVisibility(showPrompt ? VISIBLE : GONE);
+ confirmation.setVisibility(showPrompt ? GONE : VISIBLE);
+ }
}
- updateSecondaryText();
- updateAppSettingsLink();
});
+ mExpandAnimation.start();
}
@Override
@@ -339,35 +357,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
- private void updateSecondaryText() {
- final boolean disabled = mSingleNotificationChannel != null &&
- getSelectedImportance() == IMPORTANCE_NONE;
- if (disabled) {
- mChannelDisabledView.setVisibility(View.VISIBLE);
- mNumChannelsView.setVisibility(View.GONE);
- } else {
- mChannelDisabledView.setVisibility(View.GONE);
- mNumChannelsView.setVisibility(mIsSingleDefaultChannel ? View.INVISIBLE : View.VISIBLE);
- }
- }
-
- private void updateAppSettingsLink() {
- mSettingsLinkView = findViewById(R.id.app_settings);
- Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel,
- mSbn.getId(), mSbn.getTag());
- if (settingsIntent != null && getSelectedImportance() != IMPORTANCE_NONE
- && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
- mSettingsLinkView.setVisibility(View.VISIBLE);
- mSettingsLinkView.setText(mContext.getString(R.string.notification_app_settings,
- mSbn.getNotification().getSettingsText()));
- mSettingsLinkView.setOnClickListener((View view) -> {
- mAppSettingsClickListener.onClick(view, settingsIntent);
- });
- } else {
- mSettingsLinkView.setVisibility(View.GONE);
- }
- }
-
private Intent getAppSettingsIntent(PackageManager pm, String packageName,
NotificationChannel channel, int id, String tag) {
Intent intent = new Intent(Intent.ACTION_MAIN)
@@ -390,6 +379,18 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
return intent;
}
+ private void closeControls(View v) {
+ 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;
+ mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+ }
+
@Override
public void setGutsParent(NotificationGuts guts) {
mGutsContainer = guts;
@@ -397,7 +398,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
@Override
public boolean willBeRemoved() {
- return mChannelEnabledSwitch != null && !mChannelEnabledSwitch.isChecked();
+ return hasImportanceChanged();
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 672193835ac3..d77bf69ad365 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -16,11 +16,13 @@
package com.android.systemui.statusbar;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.any;
@@ -50,11 +52,11 @@ import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.testing.PollingCheck;
import android.testing.UiThreadTest;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
-import android.widget.Switch;
import android.widget.TextView;
import com.android.systemui.R;
@@ -66,7 +68,6 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -117,50 +118,31 @@ public class NotificationInfoTest extends SysuiTestCase {
// Some test channels.
mNotificationChannel = new NotificationChannel(
- TEST_CHANNEL, TEST_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
+ TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
mDefaultNotificationChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
- NotificationManager.IMPORTANCE_LOW);
+ IMPORTANCE_LOW);
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
new Notification(), UserHandle.CURRENT, null, 0);
}
- private CharSequence getStringById(int resId) {
- return mContext.getString(resId);
+ // TODO: if tests are taking too long replace this with something that makes the animation
+ // finish instantly.
+ private void waitForUndoButton() {
+ PollingCheck.waitFor(1000,
+ () -> VISIBLE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility());
}
-
- private CharSequence getNumChannelsDescString(int numChannels) {
- return String.format(
- mContext.getResources().getQuantityString(
- R.plurals.notification_num_channels_desc, numChannels),
- numChannels);
- }
-
- private CharSequence getChannelsListDescString(NotificationChannel... channels) {
- if (channels.length == 2) {
- return mContext.getString(R.string.notification_channels_list_desc_2,
- channels[0].getName(), channels[1].getName());
- } else {
- final int numOthers = channels.length - 2;
- return String.format(
- mContext.getResources().getQuantityString(
- R.plurals.notification_channels_list_desc_2_and_others, numOthers),
- channels[0].getName(), channels[1].getName(), numOthers);
- }
- }
-
- private CharSequence getNumChannelsString(int numChannels) {
- return mContext.getString(R.string.notification_num_channels, numChannels);
+ private void waitForStopButton() {
+ PollingCheck.waitFor(1000,
+ () -> VISIBLE == mNotificationInfo.findViewById(R.id.prompt).getVisibility());
}
@Test
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -170,24 +152,19 @@ public class NotificationInfoTest extends SysuiTestCase {
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@Test
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, 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_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
+ assertEquals(GONE, groupNameView.getVisibility());
+ final TextView groupDividerView = mNotificationInfo.findViewById(R.id.pkg_group_divider);
+ assertEquals(GONE, groupDividerView.getVisibility());
}
@Test
@@ -199,75 +176,50 @@ public class NotificationInfoTest extends SysuiTestCase {
eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
.thenReturn(notificationChannelGroup);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final TextView groupNameView = 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);
+ final TextView groupDividerView = mNotificationInfo.findViewById(R.id.pkg_group_divider);
assertEquals(View.VISIBLE, groupDividerView.getVisibility());
}
@Test
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@Test
public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
- assertEquals(mContext.getString(R.string.notification_header_default_channel),
- textView.getText());
+ TEST_PACKAGE_NAME, mDefaultNotificationChannel, 1, mSbn, null, null, null, null);
+ final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
+ assertEquals(GONE, textView.getVisibility());
}
@Test
- public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, Collections.singleton(TEST_PACKAGE_NAME));
- final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
- assertEquals(mContext.getString(R.string.notification_header_default_channel),
- textView.getText());
- }
-
- @Test
- public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
- throws Exception {
- when(mMockINotificationManager.getNumNotificationChannelsForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
+ public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
- assertEquals(mDefaultNotificationChannel.getName(), textView.getText());
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null,
+ Collections.singleton(TEST_PACKAGE_NAME));
+ final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
+ assertEquals(VISIBLE, textView.getVisibility());
}
@Test
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null,
(View v, NotificationChannel c, int appUid) -> {
assertEquals(mNotificationChannel, c);
latch.countDown();
- }, null, null, null, null);
+ }, null, null);
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ final View settingsButton = mNotificationInfo.findViewById(R.id.info);
settingsButton.performClick();
// Verify that listener was triggered.
assertEquals(0, latch.getCount());
@@ -276,24 +228,20 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
+ final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
}
@Test
- public void testBindNotification_SettingsButtonReappersAfterSecondBind() throws Exception {
+ public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
- (View v, NotificationChannel c, int appUid) -> {}, null, null, null, null);
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null,
+ (View v, NotificationChannel c, int appUid) -> {
+ }, null, null);
+ final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertEquals(View.VISIBLE, settingsButton.getVisibility());
}
@@ -301,279 +249,63 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME,
- Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
+ TEST_PACKAGE_NAME, mNotificationChannel, 2, mSbn, null,
(View v, NotificationChannel c, int appUid) -> {
assertEquals(null, c);
latch.countDown();
- }, null, null, null, null);
-
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
- settingsButton.performClick();
- // Verify that listener was triggered.
- assertEquals(0, latch.getCount());
- }
-
- @Test
- public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
- (View v, NotificationChannel c, int appUid) -> {
- }, null, null, null, null);
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
- assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
- }
-
- @Test
- public void testBindNotification_SettingsTextWithMultipleChannels() throws Exception {
- when(mMockINotificationManager.getNumNotificationChannelsForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
- (View v, NotificationChannel c, int appUid) -> {
- }, null, null, null, null);
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
- assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText());
- }
-
- @Test
- public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp()
- throws Exception {
- when(mMockINotificationManager.getNumNotificationChannelsForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn,
- (View v, NotificationChannel c, int appUid) -> {
- }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME));
- final TextView settingsButton =
- (TextView) mNotificationInfo.findViewById(R.id.more_settings);
- assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
- }
-
- @Test
- public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null,
- null, (View v) -> {
- latch.countDown();
- },
- null, null);
+ }, null, null);
- final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
- doneButton.performClick();
+ mNotificationInfo.findViewById(R.id.info).performClick();
// Verify that listener was triggered.
assertEquals(0, latch.getCount());
}
@Test
- public void testBindNotification_NumChannelsTextHiddenWhenDefaultChannel() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null,
- null, null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(View.INVISIBLE, numChannelsView.getVisibility());
- }
-
- @Test
- public void testBindNotification_NumChannelsTextDisplaysWhenMoreThanOneChannelExists()
- throws Exception {
- when(mMockINotificationManager.getNumNotificationChannelsForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null,
- null, null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
- assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
- }
-
- @Test
- public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
- throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
- assertEquals(getNumChannelsDescString(1), numChannelsView.getText());
- }
-
- @Test
- public void testBindNotification_NumChannelsTextScalesWithNumberOfChannels()
- throws Exception {
- when(mMockINotificationManager.getNumNotificationChannelsForPackage(
- eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
- }
-
- @Test
- @UiThreadTest
- public void testBindNotification_NumChannelsTextListsChannelsWhenTwoInBundle()
- throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel),
- numChannelsView.getText());
- }
-
- @Test
- @UiThreadTest
- public void testBindNotification_NumChannelsTextListsChannelsWhenThreeInBundle()
- throws Exception {
- NotificationChannel thirdChannel = new NotificationChannel(
- "third_channel", "third_channel", NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME,
- Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(
- getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel,
- thirdChannel),
- numChannelsView.getText());
- }
-
- @Test
- @UiThreadTest
- public void testBindNotification_NumChannelsTextListsChannelsWhenFourInBundle()
- throws Exception {
- NotificationChannel thirdChannel = new NotificationChannel(
- "third_channel", "third_channel", NotificationManager.IMPORTANCE_LOW);
- NotificationChannel fourthChannel = new NotificationChannel(
- "fourth_channel", "fourth_channel", NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME,
- Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel,
- fourthChannel), mNotificationChannel.getImportance(), mSbn, null, null,
- null, null, null);
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(
- getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel,
- thirdChannel, fourthChannel),
- numChannelsView.getText());
- }
-
- @Test
@UiThreadTest
- public void testBindNotification_ChannelNameChangesWhenBundleFromDifferentChannels()
+ public void testBindNotification_ChannelNameInvisibleWhenBundleFromDifferentChannels()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 2, mSbn, null, null, null, null);
final TextView channelNameView =
- (TextView) mNotificationInfo.findViewById(R.id.channel_name);
- assertEquals(getNumChannelsString(2), channelNameView.getText());
+ mNotificationInfo.findViewById(R.id.channel_name);
+ assertEquals(GONE, channelNameView.getVisibility());
}
@Test
@UiThreadTest
- public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception {
+ public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
- }
-
- @Test
- public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
- final TextView channelDisabledView =
- (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
- assertEquals(channelDisabledView.getVisibility(), View.GONE);
- }
-
- @Test
- public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, 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_PACKAGE_NAME, mNotificationChannel, 2, mSbn, null, null, null, null);
+ final TextView blockView = mNotificationInfo.findViewById(R.id.block);
+ assertEquals(GONE, blockView.getVisibility());
}
@Test
public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null,
null, Collections.singleton(TEST_PACKAGE_NAME));
- final TextView numChannelsView =
- (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
- assertEquals(View.VISIBLE, numChannelsView.getVisibility());
+ final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
+ assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(mContext.getString(R.string.notification_unblockable_desc),
- numChannelsView.getText());
- }
-
- @Test
- @UiThreadTest
- public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel()
- throws Exception {
- mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- mDefaultNotificationChannel.getImportance(), mSbn, null, null,
- null, null, null);
- final TextView channelDisabledView =
- (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
- assertEquals(View.VISIBLE, channelDisabledView.getVisibility());
+ view.getText());
}
@Test
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
}
@Test
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
+ mNotificationInfo.findViewById(R.id.block).performClick();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
}
@@ -582,9 +314,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.handleCloseControls(true, false);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -596,9 +326,7 @@ public class NotificationInfoTest extends SysuiTestCase {
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
mNotificationInfo.handleCloseControls(true, false);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -606,134 +334,65 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testEnabledSwitchOnByDefault() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertTrue(enabledSwitch.isChecked());
- }
-
- @Test
- public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertFalse(enabledSwitch.isChecked());
- }
-
- @Test
- public void testEnabledSwitchVisibleByDefault() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
- }
-
- @Test
- public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null,
null, Collections.singleton(TEST_PACKAGE_NAME));
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
- }
-
- @Test
- public void testEnabledSwitchInvisibleIfNonBlockableSystemChannel() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationChannel.setBlockableSystem(false);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_SYSTEM_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), any());
}
@Test
- public void testEnabledSwitchVisibleIfBlockableSystemChannel() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationChannel.setBlockableSystem(true);
+ public void testBlockChangedCallsUpdateNotificationChannel() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_SYSTEM_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, null);
-
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
- }
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, null);
- @Test
- public void testEnabledSwitchInvisibleIfMultiChannelSummary() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationChannel.setBlockableSystem(true);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, Collections.singleton(TEST_PACKAGE_NAME));
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0);
}
@Test
- public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ public void testBlockUndoDoesNotCallUpdateNotificationChannel() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, Collections.singleton(TEST_PACKAGE_NAME));
- mNotificationInfo.handleCloseControls(true, false);
- verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
- anyString(), eq(TEST_UID), any());
- }
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null,
+ Collections.singleton(TEST_PACKAGE_NAME));
- @Test
- public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, Collections.singleton(TEST_PACKAGE_NAME));
- Switch enabledSwitch = mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
+ mNotificationInfo.findViewById(R.id.undo).performClick();
+ waitForStopButton();
mNotificationInfo.handleCloseControls(true, false);
ArgumentCaptor<NotificationChannel> updated =
ArgumentCaptor.forClass(NotificationChannel.class);
- verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), updated.capture());
- assertTrue((updated.getValue().getUserLockedFields()
- & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
}
@Test
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
- null, Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null,
+ Collections.singleton(TEST_PACKAGE_NAME));
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
mNotificationInfo.handleCloseControls(false, false);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
@@ -741,16 +400,14 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
(Runnable saveImportance, StatusBarNotification sbn) -> {
- },
- Collections.singleton(TEST_PACKAGE_NAME));
+ }, null, null, Collections.singleton(TEST_PACKAGE_NAME));
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
mNotificationInfo.handleCloseControls(true, false);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
@@ -758,17 +415,15 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), mSbn, null, null, null,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
(Runnable saveImportance, StatusBarNotification sbn) -> {
saveImportance.run();
- },
- Collections.singleton(TEST_PACKAGE_NAME));
+ }, null, null, null);
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
+ mNotificationInfo.findViewById(R.id.block).performClick();
+ waitForUndoButton();
mNotificationInfo.handleCloseControls(true, false);
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
@@ -785,22 +440,19 @@ public class NotificationInfoTest extends SysuiTestCase {
List<ResolveInfo> ris = new ArrayList<>();
ris.add(ri);
when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris);
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
.setSettingsText(settingsText).build();
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), sbn, null,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null,
(View v, Intent intent) -> {
latch.countDown();
- }, null, null, null);
+ }, null);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(View.VISIBLE, settingsLink.getVisibility());
- assertTrue(settingsLink.getText().toString().length() > settingsText.length());
- assertTrue(settingsLink.getText().toString().contains(settingsText));
settingsLink.performClick();
assertEquals(0, latch.getCount());
}
@@ -816,17 +468,17 @@ public class NotificationInfoTest extends SysuiTestCase {
List<ResolveInfo> ris = new ArrayList<>();
ris.add(ri);
when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris);
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
.setSettingsText(settingsText).build();
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- mNotificationChannel.getImportance(), sbn, null, (View v, Intent intent) -> {
+ TEST_PACKAGE_NAME, mNotificationChannel, 2, sbn, null, null,
+ (View v, Intent intent) -> {
latch.countDown();
- }, null, null, null);
+ }, null);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(View.VISIBLE, settingsLink.getVisibility());
settingsLink.performClick();
@@ -837,18 +489,16 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testNoSettingsLink_noHandlingActivity() throws Exception {
final String settingsText = "work chats";
when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null);
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
.setSettingsText(settingsText).build();
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), sbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 2, sbn, null, null, null, null);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
- assertEquals(View.GONE, settingsLink.getVisibility());
+ assertEquals(GONE, settingsLink.getVisibility());
}
@Test
@@ -860,52 +510,17 @@ public class NotificationInfoTest extends SysuiTestCase {
List<ResolveInfo> ris = new ArrayList<>();
ris.add(ri);
when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris);
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()).build();
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), sbn, null, null, null,
- null, null);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, null);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
- assertEquals(View.GONE, settingsLink.getVisibility());
+ assertEquals(GONE, settingsLink.getVisibility());
}
- @Test
- public void testNoSettingsLink_afterBlockingChannel() throws Exception {
- final String settingsText = "work chats";
- final ResolveInfo ri = new ResolveInfo();
- ri.activityInfo = new ActivityInfo();
- ri.activityInfo.packageName = TEST_PACKAGE_NAME;
- ri.activityInfo.name = "something";
- List<ResolveInfo> ris = new ArrayList<>();
- ris.add(ri);
- when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris);
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
- .setSettingsText(settingsText).build();
- StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
- 0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
-
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- mNotificationChannel.getImportance(), sbn, null, null, null,
- null, null);
- final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
- assertEquals(View.VISIBLE, settingsLink.getVisibility());
-
- // Block channel
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
-
- assertEquals(View.GONE, settingsLink.getVisibility());
-
- //unblock
- enabledSwitch.setChecked(true);
- assertEquals(View.VISIBLE, settingsLink.getVisibility());
- }
@Test
public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception {
diff --git a/tests/testables/src/android/testing/PollingCheck.java b/tests/testables/src/android/testing/PollingCheck.java
new file mode 100644
index 000000000000..5a31450f048f
--- /dev/null
+++ b/tests/testables/src/android/testing/PollingCheck.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.testing;
+
+import junit.framework.Assert;
+import java.util.concurrent.Callable;
+
+public abstract class PollingCheck {
+ private static final long TIME_SLICE = 50;
+ private long mTimeout = 3000;
+
+ public static interface PollingCheckCondition {
+ boolean canProceed();
+ }
+
+ public PollingCheck() {
+ }
+
+ public PollingCheck(long timeout) {
+ mTimeout = timeout;
+ }
+
+ protected abstract boolean check();
+
+ public void run() {
+ if (check()) {
+ return;
+ }
+
+ long timeout = mTimeout;
+ while (timeout > 0) {
+ try {
+ Thread.sleep(TIME_SLICE);
+ } catch (InterruptedException e) {
+ Assert.fail("unexpected InterruptedException");
+ }
+
+ if (check()) {
+ return;
+ }
+
+ timeout -= TIME_SLICE;
+ }
+
+ Assert.fail("unexpected timeout");
+ }
+
+ public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
+ throws Exception {
+ while (timeout > 0) {
+ if (condition.call()) {
+ return;
+ }
+
+ Thread.sleep(TIME_SLICE);
+ timeout -= TIME_SLICE;
+ }
+
+ Assert.fail(message.toString());
+ }
+
+ public static void waitFor(final PollingCheckCondition condition) {
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return condition.canProceed();
+ }
+ }.run();
+ }
+
+ public static void waitFor(long timeout, final PollingCheckCondition condition) {
+ new PollingCheck(timeout) {
+ @Override
+ protected boolean check() {
+ return condition.canProceed();
+ }
+ }.run();
+ }
+}
+