Add updatable fields to Ranking

- NotificationChannel
- Badging

Test: runtest systemuinotification & cts

Change-Id: I7fd1f2dc06148927e9a4bd5b760d436e2c5e8a98
This commit is contained in:
Julia Reynolds
2017-01-19 09:52:07 -05:00
parent 2cff9319e8
commit 924eed1ca6
29 changed files with 531 additions and 181 deletions

View File

@@ -35788,6 +35788,7 @@ package android.service.notification {
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
method public boolean canShowBadge();
method public java.util.List<java.lang.String> getAdditionalPeople();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
@@ -35829,7 +35830,6 @@ package android.service.notification {
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
method public android.app.NotificationChannel getNotificationChannel();
method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();

View File

@@ -38733,6 +38733,7 @@ package android.service.notification {
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
method public boolean canShowBadge();
method public java.util.List<java.lang.String> getAdditionalPeople();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
@@ -38774,7 +38775,6 @@ package android.service.notification {
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
method public android.app.NotificationChannel getNotificationChannel();
method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();

View File

@@ -35909,6 +35909,7 @@ package android.service.notification {
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
method public boolean canShowBadge();
method public java.util.List<java.lang.String> getAdditionalPeople();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
@@ -35950,7 +35951,6 @@ package android.service.notification {
method public int getId();
method public java.lang.String getKey();
method public android.app.Notification getNotification();
method public android.app.NotificationChannel getNotificationChannel();
method public java.lang.String getOverrideGroupKey();
method public java.lang.String getPackageName();
method public long getPostTime();

View File

@@ -47,6 +47,8 @@ interface INotificationManager
in Notification notification, inout int[] idReceived, int userId);
void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
void setShowBadge(String pkg, int uid, boolean showBadge);
boolean canShowBadge(String pkg, int uid);
void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
boolean areNotificationsEnabledForPackage(String pkg, int uid);
boolean areNotificationsEnabled(String pkg);

View File

@@ -122,6 +122,7 @@ public final class NotificationChannel implements Parcelable {
private static final int DEFAULT_IMPORTANCE =
NotificationManager.IMPORTANCE_UNSPECIFIED;
private static final boolean DEFAULT_DELETED = false;
private static final boolean DEFAULT_SHOW_BADGE = true;
private final String mId;
private CharSequence mName;
@@ -133,7 +134,7 @@ public final class NotificationChannel implements Parcelable {
private long[] mVibration;
private int mUserLockedFields;
private boolean mVibrationEnabled;
private boolean mShowBadge;
private boolean mShowBadge = DEFAULT_SHOW_BADGE;
private boolean mDeleted = DEFAULT_DELETED;
/**
@@ -368,6 +369,8 @@ public final class NotificationChannel implements Parcelable {
/**
* Returns whether notifications posted to this channel can appear as badges in a Launcher
* application.
*
* Note that badging may be disabled for other reasons.
*/
public boolean canShowBadge() {
return mShowBadge;

View File

@@ -1166,11 +1166,12 @@ public abstract class NotificationListenerService extends Service {
// System specified group key.
private String mOverrideGroupKey;
// Notification assistant channel override.
private NotificationChannel mOverrideChannel;
private NotificationChannel mChannel;
// Notification assistant people override.
private ArrayList<String> mOverridePeople;
// Notification assistant snooze criteria.
private ArrayList<SnoozeCriterion> mSnoozeCriteria;
private boolean mShowBadge;
public Ranking() {}
@@ -1200,7 +1201,7 @@ public abstract class NotificationListenerService extends Service {
}
/**
* Returns the user specificed visibility for the package that posted
* Returns the user specified visibility for the package that posted
* this notification, or
* {@link NotificationListenerService.Ranking#VISIBILITY_NO_OVERRIDE} if
* no such preference has been expressed.
@@ -1233,7 +1234,7 @@ public abstract class NotificationListenerService extends Service {
* Returns the importance of the notification, which dictates its
* modes of presentation, see: {@link NotificationManager#IMPORTANCE_DEFAULT}, etc.
*
* @return the rank of the notification
* @return the importance of the notification
*/
public @NotificationManager.Importance int getImportance() {
return mImportance;
@@ -1258,12 +1259,11 @@ public abstract class NotificationListenerService extends Service {
}
/**
* If the {@link NotificationAssistantService} has overridden the channel this notification
* was posted to, then this will not match the channel provided by the posting application
* and this should be used to determine the interruptiveness of the notification instead.
* Returns the notification channel this notification was posted to, which dictates
* notification behavior and presentation.
*/
public NotificationChannel getChannel() {
return mOverrideChannel;
return mChannel;
}
/**
@@ -1283,11 +1283,20 @@ public abstract class NotificationListenerService extends Service {
return mSnoozeCriteria;
}
/**
* Returns whether this notification can be displayed as a badge.
*
* @return true if the notification can be displayed as a badge, false otherwise.
*/
public boolean canShowBadge() {
return mShowBadge;
}
private void populate(String key, int rank, boolean matchesInterruptionFilter,
int visibilityOverride, int suppressedVisualEffects, int importance,
CharSequence explanation, String overrideGroupKey,
NotificationChannel overrideChannel, ArrayList<String> overridePeople,
ArrayList<SnoozeCriterion> snoozeCriteria) {
NotificationChannel channel, ArrayList<String> overridePeople,
ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1297,9 +1306,10 @@ public abstract class NotificationListenerService extends Service {
mImportance = importance;
mImportanceExplanation = explanation;
mOverrideGroupKey = overrideGroupKey;
mOverrideChannel = overrideChannel;
mChannel = channel;
mOverridePeople = overridePeople;
mSnoozeCriteria = snoozeCriteria;
mShowBadge = showBadge;
}
/**
@@ -1343,9 +1353,10 @@ public abstract class NotificationListenerService extends Service {
private ArrayMap<String, Integer> mImportance;
private ArrayMap<String, String> mImportanceExplanation;
private ArrayMap<String, String> mOverrideGroupKeys;
private ArrayMap<String, NotificationChannel> mOverrideChannels;
private ArrayMap<String, NotificationChannel> mChannels;
private ArrayMap<String, ArrayList<String>> mOverridePeople;
private ArrayMap<String, ArrayList<SnoozeCriterion>> mSnoozeCriteria;
private ArrayMap<String, Boolean> mShowBadge;
private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
@@ -1373,7 +1384,8 @@ public abstract class NotificationListenerService extends Service {
outRanking.populate(key, rank, !isIntercepted(key),
getVisibilityOverride(key), getSuppressedVisualEffects(key),
getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
getOverrideChannel(key), getOverridePeople(key), getSnoozeCriteria(key));
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
getShowBadge(key));
return rank >= 0;
}
@@ -1453,13 +1465,13 @@ public abstract class NotificationListenerService extends Service {
return mOverrideGroupKeys.get(key);
}
private NotificationChannel getOverrideChannel(String key) {
private NotificationChannel getChannel(String key) {
synchronized (this) {
if (mOverrideChannels == null) {
buildOverrideChannelsLocked();
if (mChannels == null) {
buildChannelsLocked();
}
}
return mOverrideChannels.get(key);
return mChannels.get(key);
}
private ArrayList<String> getOverridePeople(String key) {
@@ -1480,6 +1492,16 @@ public abstract class NotificationListenerService extends Service {
return mSnoozeCriteria.get(key);
}
private boolean getShowBadge(String key) {
synchronized (this) {
if (mShowBadge == null) {
buildShowBadgeLocked();
}
}
Boolean showBadge = mShowBadge.get(key);
return showBadge == null ? false : showBadge.booleanValue();
}
// Locked by 'this'
private void buildRanksLocked() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
@@ -1544,11 +1566,11 @@ public abstract class NotificationListenerService extends Service {
}
// Locked by 'this'
private void buildOverrideChannelsLocked() {
Bundle overrideChannels = mRankingUpdate.getOverrideChannels();
mOverrideChannels = new ArrayMap<>(overrideChannels.size());
for (String key : overrideChannels.keySet()) {
mOverrideChannels.put(key, overrideChannels.getParcelable(key));
private void buildChannelsLocked() {
Bundle channels = mRankingUpdate.getChannels();
mChannels = new ArrayMap<>(channels.size());
for (String key : channels.keySet()) {
mChannels.put(key, channels.getParcelable(key));
}
}
@@ -1570,6 +1592,15 @@ public abstract class NotificationListenerService extends Service {
}
}
// Locked by 'this'
private void buildShowBadgeLocked() {
Bundle showBadge = mRankingUpdate.getShowBadge();
mShowBadge = new ArrayMap<>(showBadge.size());
for (String key : showBadge.keySet()) {
mShowBadge.put(key, showBadge.getBoolean(key));
}
}
// ----------- Parcelable
@Override

View File

@@ -31,14 +31,16 @@ public class NotificationRankingUpdate implements Parcelable {
private final int[] mImportance;
private final Bundle mImportanceExplanation;
private final Bundle mOverrideGroupKeys;
private final Bundle mOverrideChannels;
private final Bundle mChannels;
private final Bundle mOverridePeople;
private final Bundle mSnoozeCriteria;
private final Bundle mShowBadge;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
Bundle overrideChannels, Bundle overridePeople, Bundle snoozeCriteria) {
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
Bundle showBadge) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
@@ -46,9 +48,10 @@ public class NotificationRankingUpdate implements Parcelable {
mImportance = importance;
mImportanceExplanation = explanation;
mOverrideGroupKeys = overrideGroupKeys;
mOverrideChannels = overrideChannels;
mChannels = channels;
mOverridePeople = overridePeople;
mSnoozeCriteria = snoozeCriteria;
mShowBadge = showBadge;
}
public NotificationRankingUpdate(Parcel in) {
@@ -60,9 +63,10 @@ public class NotificationRankingUpdate implements Parcelable {
in.readIntArray(mImportance);
mImportanceExplanation = in.readBundle();
mOverrideGroupKeys = in.readBundle();
mOverrideChannels = in.readBundle();
mChannels = in.readBundle();
mOverridePeople = in.readBundle();
mSnoozeCriteria = in.readBundle();
mShowBadge = in.readBundle();
}
@Override
@@ -79,9 +83,10 @@ public class NotificationRankingUpdate implements Parcelable {
out.writeIntArray(mImportance);
out.writeBundle(mImportanceExplanation);
out.writeBundle(mOverrideGroupKeys);
out.writeBundle(mOverrideChannels);
out.writeBundle(mChannels);
out.writeBundle(mOverridePeople);
out.writeBundle(mSnoozeCriteria);
out.writeBundle(mShowBadge);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -123,8 +128,8 @@ public class NotificationRankingUpdate implements Parcelable {
return mOverrideGroupKeys;
}
public Bundle getOverrideChannels() {
return mOverrideChannels;
public Bundle getChannels() {
return mChannels;
}
public Bundle getOverridePeople() {
@@ -134,4 +139,8 @@ public class NotificationRankingUpdate implements Parcelable {
public Bundle getSnoozeCriteria() {
return mSnoozeCriteria;
}
public Bundle getShowBadge() {
return mShowBadge;
}
}

View File

@@ -43,21 +43,18 @@ public class StatusBarNotification implements Parcelable {
private final Notification notification;
private final UserHandle user;
private final long postTime;
private final NotificationChannel channel;
private Context mContext; // used for inflation & icon expansion
/** @hide */
public StatusBarNotification(String pkg, String opPkg, NotificationChannel channel, int id,
public StatusBarNotification(String pkg, String opPkg, int id,
String tag, int uid, int initialPid, Notification notification, UserHandle user,
String overrideGroupKey, long postTime) {
if (pkg == null) throw new NullPointerException();
if (notification == null) throw new NullPointerException();
if (channel == null) throw new IllegalArgumentException();
this.pkg = pkg;
this.opPkg = opPkg;
this.channel = channel;
this.id = id;
this.tag = tag;
this.uid = uid;
@@ -88,7 +85,6 @@ public class StatusBarNotification implements Parcelable {
this.postTime = postTime;
this.key = key();
this.groupKey = groupKey();
this.channel = null;
}
public StatusBarNotification(Parcel in) {
@@ -112,7 +108,6 @@ public class StatusBarNotification implements Parcelable {
}
this.key = key();
this.groupKey = groupKey();
this.channel = NotificationChannel.CREATOR.createFromParcel(in);
}
private String key() {
@@ -182,7 +177,6 @@ public class StatusBarNotification implements Parcelable {
} else {
out.writeInt(0);
}
this.channel.writeToParcel(out, flags);
}
public int describeContents() {
@@ -209,14 +203,14 @@ public class StatusBarNotification implements Parcelable {
public StatusBarNotification cloneLight() {
final Notification no = new Notification();
this.notification.cloneInto(no, false); // light copy
return new StatusBarNotification(this.pkg, this.opPkg, this.channel,
return new StatusBarNotification(this.pkg, this.opPkg,
this.id, this.tag, this.uid, this.initialPid,
no, this.user, this.overrideGroupKey, this.postTime);
}
@Override
public StatusBarNotification clone() {
return new StatusBarNotification(this.pkg, this.opPkg, this.channel,
return new StatusBarNotification(this.pkg, this.opPkg,
this.id, this.tag, this.uid, this.initialPid,
this.notification.clone(), this.user, this.overrideGroupKey, this.postTime);
}
@@ -335,13 +329,6 @@ public class StatusBarNotification implements Parcelable {
return overrideGroupKey;
}
/**
* Returns the channel this notification was posted to.
*/
public NotificationChannel getNotificationChannel() {
return channel;
}
/**
* @hide
*/

View File

@@ -2090,6 +2090,7 @@
<item>com.android.server.notification.ImportanceExtractor</item>
<item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
<item>com.android.server.notification.VisibilityExtractor</item>
<item>com.android.server.notification.BadgeExtractor</item>
</string-array>
<!-- Flag indicating that this device does not rotate and will always remain in its default

View File

@@ -24,6 +24,7 @@ import android.app.ActivityOptions;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.RemoteInput;
@@ -1038,6 +1039,7 @@ public abstract class BaseStatusBar extends SystemUI implements
private void bindGuts(final ExpandableNotificationRow row) {
row.inflateGuts();
final StatusBarNotification sbn = row.getStatusBarNotification();
final NotificationChannel channel = row.getEntry().channel;
PackageManager pmUser = getPackageManagerForUser(mContext, sbn.getUser().getIdentifier());
row.setTag(sbn.getPackageName());
final NotificationGuts guts = row.getGuts();
@@ -1077,8 +1079,8 @@ public abstract class BaseStatusBar extends SystemUI implements
closeControls(row, guts, v);
}
};
guts.bindNotification(pmUser, iNotificationManager, sbn, onSettingsClick, onDoneClick,
mNonBlockablePkgs);
guts.bindNotification(pmUser, iNotificationManager, sbn, channel,
onSettingsClick, onDoneClick, mNonBlockablePkgs);
}
private void closeControls(

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.drawable.Icon;
@@ -55,6 +56,7 @@ public class NotificationData {
private static final int COLOR_INVALID = 1;
public String key;
public StatusBarNotification notification;
public NotificationChannel channel;
public StatusBarIconView icon;
public StatusBarIconView expandedIcon;
public ExpandableNotificationRow row; // the outer expanded view
@@ -429,6 +431,14 @@ public class NotificationData {
return null;
}
public NotificationChannel getChannel(String key) {
if (mRankingMap != null) {
mRankingMap.getRanking(key, mTmpRanking);
return mTmpRanking.getChannel();
}
return null;
}
private void updateRankingAndSort(RankingMap ranking) {
if (ranking != null) {
mRankingMap = ranking;
@@ -442,6 +452,7 @@ public class NotificationData {
entry.notification.setOverrideGroupKey(overrideGroupKey);
mGroupManager.onEntryUpdated(entry, oldSbn);
}
entry.channel = getChannel(entry.key);
}
}
}

View File

@@ -72,11 +72,7 @@ public class NotificationGuts extends LinearLayout {
private INotificationManager mINotificationManager;
private int mStartingUserImportance;
private StatusBarNotification mStatusBarNotification;
private ImageView mAutoButton;
private TextView mImportanceSummary;
private TextView mImportanceTitle;
private boolean mAuto;
private NotificationChannel mNotificationChannel;
private View mImportanceGroup;
private View mChannelDisabled;
@@ -170,11 +166,12 @@ public class NotificationGuts extends LinearLayout {
}
void bindNotification(final PackageManager pm, final INotificationManager iNotificationManager,
final StatusBarNotification sbn, OnSettingsClickListener onSettingsClick,
final StatusBarNotification sbn, final NotificationChannel channel,
OnSettingsClickListener onSettingsClick,
OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) {
mINotificationManager = iNotificationManager;
mNotificationChannel = channel;
mStatusBarNotification = sbn;
final NotificationChannel channel = sbn.getNotificationChannel();
mStartingUserImportance = channel.getImportance();
final String pkg = sbn.getPackageName();
@@ -288,14 +285,13 @@ public class NotificationGuts extends LinearLayout {
if (selectedImportance == mStartingUserImportance) {
return;
}
final NotificationChannel channel = mStatusBarNotification.getNotificationChannel();
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
selectedImportance - mStartingUserImportance);
channel.setImportance(selectedImportance);
mNotificationChannel.setImportance(selectedImportance);
try {
mINotificationManager.updateNotificationChannelForPackage(
mStatusBarNotification.getPackageName(), mStatusBarNotification.getUid(),
channel);
mNotificationChannel);
} catch (RemoteException e) {
// :(
}

View File

@@ -1388,7 +1388,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
sbn.getOpPkg(), sbn.getNotificationChannel(),
sbn.getOpPkg(),
sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
newNotification, sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());

View File

@@ -91,7 +91,6 @@ public class NotificationGutsTest {
// mMockStatusBarNotification with a test channel.
mNotificationChannel = new NotificationChannel(
TEST_CHANNEL, TEST_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
when(mMockStatusBarNotification.getNotificationChannel()).thenReturn(mNotificationChannel);
when(mMockStatusBarNotification.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
}
@@ -100,7 +99,7 @@ public class NotificationGutsTest {
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
final TextView textView = (TextView) mNotificationGuts.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -109,7 +108,7 @@ public class NotificationGutsTest {
@UiThreadTest
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
final TextView textView = (TextView) mNotificationGuts.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@@ -119,8 +118,8 @@ public class NotificationGutsTest {
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, (View v, int appUid) -> { latch.countDown(); },
null, null);
mMockStatusBarNotification, mNotificationChannel,
(View v, int appUid) -> { latch.countDown(); }, null, null);
final TextView settingsButton =
(TextView) mNotificationGuts.findViewById(R.id.more_settings);
@@ -134,7 +133,7 @@ public class NotificationGutsTest {
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null,
mMockStatusBarNotification, mNotificationChannel, null,
(View v) -> { latch.countDown(); },
null);
@@ -148,7 +147,7 @@ public class NotificationGutsTest {
@UiThreadTest
public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
assertFalse(mNotificationGuts.hasImportanceChanged());
}
@@ -157,7 +156,7 @@ public class NotificationGutsTest {
public void testHasImportanceChanged_ReturnsTrueAfterButtonChecked() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
// Find the high button and check it.
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
highButton.setChecked(true);
@@ -169,7 +168,7 @@ public class NotificationGutsTest {
public void testImportanceButtonCheckedBasedOnInitialImportance() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_HIGH);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
assertTrue(highButton.isChecked());
@@ -179,7 +178,7 @@ public class NotificationGutsTest {
@UiThreadTest
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@@ -189,7 +188,7 @@ public class NotificationGutsTest {
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
highButton.setChecked(true);
@@ -201,7 +200,7 @@ public class NotificationGutsTest {
@UiThreadTest
public void testCloseControls_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception {
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
mNotificationGuts.closeControls(-1, -1, true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -213,7 +212,7 @@ public class NotificationGutsTest {
public void testCloseControls_DoesNotUpdateNotificationChannelIfUnspecified() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
mNotificationGuts.closeControls(-1, -1, true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -225,7 +224,7 @@ public class NotificationGutsTest {
public void testCloseControls_CallsUpdateNotificationChannelIfChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
highButton.setChecked(true);
@@ -240,7 +239,7 @@ public class NotificationGutsTest {
public void testCloseControls_DoesNotUpdateNotificationChannelIfSaveFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
highButton.setChecked(true);
@@ -254,7 +253,7 @@ public class NotificationGutsTest {
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
assertTrue(enabledSwitch.isChecked());
@@ -265,7 +264,7 @@ public class NotificationGutsTest {
public void testEnabledSwitchVisibleByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
@@ -276,7 +275,8 @@ public class NotificationGutsTest {
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, Collections.singleton(TEST_PACKAGE_NAME));
mMockStatusBarNotification, mNotificationChannel, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
@@ -287,7 +287,8 @@ public class NotificationGutsTest {
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, Collections.singleton(TEST_PACKAGE_NAME));
mMockStatusBarNotification, mNotificationChannel, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -301,7 +302,7 @@ public class NotificationGutsTest {
public void testEnabledSwitchOverridesOtherButtons() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, null, null, null);
mMockStatusBarNotification, mNotificationChannel, null, null, null);
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
RadioButton lowButton = (RadioButton) mNotificationGuts.findViewById(R.id.low_importance);

View File

@@ -0,0 +1,59 @@
/**
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.notification;
import android.content.Context;
import android.util.Slog;
/**
* Determines whether a badge should be shown for this notification
*/
public class BadgeExtractor implements NotificationSignalExtractor {
private static final String TAG = "BadgeExtractor";
private static final boolean DBG = false;
private RankingConfig mConfig;
public void initialize(Context ctx, NotificationUsageStats usageStats) {
if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
}
public RankingReconsideration process(NotificationRecord record) {
if (record == null || record.getNotification() == null) {
if (DBG) Slog.d(TAG, "skipping empty notification");
return null;
}
if (mConfig == null) {
if (DBG) Slog.d(TAG, "missing config");
return null;
}
boolean appCanShowBadge =
mConfig.canShowBadge(record.sbn.getPackageName(), record.sbn.getUid());
if (!appCanShowBadge) {
record.setShowBadge(false);
} else {
record.setShowBadge(record.getChannel().canShowBadge() && appCanShowBadge);
}
return null;
}
@Override
public void setConfig(RankingConfig config) {
mConfig = config;
}
}

View File

@@ -1243,6 +1243,35 @@ public class NotificationManagerService extends SystemService {
sendRegisteredOnlyBroadcast(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
}
private void updateNotificationChannelInt(String pkg, int uid, NotificationChannel channel,
boolean fromAssistant) {
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
// cancel
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED,
null);
}
if (fromAssistant) {
mRankingHelper.updateNotificationChannelFromAssistant(pkg, uid, channel);
} else {
mRankingHelper.updateNotificationChannel(pkg, uid, channel);
}
synchronized (mNotificationList) {
final int N = mNotificationList.size();
for (int i = N - 1; i >= 0; --i) {
NotificationRecord r = mNotificationList.get(i);
if (channel.getId() != null && channel.getId().equals(r.getChannel().getId())) {
r.updateNotificationChannel(mRankingHelper.getNotificationChannel(
r.sbn.getPackageName(), r.getUser().getIdentifier(),
channel.getId(), false));
}
}
}
mRankingHandler.requestSort(true);
savePolicyFile();
}
private ArrayList<ComponentName> getSuppressors() {
ArrayList<ComponentName> names = new ArrayList<ComponentName>();
for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
@@ -1520,6 +1549,19 @@ public class NotificationManagerService extends SystemService {
return mRankingHelper.getImportance(pkg, Binder.getCallingUid());
}
@Override
public boolean canShowBadge(String pkg, int uid) {
checkCallerIsSystem();
return mRankingHelper.canShowBadge(pkg, uid);
}
@Override
public void setShowBadge(String pkg, int uid, boolean showBadge) {
checkCallerIsSystem();
mRankingHelper.setShowBadge(pkg, uid, showBadge);
savePolicyFile();
}
@Override
public void createNotificationChannels(String pkg,
ParceledListSlice channelsList) throws RemoteException {
@@ -1566,15 +1608,8 @@ public class NotificationManagerService extends SystemService {
public void updateNotificationChannelForPackage(String pkg, int uid,
NotificationChannel channel) {
enforceSystemOrSystemUI("Caller not system or systemui");
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
// cancel
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED,
null);
}
mRankingHelper.updateNotificationChannel(pkg, uid, channel);
mRankingHandler.requestSort(true);
savePolicyFile();
Preconditions.checkNotNull(channel);
updateNotificationChannelInt(pkg, uid, channel, false);
}
@Override
@@ -1701,7 +1736,6 @@ public class NotificationManagerService extends SystemService {
return new StatusBarNotification(
sbn.getPackageName(),
sbn.getOpPkg(),
sbn.getNotificationChannel(),
sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
sbn.getNotification().clone(),
sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
@@ -2495,15 +2529,9 @@ public class NotificationManagerService extends SystemService {
public void updateNotificationChannelFromAssistant(INotificationListener token, String pkg,
NotificationChannel channel) throws RemoteException {
ManagedServiceInfo info = mNotificationAssistants.checkServiceTokenLocked(token);
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
// cancel
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
info.userid, REASON_CHANNEL_BANNED, null);
}
Preconditions.checkNotNull(channel);
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
mRankingHelper.updateNotificationChannelFromAssistant(pkg, uid, channel);
mRankingHandler.requestSort(true);
savePolicyFile();
updateNotificationChannelInt(pkg, uid, channel, true);
}
@Override
@@ -2528,7 +2556,7 @@ public class NotificationManagerService extends SystemService {
final ArrayList<SnoozeCriterion> snoozeCriterionList =
adjustment.getSignals().getParcelableArrayList(Adjustment.KEY_SNOOZE_CRITERIA);
if (!TextUtils.isEmpty(overrideChannelId)) {
n.setNotificationChannelOverride(mRankingHelper.getNotificationChannel(
n.updateNotificationChannel(mRankingHelper.getNotificationChannel(
n.sbn.getPackageName(), n.sbn.getUid(), overrideChannelId,
false /* includeDeleted */));
}
@@ -2610,13 +2638,13 @@ public class NotificationManagerService extends SystemService {
final StatusBarNotification summarySbn =
new StatusBarNotification(adjustedSbn.getPackageName(),
adjustedSbn.getOpPkg(),
adjustedSbn.getNotificationChannel(),
Integer.MAX_VALUE,
GroupHelper.AUTOGROUP_KEY, adjustedSbn.getUid(),
adjustedSbn.getInitialPid(), summaryNotification,
adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY,
System.currentTimeMillis());
summaryRecord = new NotificationRecord(getContext(), summarySbn);
summaryRecord = new NotificationRecord(getContext(), summarySbn,
notificationRecord.getChannel());
summaries.put(pkg, summarySbn.getKey());
}
}
@@ -2882,7 +2910,7 @@ public class NotificationManagerService extends SystemService {
final NotificationChannel channel = mRankingHelper.getNotificationChannelWithFallback(pkg,
callingUid, notification.getChannel(), false /* includeDeleted */);
final StatusBarNotification n = new StatusBarNotification(
pkg, opPkg, channel, id, tag, callingUid, callingPid, notification,
pkg, opPkg, id, tag, callingUid, callingPid, notification,
user, null, System.currentTimeMillis());
// Limit the number of notifications that any given package except the android
@@ -2946,7 +2974,7 @@ public class NotificationManagerService extends SystemService {
Notification.PRIORITY_MAX);
// setup local book-keeping
final NotificationRecord r = new NotificationRecord(getContext(), n);
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
synchronized (mNotificationLock) {
mEnqueuedNotifications.add(r);
}
@@ -3490,14 +3518,18 @@ public class NotificationManagerService extends SystemService {
boolean forceUpdate = ((Boolean) msg.obj == null) ? false : (boolean) msg.obj;
synchronized (mNotificationLock) {
final int N = mNotificationList.size();
// Any field that can change via one of the extractors or by the assistant
// needs to be added here.
ArrayList<String> orderBefore = new ArrayList<String>(N);
ArrayList<String> groupOverrideBefore = new ArrayList<>(N);
int[] visibilities = new int[N];
boolean[] showBadges = new boolean[N];
for (int i = 0; i < N; i++) {
final NotificationRecord r = mNotificationList.get(i);
orderBefore.add(r.getKey());
groupOverrideBefore.add(r.sbn.getGroupKey());
visibilities[i] = r.getPackageVisibilityOverride();
showBadges[i] = r.canShowBadge();
mRankingHelper.extractSignals(r);
}
mRankingHelper.sort(mNotificationList);
@@ -3506,7 +3538,8 @@ public class NotificationManagerService extends SystemService {
if (forceUpdate
|| !orderBefore.get(i).equals(r.getKey())
|| visibilities[i] != r.getPackageVisibilityOverride()
|| !groupOverrideBefore.get(i).equals(r.sbn.getGroupKey())) {
|| !groupOverrideBefore.get(i).equals(r.sbn.getGroupKey())
|| showBadges[i] != r.canShowBadge()) {
scheduleSendRankingUpdate();
return;
}
@@ -4246,9 +4279,10 @@ public class NotificationManagerService extends SystemService {
Bundle visibilityOverrides = new Bundle();
Bundle suppressedVisualEffects = new Bundle();
Bundle explanation = new Bundle();
Bundle overrideChannels = new Bundle();
Bundle channels = new Bundle();
Bundle overridePeople = new Bundle();
Bundle snoozeCriteria = new Bundle();
Bundle showBadge = new Bundle();
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
if (!isVisibleToListener(record.sbn, info)) {
@@ -4270,9 +4304,10 @@ public class NotificationManagerService extends SystemService {
visibilityOverrides.putInt(key, record.getPackageVisibilityOverride());
}
overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey());
overrideChannels.putParcelable(key, record.getChannel());
channels.putParcelable(key, record.getChannel());
overridePeople.putStringArrayList(key, record.getPeopleOverride());
snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria());
showBadge.putBoolean(key, record.canShowBadge());
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
@@ -4283,7 +4318,7 @@ public class NotificationManagerService extends SystemService {
}
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
overrideChannels, overridePeople, snoozeCriteria);
channels, overridePeople, snoozeCriteria, showBadge);
}
private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {

View File

@@ -25,7 +25,6 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -114,12 +113,14 @@ public final class NotificationRecord {
private Uri mSound;
private long[] mVibration;
private AudioAttributes mAttributes;
private NotificationChannel mOverrideChannel;
private NotificationChannel mChannel;
private ArrayList<String> mPeopleOverride;
private ArrayList<SnoozeCriterion> mSnoozeCriteria;
private boolean mShowBadge;
@VisibleForTesting
public NotificationRecord(Context context, StatusBarNotification sbn)
public NotificationRecord(Context context, StatusBarNotification sbn,
NotificationChannel channel)
{
this.sbn = sbn;
mOriginalFlags = sbn.getNotification().flags;
@@ -128,6 +129,7 @@ public final class NotificationRecord {
mUpdateTimeMs = mCreationTimeMs;
mContext = context;
stats = new NotificationUsageStats.SingleNotificationStats();
mChannel = channel;
mPreChannelsNotification = isPreChannelsNotification();
mSound = calculateSound();
mVibration = calculateVibration();
@@ -154,7 +156,7 @@ public final class NotificationRecord {
private Uri calculateSound() {
final Notification n = sbn.getNotification();
Uri sound = sbn.getNotificationChannel().getSound();
Uri sound = mChannel.getSound();
if (mPreChannelsNotification && (getChannel().getUserLockedFields()
& NotificationChannel.USER_LOCKED_SOUND) == 0) {
@@ -386,7 +388,8 @@ public final class NotificationRecord {
pw.println(prefix + " mSound= " + mSound);
pw.println(prefix + " mVibration= " + mVibration);
pw.println(prefix + " mAttributes= " + mAttributes);
pw.println(prefix + " overrideChannel=" + getChannel());
pw.println(prefix + " mShowBadge=" + mShowBadge);
pw.println(prefix + " channel=" + getChannel());
if (getPeopleOverride() != null) {
pw.println(prefix + " overridePeople= " + TextUtils.join(",", getPeopleOverride()));
}
@@ -640,16 +643,24 @@ public final class NotificationRecord {
}
public NotificationChannel getChannel() {
return mOverrideChannel == null ? sbn.getNotificationChannel() : mOverrideChannel;
return mChannel;
}
protected void setNotificationChannelOverride(NotificationChannel channel) {
mOverrideChannel = channel;
if (mOverrideChannel != null) {
protected void updateNotificationChannel(NotificationChannel channel) {
if (channel != null) {
mChannel = channel;
calculateImportance();
}
}
public void setShowBadge(boolean showBadge) {
mShowBadge = showBadge;
}
public boolean canShowBadge() {
return mShowBadge;
}
public Uri getSound() {
return mSound;
}

View File

@@ -22,6 +22,8 @@ public interface RankingConfig {
void setImportance(String packageName, int uid, int importance);
int getImportance(String packageName, int uid);
void setShowBadge(String packageName, int uid, boolean showBadge);
boolean canShowBadge(String packageName, int uid);
void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp);

View File

@@ -67,10 +67,12 @@ public class RankingHelper implements RankingConfig {
private static final String ATT_PRIORITY = "priority";
private static final String ATT_VISIBILITY = "visibility";
private static final String ATT_IMPORTANCE = "importance";
private static final String ATT_SHOW_BADGE = "show_badge";
private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE;
private static final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_UNSPECIFIED;
private static final boolean DEFAULT_SHOW_BADGE = true;
private final NotificationSignalExtractor[] mSignalExtractors;
private final NotificationComparator mPreliminaryComparator;
@@ -169,7 +171,8 @@ public class RankingHelper implements RankingConfig {
Record r = getOrCreateRecord(name, uid,
safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY));
safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
// Channels
final int innerDepth = parser.getDepth();
@@ -215,11 +218,11 @@ public class RankingHelper implements RankingConfig {
private Record getOrCreateRecord(String pkg, int uid) {
return getOrCreateRecord(pkg, uid,
DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY);
DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE);
}
private Record getOrCreateRecord(String pkg, int uid, int importance, int priority,
int visibility) {
int visibility, boolean showBadge) {
final String key = recordKey(pkg, uid);
Record r = (uid == Record.UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg) : mRecords.get(key);
if (r == null) {
@@ -229,6 +232,7 @@ public class RankingHelper implements RankingConfig {
r.importance = importance;
r.priority = priority;
r.visibility = visibility;
r.showBadge = showBadge;
createDefaultChannelIfMissing(r);
if (r.uid == Record.UNKNOWN_UID) {
mRestoredWithoutUids.put(pkg, r);
@@ -298,7 +302,7 @@ public class RankingHelper implements RankingConfig {
}
final boolean hasNonDefaultSettings = r.importance != DEFAULT_IMPORTANCE
|| r.priority != DEFAULT_PRIORITY || r.visibility != DEFAULT_VISIBILITY
|| r.channels.size() > 0;
|| r.showBadge != DEFAULT_SHOW_BADGE || r.channels.size() > 0;
if (hasNonDefaultSettings) {
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATT_NAME, r.pkg);
@@ -311,6 +315,7 @@ public class RankingHelper implements RankingConfig {
if (r.visibility != DEFAULT_VISIBILITY) {
out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
}
out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(r.showBadge));
if (!forBackup) {
out.attribute(null, ATT_UID, Integer.toString(r.uid));
@@ -396,6 +401,12 @@ public class RankingHelper implements RankingConfig {
return Collections.binarySearch(notificationList, target, mFinalComparator);
}
private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
final String value = parser.getAttributeValue(null, att);
if (TextUtils.isEmpty(value)) return defValue;
return Boolean.parseBoolean(value);
}
private static int safeInt(XmlPullParser parser, String att, int defValue) {
final String val = parser.getAttributeValue(null, att);
return tryParseInt(val, defValue);
@@ -418,6 +429,17 @@ public class RankingHelper implements RankingConfig {
return getOrCreateRecord(packageName, uid).importance;
}
@Override
public boolean canShowBadge(String packageName, int uid) {
return getOrCreateRecord(packageName, uid).showBadge;
}
@Override
public void setShowBadge(String packageName, int uid, boolean showBadge) {
getOrCreateRecord(packageName, uid).showBadge = showBadge;
updateConfig();
}
@Override
public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp) {
@@ -454,6 +476,9 @@ public class RankingHelper implements RankingConfig {
if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
channel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
}
if (!r.showBadge) {
channel.setShowBadge(false);
}
r.channels.put(channel.getId(), channel);
updateConfig();
}
@@ -672,7 +697,7 @@ public class RankingHelper implements RankingConfig {
final Record r = records.valueAt(i);
if (filter == null || filter.matches(r.pkg)) {
pw.print(prefix);
pw.print(" ");
pw.print(" AppSettings: ");
pw.print(r.pkg);
pw.print(" (");
pw.print(r.uid == Record.UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid));
@@ -689,6 +714,8 @@ public class RankingHelper implements RankingConfig {
pw.print(" visibility=");
pw.print(Notification.visibilityToString(r.visibility));
}
pw.print(" showBadge=");
pw.print(Boolean.toString(r.showBadge));
pw.println();
for (NotificationChannel channel : r.channels.values()) {
pw.print(prefix);
@@ -725,6 +752,9 @@ public class RankingHelper implements RankingConfig {
if (r.visibility != DEFAULT_VISIBILITY) {
record.put("visibility", Notification.visibilityToString(r.visibility));
}
if (r.showBadge != DEFAULT_SHOW_BADGE) {
record.put("showBadge", Boolean.valueOf(r.showBadge));
}
for (NotificationChannel channel : r.channels.values()) {
record.put("channel", channel.toJson());
}
@@ -838,6 +868,7 @@ public class RankingHelper implements RankingConfig {
int importance = DEFAULT_IMPORTANCE;
int priority = DEFAULT_PRIORITY;
int visibility = DEFAULT_VISIBILITY;
boolean showBadge = DEFAULT_SHOW_BADGE;
ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.notification;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BadgeExtractorTest {
@Mock RankingConfig mConfig;
private String mPkg = "com.android.server.notification";
private int mId = 1001;
private String mTag = null;
private int mUid = 1000;
private int mPid = 2000;
private UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
private NotificationRecord getNotificationRecord(NotificationChannel channel) {
final Builder builder = new Builder(getContext())
.setContentTitle("foo")
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.DEFAULT_SOUND);
Notification n = builder.build();
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
mPid, n, mUser, null, System.currentTimeMillis());
NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
return r;
}
private Context getContext() {
return InstrumentationRegistry.getTargetContext();
}
//
// Tests
//
@Test
public void testAppYesChannelNo() throws Exception {
BadgeExtractor extractor = new BadgeExtractor();
extractor.setConfig(mConfig);
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
channel.setShowBadge(false);
NotificationRecord r = getNotificationRecord(channel);
extractor.process(r);
assertFalse(r.canShowBadge());
}
@Test
public void testAppNoChannelYes() throws Exception {
BadgeExtractor extractor = new BadgeExtractor();
extractor.setConfig(mConfig);
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(false);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_HIGH);
channel.setShowBadge(true);
NotificationRecord r = getNotificationRecord(channel);
extractor.process(r);
assertFalse(r.canShowBadge());
}
@Test
public void testAppYesChannelYes() throws Exception {
BadgeExtractor extractor = new BadgeExtractor();
extractor.setConfig(mConfig);
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
channel.setShowBadge(true);
NotificationRecord r = getNotificationRecord(channel);
extractor.process(r);
assertTrue(r.canShowBadge());
}
@Test
public void testAppNoChannelNo() throws Exception {
BadgeExtractor extractor = new BadgeExtractor();
extractor.setConfig(mConfig);
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(false);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
channel.setShowBadge(false);
NotificationRecord r = getNotificationRecord(channel);
extractor.process(r);
assertFalse(r.canShowBadge());
}
}

View File

@@ -230,9 +230,9 @@ public class BuzzBeepBlinkTest {
n.flags |= Notification.FLAG_INSISTENT;
}
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, channel, id, mTag, mUid,
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
mPid, n, mUser, null, System.currentTimeMillis());
NotificationRecord r = new NotificationRecord(getContext(), sbn);
NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
mService.addNotification(r);
return r;
}

View File

@@ -70,9 +70,7 @@ public class GroupHelperTest {
if (groupKey != null) {
nb.setGroup(groupKey);
}
NotificationChannel channel =
new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_LOW);
return new StatusBarNotification(pkg, pkg, channel, id, tag, 0, 0, nb.build(), user, null,
return new StatusBarNotification(pkg, pkg, id, tag, 0, 0, nb.build(), user, null,
System.currentTimeMillis());
}

View File

@@ -69,9 +69,9 @@ public class ImportanceExtractorTest {
.setDefaults(Notification.DEFAULT_SOUND);
Notification n = builder.build();
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, channel, mId, mTag, mUid,
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
mPid, n, mUser, null, System.currentTimeMillis());
NotificationRecord r = new NotificationRecord(getContext(), sbn);
NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
return r;
}

View File

@@ -105,8 +105,8 @@ public class NotificationComparatorTest {
.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
mRecordMinCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
callPkg, getDefaultChannel(), 1, "minCall", callUid, callUid, n1,
new UserHandle(userId), "", 2000));
callPkg, 1, "minCall", callUid, callUid, n1,
new UserHandle(userId), "", 2000), getDefaultChannel());
mRecordMinCall.setUserImportance(NotificationManager.IMPORTANCE_MIN);
Notification n2 = new Notification.Builder(mContext)
@@ -114,8 +114,8 @@ public class NotificationComparatorTest {
.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
callPkg, getDefaultChannel(), 1, "highcall", callUid, callUid, n2,
new UserHandle(userId), "", 1999));
callPkg, 1, "highcall", callUid, callUid, n2,
new UserHandle(userId), "", 1999), getDefaultChannel());
mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
Notification n3 = new Notification.Builder(mContext)
@@ -124,43 +124,43 @@ public class NotificationComparatorTest {
.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "media", uid2, uid2, n3, new UserHandle(userId),
"", 1499));
pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId),
"", 1499), getDefaultChannel());
mRecordDefaultMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
Notification n4 = new Notification.Builder(mContext)
.setStyle(new Notification.MessagingStyle("sender!")).build();
mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
"", 1599));
pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
"", 1599), getDefaultChannel());
mRecordInlineReply.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX);
Notification n5 = new Notification.Builder(mContext)
.setCategory(Notification.CATEGORY_MESSAGE).build();
mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg,
smsPkg, getDefaultChannel(), 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
"", 1299));
smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
"", 1299), getDefaultChannel());
mRecordSms.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
Notification n6 = new Notification.Builder(mContext).build();
mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "starred", uid2, uid2, n6, new UserHandle(userId),
"", 1259));
pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId),
"", 1259), getDefaultChannel());
mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT);
mRecordStarredContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
Notification n7 = new Notification.Builder(mContext).build();
mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "contact", uid2, uid2, n7, new UserHandle(userId),
"", 1259));
pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId),
"", 1259), getDefaultChannel());
mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT);
mRecordContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
Notification n8 = new Notification.Builder(mContext).build();
mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
"", 1258));
pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
"", 1258), getDefaultChannel());
mRecordUrgent.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
Notification n9 = new Notification.Builder(mContext)
@@ -169,15 +169,15 @@ public class NotificationComparatorTest {
|Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
mRecordCheater = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
"", 9258));
pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
"", 9258), getDefaultChannel());
mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW);
Notification n10 = new Notification.Builder(mContext)
.setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
pkg2, getDefaultChannel(), 1, "email", uid2, uid2, n10, new UserHandle(userId),
"", 1599));
pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
"", 1599), getDefaultChannel());
mRecordEmail.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
}

View File

@@ -59,6 +59,7 @@ public class NotificationListenerServiceTest {
assertEquals(getChannel(key, i), ranking.getChannel());
assertEquals(getPeople(key, i), ranking.getAdditionalPeople());
assertEquals(getSnoozeCriteria(key, i), ranking.getSnoozeCriteria());
assertEquals(getShowBadge(i), ranking.canShowBadge());
}
}
@@ -68,9 +69,10 @@ public class NotificationListenerServiceTest {
Bundle overrideGroupKeys = new Bundle();
Bundle suppressedVisualEffects = new Bundle();
Bundle explanation = new Bundle();
Bundle overrideChannels = new Bundle();
Bundle channels = new Bundle();
Bundle overridePeople = new Bundle();
Bundle snoozeCriteria = new Bundle();
Bundle showBadge = new Bundle();
int[] importance = new int[mKeys.length];
for (int i = 0; i < mKeys.length; i++) {
@@ -83,14 +85,15 @@ public class NotificationListenerServiceTest {
suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i));
importance[i] = getImportance(i);
explanation.putString(key, getExplanation(key));
overrideChannels.putParcelable(key, getChannel(key, i));
channels.putParcelable(key, getChannel(key, i));
overridePeople.putStringArrayList(key, getPeople(key, i));
snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i));
showBadge.putBoolean(key, getShowBadge(i));
}
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
interceptedKeys.toArray(new String[0]), visibilityOverrides,
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
overrideChannels, overridePeople, snoozeCriteria);
channels, overridePeople, snoozeCriteria, showBadge);
return update;
}
@@ -122,6 +125,10 @@ public class NotificationListenerServiceTest {
return new NotificationChannel(key, key, getImportance(index));
}
private boolean getShowBadge(int index) {
return index % 3 == 0;
}
private ArrayList<String> getPeople(String key, int index) {
ArrayList<String> people = new ArrayList<>();
for (int i = 0; i < index; i++) {

View File

@@ -132,9 +132,9 @@ public class NotificationManagerServiceTest {
.setPriority(Notification.PRIORITY_HIGH)
.build();
StatusBarNotification sbn = new StatusBarNotification(mContext.getPackageName(),
mContext.getPackageName(), channel, 1, "tag", uid, 0,
mContext.getPackageName(), 1, "tag", uid, 0,
n, new UserHandle(uid), null, 0);
return new NotificationRecord(mContext, sbn);
return new NotificationRecord(mContext, sbn, channel);
}
@Test

View File

@@ -136,10 +136,10 @@ public class NotificationRecordTest {
Notification n = builder.build();
if (preO) {
return new StatusBarNotification(pkg, pkg, defaultChannel, id1, tag1, uid, uid, n,
return new StatusBarNotification(pkg, pkg, id1, tag1, uid, uid, n,
mUser, null, uid);
} else {
return new StatusBarNotification(pkg2, pkg2, channel, id2, tag2, uid2, uid2, n,
return new StatusBarNotification(pkg2, pkg2, id2, tag2, uid2, uid2, n,
mUser, null, uid2);
}
}
@@ -155,7 +155,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, record.getSound());
}
@@ -166,7 +166,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
}
@@ -178,7 +178,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
}
@@ -189,7 +189,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_SOUND, record.getSound());
}
@@ -200,7 +200,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, true /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNotNull(record.getVibration());
}
@@ -211,7 +211,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_VIBRATION, record.getVibration());
}
@@ -223,7 +223,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
}
@@ -234,7 +234,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(false /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_CHANNEL_VIBRATION, record.getVibration());
}
@@ -245,7 +245,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
}
@@ -256,7 +256,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
}
@@ -264,7 +264,7 @@ public class NotificationRecordTest {
public void testImportance_preUpgrade() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
}
@@ -275,7 +275,7 @@ public class NotificationRecordTest {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_LOW, record.getImportance());
}
@@ -283,7 +283,7 @@ public class NotificationRecordTest {
public void testImportance_upgrade() throws Exception {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(NotificationManager.IMPORTANCE_DEFAULT, record.getImportance());
}
}

View File

@@ -105,8 +105,8 @@ public class RankingHelperTest {
.setWhen(1205)
.build();
mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortA, user,
null, System.currentTimeMillis()));
"package", "package", 1, null, 0, 0, mNotiGroupGSortA, user,
null, System.currentTimeMillis()), getDefaultChannel());
mNotiGroupGSortB = new Notification.Builder(getContext())
.setContentTitle("B")
@@ -115,24 +115,24 @@ public class RankingHelperTest {
.setWhen(1200)
.build();
mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortB, user,
null, System.currentTimeMillis()));
"package", "package", 1, null, 0, 0, mNotiGroupGSortB, user,
null, System.currentTimeMillis()), getDefaultChannel());
mNotiNoGroup = new Notification.Builder(getContext())
.setContentTitle("C")
.setWhen(1201)
.build();
mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup, user,
null, System.currentTimeMillis()));
"package", "package", 1, null, 0, 0, mNotiNoGroup, user,
null, System.currentTimeMillis()), getDefaultChannel());
mNotiNoGroup2 = new Notification.Builder(getContext())
.setContentTitle("D")
.setWhen(1202)
.build();
mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup2, user,
null, System.currentTimeMillis()));
"package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
null, System.currentTimeMillis()), getDefaultChannel());
mNotiNoGroupSortA = new Notification.Builder(getContext())
.setContentTitle("E")
@@ -140,8 +140,8 @@ public class RankingHelperTest {
.setSortKey("A")
.build();
mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
"package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroupSortA, user,
null, System.currentTimeMillis()));
"package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user,
null, System.currentTimeMillis()), getDefaultChannel());
final ApplicationInfo legacy = new ApplicationInfo();
legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
@@ -254,8 +254,12 @@ public class RankingHelperTest {
mHelper.createNotificationChannel(pkg, uid, channel1, true);
mHelper.createNotificationChannel(pkg, uid, channel2, false);
mHelper.setShowBadge(pkg, uid, true);
mHelper.setShowBadge(pkg2, uid2, false);
ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), channel2.getId(),
NotificationChannel.DEFAULT_CHANNEL_ID);
mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{pkg}, new int[]{uid});
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
@@ -263,6 +267,8 @@ public class RankingHelperTest {
parser.nextTag();
mHelper.readXml(parser, false);
assertFalse(mHelper.canShowBadge(pkg2, uid2));
assertTrue(mHelper.canShowBadge(pkg, uid));
assertEquals(channel1, mHelper.getNotificationChannel(pkg, uid, channel1.getId(), false));
compareChannels(channel2,
mHelper.getNotificationChannel(pkg, uid, channel2.getId(), false));
@@ -758,4 +764,11 @@ public class RankingHelperTest {
mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid});
assertEquals(2, mHelper.getNotificationChannels(pkg, uid, false).getList().size());
}
@Test
public void testRecordDefaults() throws Exception {
assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(pkg, uid));
assertEquals(true, mHelper.canShowBadge(pkg, uid));
assertEquals(1, mHelper.getNotificationChannels(pkg, uid, false).getList().size());
}
}

View File

@@ -199,8 +199,8 @@ public class SnoozeHelperTest {
.setWhen(1205)
.build();
return new NotificationRecord(getContext(), new StatusBarNotification(
pkg, pkg, getDefaultChannel(), id, tag, 0, 0, n, user, null,
System.currentTimeMillis()));
pkg, pkg, id, tag, 0, 0, n, user, null,
System.currentTimeMillis()), getDefaultChannel());
}
private NotificationChannel getDefaultChannel() {