Merge "Add notification channel groups."
This commit is contained in:
committed by
Android (Google) Code Review
commit
de3b86e73e
@@ -5420,6 +5420,7 @@ package android.app {
|
||||
method public boolean canShowBadge();
|
||||
method public int describeContents();
|
||||
method public void enableVibration(boolean);
|
||||
method public java.lang.String getGroup();
|
||||
method public java.lang.String getId();
|
||||
method public int getImportance();
|
||||
method public int getLockscreenVisibility();
|
||||
@@ -5427,6 +5428,7 @@ package android.app {
|
||||
method public android.net.Uri getSound();
|
||||
method public long[] getVibrationPattern();
|
||||
method public void setBypassDnd(boolean);
|
||||
method public void setGroup(java.lang.String);
|
||||
method public void setImportance(int);
|
||||
method public void setLights(boolean);
|
||||
method public void setLockscreenVisibility(int);
|
||||
@@ -5440,6 +5442,17 @@ package android.app {
|
||||
field public static final java.lang.String DEFAULT_CHANNEL_ID = "miscellaneous";
|
||||
}
|
||||
|
||||
public final class NotificationChannelGroup implements android.os.Parcelable {
|
||||
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
|
||||
ctor protected NotificationChannelGroup(android.os.Parcel);
|
||||
method public int describeContents();
|
||||
method public java.util.List<android.app.NotificationChannel> getChannels();
|
||||
method public java.lang.String getId();
|
||||
method public java.lang.CharSequence getName();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.app.NotificationChannelGroup> CREATOR;
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public java.lang.String addAutomaticZenRule(android.app.AutomaticZenRule);
|
||||
method public boolean areNotificationsEnabled();
|
||||
@@ -5447,6 +5460,8 @@ package android.app {
|
||||
method public void cancel(java.lang.String, int);
|
||||
method public void cancelAll();
|
||||
method public void createNotificationChannel(android.app.NotificationChannel);
|
||||
method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
|
||||
method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
|
||||
method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
|
||||
method public void deleteNotificationChannel(java.lang.String);
|
||||
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
|
||||
|
||||
@@ -5596,6 +5596,7 @@ package android.app {
|
||||
method public boolean canShowBadge();
|
||||
method public int describeContents();
|
||||
method public void enableVibration(boolean);
|
||||
method public java.lang.String getGroup();
|
||||
method public java.lang.String getId();
|
||||
method public int getImportance();
|
||||
method public int getLockscreenVisibility();
|
||||
@@ -5608,6 +5609,7 @@ package android.app {
|
||||
method public void populateFromXml(org.xmlpull.v1.XmlPullParser);
|
||||
method public void setBypassDnd(boolean);
|
||||
method public void setDeleted(boolean);
|
||||
method public void setGroup(java.lang.String);
|
||||
method public void setImportance(int);
|
||||
method public void setLights(boolean);
|
||||
method public void setLockscreenVisibility(int);
|
||||
@@ -5632,6 +5634,20 @@ package android.app {
|
||||
field public static final int USER_LOCKED_VISIBILITY = 2; // 0x2
|
||||
}
|
||||
|
||||
public final class NotificationChannelGroup implements android.os.Parcelable {
|
||||
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
|
||||
ctor protected NotificationChannelGroup(android.os.Parcel);
|
||||
method public void addChannel(android.app.NotificationChannel);
|
||||
method public int describeContents();
|
||||
method public java.util.List<android.app.NotificationChannel> getChannels();
|
||||
method public java.lang.String getId();
|
||||
method public java.lang.CharSequence getName();
|
||||
method public org.json.JSONObject toJson() throws org.json.JSONException;
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
method public void writeXml(org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
|
||||
field public static final android.os.Parcelable.Creator<android.app.NotificationChannelGroup> CREATOR;
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public java.lang.String addAutomaticZenRule(android.app.AutomaticZenRule);
|
||||
method public boolean areNotificationsEnabled();
|
||||
@@ -5639,6 +5655,8 @@ package android.app {
|
||||
method public void cancel(java.lang.String, int);
|
||||
method public void cancelAll();
|
||||
method public void createNotificationChannel(android.app.NotificationChannel);
|
||||
method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
|
||||
method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
|
||||
method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
|
||||
method public void deleteNotificationChannel(java.lang.String);
|
||||
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
|
||||
|
||||
@@ -5430,6 +5430,7 @@ package android.app {
|
||||
method public boolean canShowBadge();
|
||||
method public int describeContents();
|
||||
method public void enableVibration(boolean);
|
||||
method public java.lang.String getGroup();
|
||||
method public java.lang.String getId();
|
||||
method public int getImportance();
|
||||
method public int getLockscreenVisibility();
|
||||
@@ -5437,6 +5438,7 @@ package android.app {
|
||||
method public android.net.Uri getSound();
|
||||
method public long[] getVibrationPattern();
|
||||
method public void setBypassDnd(boolean);
|
||||
method public void setGroup(java.lang.String);
|
||||
method public void setImportance(int);
|
||||
method public void setLights(boolean);
|
||||
method public void setLockscreenVisibility(int);
|
||||
@@ -5450,6 +5452,17 @@ package android.app {
|
||||
field public static final java.lang.String DEFAULT_CHANNEL_ID = "miscellaneous";
|
||||
}
|
||||
|
||||
public final class NotificationChannelGroup implements android.os.Parcelable {
|
||||
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
|
||||
ctor protected NotificationChannelGroup(android.os.Parcel);
|
||||
method public int describeContents();
|
||||
method public java.util.List<android.app.NotificationChannel> getChannels();
|
||||
method public java.lang.String getId();
|
||||
method public java.lang.CharSequence getName();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.app.NotificationChannelGroup> CREATOR;
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public java.lang.String addAutomaticZenRule(android.app.AutomaticZenRule);
|
||||
method public boolean areNotificationsEnabled();
|
||||
@@ -5457,6 +5470,8 @@ package android.app {
|
||||
method public void cancel(java.lang.String, int);
|
||||
method public void cancelAll();
|
||||
method public void createNotificationChannel(android.app.NotificationChannel);
|
||||
method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
|
||||
method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
|
||||
method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
|
||||
method public void deleteNotificationChannel(java.lang.String);
|
||||
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
|
||||
|
||||
@@ -54,7 +54,9 @@ interface INotificationManager
|
||||
boolean areNotificationsEnabled(String pkg);
|
||||
int getPackageImportance(String pkg);
|
||||
|
||||
void createNotificationChannelGroups(String pkg, in ParceledListSlice channelGroupList);
|
||||
void createNotificationChannels(String pkg, in ParceledListSlice channelsList);
|
||||
ParceledListSlice getNotificationChannelGroupsForPackage(String pkg, int uid, boolean includeDeleted);
|
||||
void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
|
||||
NotificationChannel getNotificationChannel(String pkg, String channelId);
|
||||
NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, boolean includeDeleted);
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.NotificationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -49,6 +50,8 @@ public final class NotificationChannel implements Parcelable {
|
||||
private static final String ATT_VISIBILITY = "visibility";
|
||||
private static final String ATT_IMPORTANCE = "importance";
|
||||
private static final String ATT_LIGHTS = "lights";
|
||||
//TODO: add support for light colors
|
||||
private static final String ATT_LIGHT_COLOR = "light_color";
|
||||
private static final String ATT_VIBRATION = "vibration";
|
||||
private static final String ATT_VIBRATION_ENABLED = "vibration_enabled";
|
||||
private static final String ATT_SOUND = "sound";
|
||||
@@ -56,6 +59,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
private static final String ATT_AUDIO_ATTRIBUTES = "audio_attributes";
|
||||
private static final String ATT_SHOW_BADGE = "show_badge";
|
||||
private static final String ATT_USER_LOCKED = "locked";
|
||||
private static final String ATT_GROUP = "group";
|
||||
private static final String DELIMITER = ",";
|
||||
|
||||
/**
|
||||
@@ -136,6 +140,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
private boolean mVibrationEnabled;
|
||||
private boolean mShowBadge = DEFAULT_SHOW_BADGE;
|
||||
private boolean mDeleted = DEFAULT_DELETED;
|
||||
private String mGroup;
|
||||
|
||||
/**
|
||||
* Creates a notification channel.
|
||||
@@ -173,6 +178,11 @@ public final class NotificationChannel implements Parcelable {
|
||||
mVibrationEnabled = in.readByte() != 0;
|
||||
mShowBadge = in.readByte() != 0;
|
||||
mDeleted = in.readByte() != 0;
|
||||
if (in.readByte() != 0) {
|
||||
mGroup = in.readString();
|
||||
} else {
|
||||
mGroup = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,6 +209,12 @@ public final class NotificationChannel implements Parcelable {
|
||||
dest.writeByte(mVibrationEnabled ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(mShowBadge ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(mDeleted ? (byte) 1 : (byte) 0);
|
||||
if (mGroup != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeString(mGroup);
|
||||
} else {
|
||||
dest.writeByte((byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,6 +270,18 @@ public final class NotificationChannel implements Parcelable {
|
||||
|
||||
// Modifiable by apps on channel creation.
|
||||
|
||||
/**
|
||||
* Sets what group this channel belongs to.
|
||||
*
|
||||
* Group information is only used for presentation, not for behavior.
|
||||
*
|
||||
* @param groupId the id of a group created by
|
||||
* {@link NotificationManager#createNotificationChannelGroup(NotificationChannelGroup)}.
|
||||
*/
|
||||
public void setGroup(String groupId) {
|
||||
this.mGroup = groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether notifications posted to this channel can appear as application icon badges
|
||||
* in a Launcher.
|
||||
@@ -376,6 +404,15 @@ public final class NotificationChannel implements Parcelable {
|
||||
return mShowBadge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns what group this channel belongs to.
|
||||
*
|
||||
* This is used only for visually grouping channels in the UI.
|
||||
*/
|
||||
public String getGroup() {
|
||||
return mGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -407,6 +444,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
setVibrationPattern(safeLongArray(parser, ATT_VIBRATION, null));
|
||||
setShowBadge(safeBool(parser, ATT_SHOW_BADGE, false));
|
||||
setDeleted(safeBool(parser, ATT_DELETED, false));
|
||||
setGroup(parser.getAttributeValue(null, ATT_GROUP));
|
||||
lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
|
||||
}
|
||||
|
||||
@@ -451,6 +489,9 @@ public final class NotificationChannel implements Parcelable {
|
||||
if (isDeleted()) {
|
||||
out.attribute(null, ATT_DELETED, Boolean.toString(isDeleted()));
|
||||
}
|
||||
if (getGroup() != null) {
|
||||
out.attribute(null, ATT_GROUP, getGroup());
|
||||
}
|
||||
|
||||
out.endTag(null, TAG_CHANNEL);
|
||||
}
|
||||
@@ -482,6 +523,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
record.put(ATT_VIBRATION, longArrayToString(getVibrationPattern()));
|
||||
record.put(ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
|
||||
record.put(ATT_DELETED, Boolean.toString(isDeleted()));
|
||||
record.put(ATT_GROUP, getGroup());
|
||||
return record;
|
||||
}
|
||||
|
||||
@@ -527,10 +569,12 @@ public final class NotificationChannel implements Parcelable {
|
||||
|
||||
private static String longArrayToString(long[] values) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < values.length - 1; i++) {
|
||||
sb.append(values[i]).append(DELIMITER);
|
||||
if (values != null) {
|
||||
for (int i = 0; i < values.length - 1; i++) {
|
||||
sb.append(values[i]).append(DELIMITER);
|
||||
}
|
||||
sb.append(values[values.length - 1]);
|
||||
}
|
||||
sb.append(values[values.length - 1]);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -558,35 +602,41 @@ public final class NotificationChannel implements Parcelable {
|
||||
|
||||
NotificationChannel that = (NotificationChannel) o;
|
||||
|
||||
if (mImportance != that.mImportance) return false;
|
||||
if (getImportance() != that.getImportance()) return false;
|
||||
if (mBypassDnd != that.mBypassDnd) return false;
|
||||
if (mLockscreenVisibility != that.mLockscreenVisibility) return false;
|
||||
if (getLockscreenVisibility() != that.getLockscreenVisibility()) return false;
|
||||
if (mLights != that.mLights) return false;
|
||||
if (mUserLockedFields != that.mUserLockedFields) return false;
|
||||
if (getUserLockedFields() != that.getUserLockedFields()) return false;
|
||||
if (mVibrationEnabled != that.mVibrationEnabled) return false;
|
||||
if (mShowBadge != that.mShowBadge) return false;
|
||||
if (mDeleted != that.mDeleted) return false;
|
||||
if (mId != null ? !mId.equals(that.mId) : that.mId != null) return false;
|
||||
if (mName != null ? !mName.equals(that.mName) : that.mName != null) return false;
|
||||
if (mSound != null ? !mSound.equals(that.mSound) : that.mSound != null) return false;
|
||||
return Arrays.equals(mVibration, that.mVibration);
|
||||
if (isDeleted() != that.isDeleted()) return false;
|
||||
if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
|
||||
if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) {
|
||||
return false;
|
||||
}
|
||||
if (getSound() != null ? !getSound().equals(that.getSound()) : that.getSound() != null) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(mVibration, that.mVibration)) return false;
|
||||
return getGroup() != null ? getGroup().equals(that.getGroup()) : that.getGroup() == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = mId != null ? mId.hashCode() : 0;
|
||||
result = 31 * result + (mName != null ? mName.hashCode() : 0);
|
||||
result = 31 * result + mImportance;
|
||||
int result = getId() != null ? getId().hashCode() : 0;
|
||||
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
|
||||
result = 31 * result + getImportance();
|
||||
result = 31 * result + (mBypassDnd ? 1 : 0);
|
||||
result = 31 * result + mLockscreenVisibility;
|
||||
result = 31 * result + (mSound != null ? mSound.hashCode() : 0);
|
||||
result = 31 * result + getLockscreenVisibility();
|
||||
result = 31 * result + (getSound() != null ? getSound().hashCode() : 0);
|
||||
result = 31 * result + (mLights ? 1 : 0);
|
||||
result = 31 * result + Arrays.hashCode(mVibration);
|
||||
result = 31 * result + mUserLockedFields;
|
||||
result = 31 * result + getUserLockedFields();
|
||||
result = 31 * result + (mVibrationEnabled ? 1 : 0);
|
||||
result = 31 * result + (mShowBadge ? 1 : 0);
|
||||
result = 31 * result + (mDeleted ? 1 : 0);
|
||||
result = 31 * result + (isDeleted() ? 1 : 0);
|
||||
result = 31 * result + (getGroup() != null ? getGroup().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -605,6 +655,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
", mVibrationEnabled=" + mVibrationEnabled +
|
||||
", mShowBadge=" + mShowBadge +
|
||||
", mDeleted=" + mDeleted +
|
||||
", mGroup='" + mGroup + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
19
core/java/android/app/NotificationChannelGroup.aidl
Normal file
19
core/java/android/app/NotificationChannelGroup.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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 android.app;
|
||||
|
||||
parcelable NotificationChannelGroup;
|
||||
187
core/java/android/app/NotificationChannelGroup.java
Normal file
187
core/java/android/app/NotificationChannelGroup.java
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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 android.app;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A grouping of related notification channels. e.g., channels that all belong to a single account.
|
||||
*/
|
||||
public final class NotificationChannelGroup implements Parcelable {
|
||||
|
||||
private static final String TAG_GROUP = "channelGroup";
|
||||
private static final String ATT_NAME = "name";
|
||||
private static final String ATT_ID = "id";
|
||||
|
||||
private final String mId;
|
||||
private CharSequence mName;
|
||||
private List<NotificationChannel> mChannels = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a notification channel.
|
||||
*
|
||||
* @param id The id of the group. Must be unique per package.
|
||||
* @param name The user visible name of the group.
|
||||
*/
|
||||
public NotificationChannelGroup(String id, CharSequence name) {
|
||||
this.mId = id;
|
||||
this.mName = name;
|
||||
}
|
||||
|
||||
protected NotificationChannelGroup(Parcel in) {
|
||||
if (in.readByte() != 0) {
|
||||
mId = in.readString();
|
||||
} else {
|
||||
mId = null;
|
||||
}
|
||||
mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
in.readList(mChannels, NotificationChannel.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
if (mId != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeString(mId);
|
||||
} else {
|
||||
dest.writeByte((byte) 0);
|
||||
}
|
||||
TextUtils.writeToParcel(mName, dest, flags);
|
||||
dest.writeParcelableList(mChannels, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of this channel.
|
||||
*/
|
||||
public String getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user visible name of this channel.
|
||||
*/
|
||||
public CharSequence getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the list of channels that belong to this group
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public List<NotificationChannel> getChannels() {
|
||||
return mChannels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public void addChannel(NotificationChannel channel) {
|
||||
mChannels.add(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public void writeXml(XmlSerializer out) throws IOException {
|
||||
out.startTag(null, TAG_GROUP);
|
||||
|
||||
out.attribute(null, ATT_ID, getId());
|
||||
out.attribute(null, ATT_NAME, getName().toString());
|
||||
|
||||
out.endTag(null, TAG_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject record = new JSONObject();
|
||||
record.put(ATT_ID, getId());
|
||||
record.put(ATT_NAME, getName());
|
||||
return record;
|
||||
}
|
||||
|
||||
public static final Creator<NotificationChannelGroup> CREATOR =
|
||||
new Creator<NotificationChannelGroup>() {
|
||||
@Override
|
||||
public NotificationChannelGroup createFromParcel(Parcel in) {
|
||||
return new NotificationChannelGroup(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NotificationChannelGroup[] newArray(int size) {
|
||||
return new NotificationChannelGroup[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
NotificationChannelGroup that = (NotificationChannelGroup) o;
|
||||
|
||||
if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
|
||||
if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) {
|
||||
return false;
|
||||
}
|
||||
return getChannels() != null ? getChannels().equals(that.getChannels())
|
||||
: that.getChannels() == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = getId() != null ? getId().hashCode() : 0;
|
||||
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
|
||||
result = 31 * result + (getChannels() != null ? getChannels().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NotificationChannelGroup{" +
|
||||
"mId='" + mId + '\'' +
|
||||
", mName=" + mName +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -382,9 +382,47 @@ public class NotificationManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a group container for {@link NotificationChannel} objects.
|
||||
*
|
||||
* This is a no-op for groups that already exist.
|
||||
* <p>
|
||||
* Group information is only used for presentation, not for behavior. Groups are optional
|
||||
* for channels, and you can have a mix of channels that belong to groups and channels
|
||||
* that do not.
|
||||
* </p>
|
||||
* <p>
|
||||
* For example, if your application supports multiple accounts, and those accounts will
|
||||
* have similar channels, you can create a group for each account with account specific
|
||||
* labels instead of appending account information to each channel's label.
|
||||
* </p>
|
||||
*
|
||||
* @param group The group to create
|
||||
*/
|
||||
public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
|
||||
createNotificationChannelGroups(Arrays.asList(group));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates multiple notification channel groups.
|
||||
*
|
||||
* @param groups The list of groups to create
|
||||
*/
|
||||
public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
service.createNotificationChannelGroups(mContext.getPackageName(),
|
||||
new ParceledListSlice(groups));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a notification channel that notifications can be posted to.
|
||||
*
|
||||
* This is a no-op for channels that already exist.
|
||||
*
|
||||
* @param channel the channel to create. Note that the created channel may differ from this
|
||||
* value. If the channel already exists, it will not be modified.
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@ import android.app.AlarmManager;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.app.backup.BackupManager;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.INotificationManager;
|
||||
@@ -1600,6 +1601,21 @@ public class NotificationManagerService extends SystemService {
|
||||
savePolicyFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNotificationChannelGroups(String pkg,
|
||||
ParceledListSlice channelGroupList) throws RemoteException {
|
||||
checkCallerIsSystemOrSameApp(pkg);
|
||||
List<NotificationChannelGroup> groups = channelGroupList.getList();
|
||||
final int groupSize = groups.size();
|
||||
for (int i = 0; i < groupSize; i++) {
|
||||
final NotificationChannelGroup group = groups.get(i);
|
||||
Preconditions.checkNotNull(group, "group in list is null");
|
||||
mRankingHelper.createNotificationChannelGroup(pkg, Binder.getCallingUid(), group,
|
||||
true /* fromTargetApp */);
|
||||
}
|
||||
savePolicyFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNotificationChannels(String pkg,
|
||||
ParceledListSlice channelsList) throws RemoteException {
|
||||
@@ -1657,6 +1673,13 @@ public class NotificationManagerService extends SystemService {
|
||||
return mRankingHelper.getNotificationChannels(pkg, uid, includeDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
|
||||
String pkg, int uid, boolean includeDeleted) {
|
||||
checkCallerIsSystem();
|
||||
return mRankingHelper.getNotificationChannelGroups(pkg, uid, includeDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg) {
|
||||
checkCallerIsSystemOrSameApp(pkg);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.server.notification;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
|
||||
public interface RankingConfig {
|
||||
@@ -25,6 +26,10 @@ public interface RankingConfig {
|
||||
void setShowBadge(String packageName, int uid, boolean showBadge);
|
||||
boolean canShowBadge(String packageName, int uid);
|
||||
|
||||
void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
|
||||
boolean fromTargetApp);
|
||||
ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
|
||||
int uid, boolean includeDeleted);
|
||||
void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
|
||||
boolean fromTargetApp);
|
||||
void updateNotificationChannel(String pkg, int uid, NotificationChannel channel);
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.android.internal.util.Preconditions;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -59,6 +60,7 @@ public class RankingHelper implements RankingConfig {
|
||||
private static final String TAG_RANKING = "ranking";
|
||||
private static final String TAG_PACKAGE = "package";
|
||||
private static final String TAG_CHANNEL = "channel";
|
||||
private static final String TAG_GROUP = "channelGroup";
|
||||
|
||||
private static final String ATT_VERSION = "version";
|
||||
private static final String ATT_NAME = "name";
|
||||
@@ -174,7 +176,6 @@ public class RankingHelper implements RankingConfig {
|
||||
safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
|
||||
safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
|
||||
|
||||
// Channels
|
||||
final int innerDepth = parser.getDepth();
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG
|
||||
@@ -184,6 +185,17 @@ public class RankingHelper implements RankingConfig {
|
||||
}
|
||||
|
||||
String tagName = parser.getName();
|
||||
// Channel groups
|
||||
if (TAG_GROUP.equals(tagName)) {
|
||||
String id = parser.getAttributeValue(null, ATT_ID);
|
||||
CharSequence groupName = parser.getAttributeValue(null, ATT_NAME);
|
||||
if (!TextUtils.isEmpty(id)) {
|
||||
final NotificationChannelGroup group =
|
||||
new NotificationChannelGroup(id, groupName);
|
||||
r.groups.put(id, group);
|
||||
}
|
||||
}
|
||||
// Channels
|
||||
if (TAG_CHANNEL.equals(tagName)) {
|
||||
String id = parser.getAttributeValue(null, ATT_ID);
|
||||
CharSequence channelName = parser.getAttributeValue(null, ATT_NAME);
|
||||
@@ -302,7 +314,8 @@ public class RankingHelper implements RankingConfig {
|
||||
}
|
||||
final boolean hasNonDefaultSettings = r.importance != DEFAULT_IMPORTANCE
|
||||
|| r.priority != DEFAULT_PRIORITY || r.visibility != DEFAULT_VISIBILITY
|
||||
|| r.showBadge != DEFAULT_SHOW_BADGE || r.channels.size() > 0;
|
||||
|| r.showBadge != DEFAULT_SHOW_BADGE || r.channels.size() > 0
|
||||
|| r.groups.size() > 0;
|
||||
if (hasNonDefaultSettings) {
|
||||
out.startTag(null, TAG_PACKAGE);
|
||||
out.attribute(null, ATT_NAME, r.pkg);
|
||||
@@ -321,6 +334,10 @@ public class RankingHelper implements RankingConfig {
|
||||
out.attribute(null, ATT_UID, Integer.toString(r.uid));
|
||||
}
|
||||
|
||||
for (NotificationChannelGroup group : r.groups.values()) {
|
||||
group.writeXml(out);
|
||||
}
|
||||
|
||||
for (NotificationChannel channel : r.channels.values()) {
|
||||
channel.writeXml(out);
|
||||
}
|
||||
@@ -440,6 +457,21 @@ public class RankingHelper implements RankingConfig {
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
|
||||
boolean fromTargetApp) {
|
||||
Preconditions.checkNotNull(pkg);
|
||||
Preconditions.checkNotNull(group);
|
||||
Preconditions.checkNotNull(group.getId());
|
||||
Preconditions.checkNotNull(group.getName());
|
||||
Record r = getOrCreateRecord(pkg, uid);
|
||||
if (r == null) {
|
||||
throw new IllegalArgumentException("Invalid package");
|
||||
}
|
||||
r.groups.put(group.getId(), group);
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
|
||||
boolean fromTargetApp) {
|
||||
@@ -454,6 +486,10 @@ public class RankingHelper implements RankingConfig {
|
||||
if (IMPORTANCE_NONE == r.importance) {
|
||||
throw new IllegalArgumentException("Package blocked");
|
||||
}
|
||||
if (channel.getGroup() != null && !r.groups.containsKey(channel.getGroup())) {
|
||||
throw new IllegalArgumentException("NotificationChannelGroup doesn't exist");
|
||||
}
|
||||
|
||||
NotificationChannel existing = r.channels.get(channel.getId());
|
||||
// Keep existing settings
|
||||
if (existing != null) {
|
||||
@@ -549,8 +585,9 @@ public class RankingHelper implements RankingConfig {
|
||||
channel.setShowBadge(updatedChannel.canShowBadge());
|
||||
}
|
||||
if (updatedChannel.isDeleted()) {
|
||||
updatedChannel.setDeleted(true);
|
||||
channel.setDeleted(true);
|
||||
}
|
||||
// Assistant cannot change the group
|
||||
|
||||
r.channels.put(channel.getId(), channel);
|
||||
updateConfig();
|
||||
@@ -631,6 +668,36 @@ public class RankingHelper implements RankingConfig {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
|
||||
int uid, boolean includeDeleted) {
|
||||
Preconditions.checkNotNull(pkg);
|
||||
List<NotificationChannelGroup> groups = new ArrayList<>();
|
||||
Record r = getRecord(pkg, uid);
|
||||
if (r == null) {
|
||||
return ParceledListSlice.emptyList();
|
||||
}
|
||||
NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
|
||||
int N = r.channels.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationChannel nc = r.channels.valueAt(i);
|
||||
if (includeDeleted || !nc.isDeleted()) {
|
||||
if (nc.getGroup() != null) {
|
||||
// lazily populate channel list
|
||||
NotificationChannelGroup ncg = r.groups.get(nc.getGroup());
|
||||
ncg.addChannel(nc);
|
||||
} else {
|
||||
nonGrouped.addChannel(nc);
|
||||
}
|
||||
}
|
||||
}
|
||||
groups.addAll(r.groups.values());
|
||||
if (nonGrouped.getChannels().size() > 0) {
|
||||
groups.add(nonGrouped);
|
||||
}
|
||||
return new ParceledListSlice<>(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid,
|
||||
boolean includeDeleted) {
|
||||
@@ -723,6 +790,12 @@ public class RankingHelper implements RankingConfig {
|
||||
pw.print(" ");
|
||||
pw.println(channel);
|
||||
}
|
||||
for (NotificationChannelGroup group : r.groups.values()) {
|
||||
pw.print(prefix);
|
||||
pw.print(" ");
|
||||
pw.print(" ");
|
||||
pw.println(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,6 +831,9 @@ public class RankingHelper implements RankingConfig {
|
||||
for (NotificationChannel channel : r.channels.values()) {
|
||||
record.put("channel", channel.toJson());
|
||||
}
|
||||
for (NotificationChannelGroup group : r.groups.values()) {
|
||||
record.put("group", group.toJson());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// pass
|
||||
}
|
||||
@@ -871,5 +947,6 @@ public class RankingHelper implements RankingConfig {
|
||||
boolean showBadge = DEFAULT_SHOW_BADGE;
|
||||
|
||||
ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
|
||||
ArrayMap<String, NotificationChannelGroup> groups = new ArrayMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,7 @@ import org.junit.runner.RunWith;
|
||||
import com.android.server.lights.Light;
|
||||
import com.android.server.lights.LightsManager;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
// THESE TESTS ARE DISABLED FOR NOW BECAUSE THEY DO NOT FINISH 1/2 THE TIME.
|
||||
public class NotificationManagerServiceTest {
|
||||
private final String pkg = "com.android.server.notification";
|
||||
private final int uid = Binder.getCallingUid();
|
||||
@@ -137,7 +136,6 @@ public class NotificationManagerServiceTest {
|
||||
return new NotificationRecord(mContext, sbn, channel);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCreateNotificationChannels_SingleChannel() throws Exception {
|
||||
final NotificationChannel channel =
|
||||
@@ -149,7 +147,6 @@ public class NotificationManagerServiceTest {
|
||||
assertTrue(createdChannel != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
|
||||
try {
|
||||
@@ -161,7 +158,6 @@ public class NotificationManagerServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCreateNotificationChannels_TwoChannels() throws Exception {
|
||||
final NotificationChannel channel1 =
|
||||
@@ -174,7 +170,6 @@ public class NotificationManagerServiceTest {
|
||||
assertTrue(mBinderService.getNotificationChannel("test_pkg", "id2") != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
|
||||
throws Exception {
|
||||
@@ -193,7 +188,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
|
||||
throws Exception {
|
||||
@@ -208,7 +202,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testBlockedNotifications_suspended() throws Exception {
|
||||
NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
|
||||
@@ -224,7 +217,6 @@ public class NotificationManagerServiceTest {
|
||||
verify(usageStats, times(1)).registerSuspendedByAdmin(eq(r));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testBlockedNotifications_blockedChannel() throws Exception {
|
||||
NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
|
||||
@@ -241,7 +233,6 @@ public class NotificationManagerServiceTest {
|
||||
verify(usageStats, times(1)).registerBlocked(eq(r));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testBlockedNotifications_blockedApp() throws Exception {
|
||||
NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
|
||||
@@ -258,7 +249,6 @@ public class NotificationManagerServiceTest {
|
||||
verify(usageStats, times(1)).registerBlocked(eq(r));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
|
||||
mBinderService.enqueueNotificationWithTag(mContext.getPackageName(), "opPkg", "tag", 0,
|
||||
@@ -269,7 +259,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(1, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
|
||||
mBinderService.enqueueNotificationWithTag(mContext.getPackageName(), "opPkg", "tag", 0,
|
||||
@@ -281,7 +270,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(0, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
@@ -294,7 +282,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(0, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
@@ -307,7 +294,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(0, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
@@ -321,7 +307,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(1, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
@@ -335,7 +320,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(1, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
@@ -348,7 +332,6 @@ public class NotificationManagerServiceTest {
|
||||
assertEquals(0, notifs.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
|
||||
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
|
||||
|
||||
@@ -30,12 +30,12 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.content.Context;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
@@ -186,6 +186,7 @@ public class RankingHelperTest {
|
||||
assertEquals(expected.getSound(), actual.getSound());
|
||||
assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
|
||||
assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
|
||||
assertEquals(expected.getGroup(), actual.getGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,6 +241,7 @@ public class RankingHelperTest {
|
||||
|
||||
@Test
|
||||
public void testChannelXml() throws Exception {
|
||||
NotificationChannelGroup ncg = new NotificationChannelGroup("1", "2");
|
||||
NotificationChannel channel1 =
|
||||
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
NotificationChannel channel2 =
|
||||
@@ -249,8 +251,10 @@ public class RankingHelperTest {
|
||||
channel2.setBypassDnd(true);
|
||||
channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
|
||||
channel2.enableVibration(true);
|
||||
channel2.setGroup(ncg.getId());
|
||||
channel2.setVibrationPattern(new long[] {100, 67, 145, 156});
|
||||
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
|
||||
mHelper.createNotificationChannel(pkg, uid, channel1, true);
|
||||
mHelper.createNotificationChannel(pkg, uid, channel2, false);
|
||||
|
||||
@@ -274,6 +278,10 @@ public class RankingHelperTest {
|
||||
mHelper.getNotificationChannel(pkg, uid, channel2.getId(), false));
|
||||
assertNotNull(mHelper.getNotificationChannel(
|
||||
pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false));
|
||||
assertEquals(ncg.getId(),
|
||||
mHelper.getNotificationChannelGroups(pkg, uid, false).getList().get(0).getId());
|
||||
assertEquals(channel2.getGroup(), mHelper.getNotificationChannelGroups(
|
||||
pkg, uid, false).getList().get(0).getChannels().get(0).getGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -765,10 +773,111 @@ public class RankingHelperTest {
|
||||
assertEquals(2, mHelper.getNotificationChannels(pkg, uid, false).getList().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPackageChanged_packageRemoval_importance() throws Exception {
|
||||
mHelper.setImportance(pkg, uid, NotificationManager.IMPORTANCE_HIGH);
|
||||
|
||||
mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid});
|
||||
|
||||
assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(pkg, uid));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPackageChanged_packageRemoval_groups() throws Exception {
|
||||
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
|
||||
NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg2, true);
|
||||
|
||||
mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid});
|
||||
|
||||
assertEquals(0, mHelper.getNotificationChannelGroups(pkg, uid, true).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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGroup() throws Exception {
|
||||
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
|
||||
assertEquals(ncg, mHelper.getNotificationChannelGroups(pkg, uid, false).getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotCreateChannel_badGroup() throws Exception {
|
||||
NotificationChannel channel1 =
|
||||
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel1.setGroup("garbage");
|
||||
try {
|
||||
mHelper.createNotificationChannel(pkg, uid, channel1, true);
|
||||
fail("Created a channel with a bad group");
|
||||
} catch (IllegalArgumentException e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotCreateChannel_goodGroup() throws Exception {
|
||||
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
|
||||
NotificationChannel channel1 =
|
||||
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel1.setGroup(ncg.getId());
|
||||
mHelper.createNotificationChannel(pkg, uid, channel1, true);
|
||||
|
||||
assertEquals(ncg.getId(),
|
||||
mHelper.getNotificationChannel(pkg, uid, channel1.getId(), false).getGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChannelGroups() throws Exception {
|
||||
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
|
||||
NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
|
||||
mHelper.createNotificationChannelGroup(pkg, uid, ncg2, true);
|
||||
|
||||
NotificationChannel channel1 =
|
||||
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel1.setGroup(ncg.getId());
|
||||
mHelper.createNotificationChannel(pkg, uid, channel1, true);
|
||||
NotificationChannel channel1a =
|
||||
new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel1a.setGroup(ncg.getId());
|
||||
mHelper.createNotificationChannel(pkg, uid, channel1a, true);
|
||||
|
||||
NotificationChannel channel2 =
|
||||
new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel2.setGroup(ncg2.getId());
|
||||
mHelper.createNotificationChannel(pkg, uid, channel2, true);
|
||||
|
||||
NotificationChannel channel3 =
|
||||
new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
|
||||
mHelper.createNotificationChannel(pkg, uid, channel3, true);
|
||||
|
||||
List<NotificationChannelGroup> actual =
|
||||
mHelper.getNotificationChannelGroups(pkg, uid, true).getList();
|
||||
assertEquals(3, actual.size());
|
||||
for (NotificationChannelGroup group: actual) {
|
||||
if (group.getId() == null) {
|
||||
assertEquals(2, group.getChannels().size()); // misc channel too
|
||||
assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
|
||||
|| channel3.getId().equals(group.getChannels().get(1).getId()));
|
||||
} else if (group.getId().equals(ncg.getId())) {
|
||||
assertEquals(2, group.getChannels().size());
|
||||
if (group.getChannels().get(0).getId().equals(channel1.getId())) {
|
||||
assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId()));
|
||||
} else if (group.getChannels().get(0).getId().equals(channel1a.getId())) {
|
||||
assertTrue(group.getChannels().get(1).getId().equals(channel1.getId()));
|
||||
} else {
|
||||
fail("expected channel not found");
|
||||
}
|
||||
} else if (group.getId().equals(ncg2.getId())) {
|
||||
assertEquals(1, group.getChannels().size());
|
||||
assertEquals(channel2.getId(), group.getChannels().get(0).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user