Show a link to app settings in notification guts.
Test: runtest systemui, cts
Change-Id: I7204102d5c83d589af5d3da57f72068491c12daa
diff --git a/api/current.txt b/api/current.txt
index 15d308e..0ae0298 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5116,6 +5116,7 @@
method public java.lang.String getChannel();
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
+ method public java.lang.CharSequence getSettingsText();
method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
@@ -5160,6 +5161,8 @@
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
+ field public static final java.lang.String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+ field public static final java.lang.String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
@@ -5345,6 +5348,7 @@
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setSettingsText(java.lang.CharSequence);
method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index f74bc3a..341602d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5289,6 +5289,7 @@
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
+ method public java.lang.CharSequence getSettingsText();
method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
@@ -5334,6 +5335,8 @@
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
+ field public static final java.lang.String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+ field public static final java.lang.String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
@@ -5521,6 +5524,7 @@
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setSettingsText(java.lang.CharSequence);
method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index b51739b..1ea195a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5128,6 +5128,7 @@
method public java.lang.String getChannel();
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
+ method public java.lang.CharSequence getSettingsText();
method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
@@ -5172,6 +5173,8 @@
field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
+ field public static final java.lang.String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+ field public static final java.lang.String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
field public static final java.lang.String EXTRA_PEOPLE = "android.people";
field public static final java.lang.String EXTRA_PICTURE = "android.picture";
field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
@@ -5357,6 +5360,7 @@
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setSettingsText(java.lang.CharSequence);
method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 161dd25..6d7486b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -103,8 +103,7 @@
/**
* An activity that provides a user interface for adjusting notification preferences for its
- * containing application. Optional but recommended for apps that post
- * {@link android.app.Notification Notifications}.
+ * containing application.
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES
@@ -113,11 +112,25 @@
/**
* Optional extra for {@link #INTENT_CATEGORY_NOTIFICATION_PREFERENCES}. If provided, will
* contain a {@link NotificationChannel#getId() channel id} that can be used to narrow down
- * what in app notifications settings should be shown.
+ * what settings should be shown in the target app.
*/
public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
/**
+ * Optional extra for {@link #INTENT_CATEGORY_NOTIFICATION_PREFERENCES}. If provided, will
+ * contain the tag provided to {@link NotificationManager#notify(String, int, Notification)}
+ * that can be used to narrow down what settings should be shown in the target app.
+ */
+ public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
+
+ /**
+ * Optional extra for {@link #INTENT_CATEGORY_NOTIFICATION_PREFERENCES}. If provided, will
+ * contain the id provided to {@link NotificationManager#notify(String, int, Notification)}
+ * that can be used to narrow down what settings should be shown in the target app.
+ */
+ public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+
+ /**
* Use all default values (where applicable).
*/
public static final int DEFAULT_ALL = ~0;
@@ -1082,6 +1095,7 @@
private long mTimeout;
private String mShortcutId;
+ private CharSequence mSettingsText;
/**
* If this notification is being shown as a badge, always show as a number.
@@ -1851,6 +1865,10 @@
}
mBadgeIcon = parcel.readInt();
+
+ if (parcel.readInt() != 0) {
+ mSettingsText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ }
}
@Override
@@ -1960,6 +1978,9 @@
that.mChannelId = this.mChannelId;
that.mTimeout = this.mTimeout;
+ that.mShortcutId = this.mShortcutId;
+ that.mBadgeIcon = this.mBadgeIcon;
+ that.mSettingsText = this.mSettingsText;
if (!heavy) {
that.lightenPayload(); // will clean out extras
@@ -2229,6 +2250,13 @@
}
parcel.writeInt(mBadgeIcon);
+
+ if (mSettingsText != null) {
+ parcel.writeInt(1);
+ TextUtils.writeToParcel(mSettingsText, parcel, flags);
+ } else {
+ parcel.writeInt(0);
+ }
}
/**
@@ -2458,6 +2486,14 @@
return mShortcutId;
}
+
+ /**
+ * Returns the settings text provided to {@link Builder#setSettingsText(CharSequence)}.
+ */
+ public CharSequence getSettingsText() {
+ return mSettingsText;
+ }
+
/**
* The small icon representing this notification in the status bar and content view.
*
@@ -2887,6 +2923,24 @@
}
/**
+ * Provides text that will appear as a link to your application's settings.
+ *
+ * <p>This text does not appear within notification {@link Style templates} but may
+ * appear when the user uses an affordance to learn more about the notification.
+ * Additionally, this text will not appear unless you provide a valid link target by
+ * handling {@link #INTENT_CATEGORY_NOTIFICATION_PREFERENCES}.
+ *
+ * <p>This text is meant to be concise description about what the user can customize
+ * when they click on this link. The recommended maximum length is 40 characters.
+ * @param text
+ * @return
+ */
+ public Builder setSettingsText(CharSequence text) {
+ mN.mSettingsText = safeCharSequence(text);
+ return this;
+ }
+
+ /**
* Set the remote input history.
*
* This should be set to the most recent inputs that have been sent
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 195eb9b..ff22ffb 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -97,6 +97,15 @@
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 -->
+ <TextView
+ android:id="@+id/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.Secondary.Link"/>
</LinearLayout>
<!-- Ban Channel Switch -->
<Switch
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a8cf3da..43aeaa3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1472,6 +1472,9 @@
<!-- 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>
<!-- 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 d6abda6..c9479b8 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -370,6 +370,10 @@
<item name="android:textColor">?android:attr/colorError</item>
</style>
+ <style name="TextAppearance.NotificationInfo.Secondary.Link">
+ <item name="android:textColor">?android:attr/colorAccent</item>
+ </style>
+
<style name="TextAppearance.NotificationInfo.Button">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">14sp</item>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 8298f35..b4b1cd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -16,45 +16,34 @@
package com.android.systemui.statusbar;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
import android.app.INotificationManager;
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
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;
+import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
-import android.os.Handler;
import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.SeekBar;
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 com.android.systemui.statusbar.NotificationGuts.OnSettingsClickListener;
-import com.android.systemui.statusbar.stack.StackStateAnimator;
import java.lang.IllegalArgumentException;
import java.util.List;
@@ -71,12 +60,16 @@
private int mAppUid;
private List<NotificationChannel> mNotificationChannels;
private NotificationChannel mSingleNotificationChannel;
+ private StatusBarNotification mSbn;
private int mStartingUserImportance;
private TextView mNumChannelsView;
private View mChannelDisabledView;
+ private TextView mSettingsLinkView;
private Switch mChannelEnabledSwitch;
private CheckSaveListener mCheckSaveListener;
+ private OnAppSettingsClickListener mAppSettingsClickListener;
+ private PackageManager mPm;
private NotificationGuts mGutsContainer;
@@ -95,11 +88,18 @@
void onClick(View v, NotificationChannel channel, int appUid);
}
+ public interface OnAppSettingsClickListener {
+ void onClick(View v, Intent intent);
+ }
+
public void bindNotification(final PackageManager pm,
final INotificationManager iNotificationManager,
final String pkg,
final List<NotificationChannel> notificationChannels,
+ int startingUserImportance,
+ final StatusBarNotification sbn,
OnSettingsClickListener onSettingsClick,
+ OnAppSettingsClickListener onAppSettingsClick,
OnClickListener onDoneClick,
CheckSaveListener checkSaveListener,
final Set<String> nonBlockablePkgs)
@@ -108,16 +108,21 @@
mPkg = pkg;
mNotificationChannels = notificationChannels;
mCheckSaveListener = checkSaveListener;
+ mSbn = sbn;
+ mPm = pm;
+ mAppSettingsClickListener = onAppSettingsClick;
boolean isSingleDefaultChannel = false;
+ mStartingUserImportance = startingUserImportance;
if (mNotificationChannels.isEmpty()) {
throw new IllegalArgumentException("bindNotification requires at least one channel");
- } else if (mNotificationChannels.size() == 1) {
- mSingleNotificationChannel = mNotificationChannels.get(0);
- mStartingUserImportance = mSingleNotificationChannel.getImportance();
- isSingleDefaultChannel = mSingleNotificationChannel.getId()
- .equals(NotificationChannel.DEFAULT_CHANNEL_ID);
- } else {
- mSingleNotificationChannel = null;
+ } else {
+ if (mNotificationChannels.size() == 1) {
+ mSingleNotificationChannel = mNotificationChannels.get(0);
+ isSingleDefaultChannel = mSingleNotificationChannel.getId()
+ .equals(NotificationChannel.DEFAULT_CHANNEL_ID);
+ } else {
+ mSingleNotificationChannel = null;
+ }
}
String appName = mPkg;
@@ -248,6 +253,9 @@
final TextView doneButton = (TextView) findViewById(R.id.done);
doneButton.setText(R.string.notification_done);
doneButton.setOnClickListener(onDoneClick);
+
+ // Optional settings link
+ updateAppSettingsLink();
}
private boolean hasImportanceChanged() {
@@ -276,7 +284,7 @@
private int getSelectedImportance() {
if (!mChannelEnabledSwitch.isChecked()) {
- return NotificationManager.IMPORTANCE_NONE;
+ return IMPORTANCE_NONE;
} else {
return mStartingUserImportance;
}
@@ -286,7 +294,7 @@
// Enabled Switch
mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
mChannelEnabledSwitch.setChecked(
- mStartingUserImportance != NotificationManager.IMPORTANCE_NONE);
+ mStartingUserImportance != IMPORTANCE_NONE);
final boolean visible = !nonBlockable && mSingleNotificationChannel != null;
mChannelEnabledSwitch.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
@@ -296,12 +304,13 @@
mGutsContainer.resetFalsingCheck();
}
updateSecondaryText();
+ updateAppSettingsLink();
});
}
private void updateSecondaryText() {
final boolean disabled = mSingleNotificationChannel != null &&
- getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
+ getSelectedImportance() == IMPORTANCE_NONE;
if (disabled) {
mChannelDisabledView.setVisibility(View.VISIBLE);
mNumChannelsView.setVisibility(View.GONE);
@@ -311,6 +320,45 @@
}
}
+ 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)
+ .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)
+ .setPackage(packageName);
+ final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
+ intent,
+ PackageManager.MATCH_DEFAULT_ONLY
+ );
+ if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
+ return null;
+ }
+ final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+ intent.setClassName(activityInfo.packageName, activityInfo.name);
+ if (channel != null) {
+ intent.putExtra(Notification.EXTRA_CHANNEL_ID, channel.getId());
+ }
+ intent.putExtra(Notification.EXTRA_NOTIFICATION_ID, id);
+ intent.putExtra(Notification.EXTRA_NOTIFICATION_TAG, tag);
+ return intent;
+ }
+
@Override
public void setGutsParent(NotificationGuts guts) {
mGutsContainer = guts;
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 472af65..9304de5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -48,8 +48,10 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -5701,7 +5703,7 @@
.findViewById(com.android.internal.R.id.media_actions) != null;
}
- // The (i) button in the guts that links to the system notification settings for that app
+ // The button in the guts that links to the system notification settings for that app
private void startAppNotificationSettingsActivity(String packageName, final int appUid,
final NotificationChannel channel) {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
@@ -5781,10 +5783,17 @@
startAppNotificationSettingsActivity(pkg, appUid, channel);
};
}
+ final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick = (View v,
+ Intent intent) -> {
+ mMetricsLogger.action(MetricsEvent.ACTION_APP_NOTE_SETTINGS);
+ guts.resetFalsingCheck();
+ startNotificationGutsIntent(intent, sbn.getUid());
+ };
final View.OnClickListener onDoneClick = (View v) -> {
saveAndCloseNotificationMenu(info, row, guts, v);
};
- final NotificationInfo.CheckSaveListener checkSaveListener = (Runnable saveImportance) -> {
+ final NotificationInfo.CheckSaveListener checkSaveListener =
+ (Runnable saveImportance) -> {
// If the user has security enabled, show challenge if the setting is changed.
if (isLockscreenPublicMode(userHandle.getIdentifier())
&& (mState == StatusBarState.KEYGUARD
@@ -5817,7 +5826,9 @@
}
try {
info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels),
- onSettingsClick, onDoneClick, checkSaveListener, mNonBlockablePkgs);
+ row.getEntry().channel.getImportance(), sbn, onSettingsClick,
+ onAppSettingsClick, onDoneClick, checkSaveListener,
+ mNonBlockablePkgs);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
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 0621f4a..08c580bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -18,9 +18,9 @@
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.Matchers.anyObject;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
@@ -33,13 +33,18 @@
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.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -56,6 +61,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -74,6 +81,7 @@
private final PackageManager mMockPackageManager = mock(PackageManager.class);
private NotificationChannel mNotificationChannel;
private NotificationChannel mDefaultNotificationChannel;
+ private StatusBarNotification mSbn;
@Before
public void setUp() throws Exception {
@@ -101,6 +109,8 @@
mDefaultNotificationChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
NotificationManager.IMPORTANCE_LOW);
+ mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, 0, 0,
+ new Notification(), UserHandle.CURRENT, null, 0);
}
private CharSequence getStringById(int resId) {
@@ -135,7 +145,9 @@
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -146,7 +158,9 @@
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -154,7 +168,9 @@
@Test
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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 =
@@ -171,7 +187,9 @@
eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt()))
.thenReturn(notificationChannelGroup);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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.VISIBLE, groupNameView.getVisibility());
assertEquals("Test Group Name", groupNameView.getText());
@@ -183,7 +201,9 @@
@Test
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@@ -193,10 +213,11 @@
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn,
(View v, NotificationChannel c, int appUid) -> {
- assertEquals(mNotificationChannel, c);
- latch.countDown();
- }, null, null, null);
+ assertEquals(mNotificationChannel, c);
+ latch.countDown();
+ }, null, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -209,7 +230,7 @@
public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
@@ -222,7 +243,8 @@
null, null, null, null);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
+ mNotificationChannel.getImportance(), mSbn,
+ (View v, NotificationChannel c, int appUid) -> {}, null, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertEquals(View.VISIBLE, settingsButton.getVisibility());
@@ -234,10 +256,11 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn,
(View v, NotificationChannel c, int appUid) -> {
- assertEquals(null, c);
- latch.countDown();
- }, null, null, null);
+ assertEquals(null, c);
+ latch.countDown();
+ }, null, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -250,7 +273,9 @@
public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
+ 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());
@@ -262,7 +287,9 @@
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
+ 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());
@@ -272,8 +299,11 @@
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null,
- (View v) -> { latch.countDown(); },
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null,
+ null, (View v) -> {
+ latch.countDown();
+ },
null, null);
final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
@@ -286,7 +316,8 @@
public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null,
+ null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(View.VISIBLE, numChannelsView.getVisibility());
@@ -298,7 +329,9 @@
public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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);
@@ -311,7 +344,9 @@
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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());
@@ -323,7 +358,7 @@
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel),
@@ -339,7 +374,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -359,8 +394,8 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel,
- fourthChannel),
- null, null, null, null);
+ fourthChannel), mNotificationChannel.getImportance(), mSbn, null, null,
+ null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -375,7 +410,7 @@
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
final TextView channelNameView =
(TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(getNumChannelsString(2), channelNameView.getText());
@@ -386,7 +421,7 @@
public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null, null);
+ mNotificationChannel.getImportance(), mSbn, null, null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
}
@@ -394,7 +429,8 @@
@Test
public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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);
@@ -404,7 +440,9 @@
public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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);
@@ -421,7 +459,8 @@
mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
- null, null, null, null);
+ mDefaultNotificationChannel.getImportance(), mSbn, null, null,
+ null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(View.VISIBLE, channelDisabledView.getVisibility());
@@ -430,7 +469,9 @@
@Test
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@@ -439,7 +480,9 @@
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -451,7 +494,9 @@
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -463,7 +508,9 @@
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -474,7 +521,9 @@
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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());
@@ -484,7 +533,9 @@
public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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());
@@ -494,7 +545,9 @@
public void testEnabledSwitchVisibleByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
+ 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());
@@ -504,8 +557,9 @@
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
- Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
@@ -515,8 +569,9 @@
public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
- Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
@@ -526,8 +581,9 @@
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
- Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -540,8 +596,9 @@
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
- Collections.singleton(TEST_PACKAGE_NAME));
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -554,8 +611,10 @@
public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
- (Runnable saveImportance) -> {},
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ (Runnable saveImportance) -> {
+ },
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -569,8 +628,11 @@
public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
- (Runnable saveImportance) -> { saveImportance.run(); },
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ (Runnable saveImportance) -> {
+ saveImportance.run();
+ },
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -579,4 +641,137 @@
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
+
+ @Test
+ public void testDisplaySettingsLink() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ 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,
+ (View v, Intent intent) -> {
+ latch.countDown();
+ }, 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());
+ }
+
+ @Test
+ public void testDisplaySettingsLink_multipleChannels() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ 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, mDefaultNotificationChannel),
+ mNotificationChannel.getImportance(), sbn, null, (View v, Intent intent) -> {
+ latch.countDown();
+ }, null, null, null);
+ final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
+ assertEquals(View.VISIBLE, settingsLink.getVisibility());
+ settingsLink.performClick();
+ assertEquals(0, latch.getCount());
+ }
+
+ @Test
+ public void testNoSettingsLink_noHandlingActivity() throws Exception {
+ final String settingsText = "work chats";
+ when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null);
+ 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.GONE, settingsLink.getVisibility());
+ }
+
+ @Test
+ public void testNoSettingsLink_noLinkText() throws Exception {
+ 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()).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.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());
+ }
}