1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.app; 17 18import android.annotation.StringRes; 19import android.annotation.SystemApi; 20import android.content.Intent; 21import android.net.Uri; 22import android.os.Parcel; 23import android.os.Parcelable; 24import android.service.notification.NotificationListenerService; 25import android.text.TextUtils; 26import android.util.Slog; 27 28import org.json.JSONException; 29import org.json.JSONObject; 30import org.xmlpull.v1.XmlPullParser; 31import org.xmlpull.v1.XmlSerializer; 32 33import java.io.IOException; 34import java.util.ArrayList; 35import java.util.Arrays; 36import java.util.List; 37 38/** 39 * A grouping of related notification channels. e.g., channels that all belong to a single account. 40 */ 41public final class NotificationChannelGroup implements Parcelable { 42 43 /** 44 * The maximum length for text fields in a NotificationChannelGroup. Fields will be truncated at 45 * this limit. 46 */ 47 private static final int MAX_TEXT_LENGTH = 1000; 48 49 private static final String TAG_GROUP = "channelGroup"; 50 private static final String ATT_NAME = "name"; 51 private static final String ATT_ID = "id"; 52 53 private final String mId; 54 private CharSequence mName; 55 private List<NotificationChannel> mChannels = new ArrayList<>(); 56 57 /** 58 * Creates a notification channel group. 59 * 60 * @param id The id of the group. Must be unique per package. the value may be truncated if 61 * it is too long. 62 * @param name The user visible name of the group. You can rename this group when the system 63 * locale changes by listening for the {@link Intent#ACTION_LOCALE_CHANGED} 64 * broadcast. <p>The recommended maximum length is 40 characters; the value may be 65 * truncated if it is too long. 66 */ 67 public NotificationChannelGroup(String id, CharSequence name) { 68 this.mId = getTrimmedString(id); 69 this.mName = name != null ? getTrimmedString(name.toString()) : null; 70 } 71 72 /** 73 * @hide 74 */ 75 protected NotificationChannelGroup(Parcel in) { 76 if (in.readByte() != 0) { 77 mId = in.readString(); 78 } else { 79 mId = null; 80 } 81 mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 82 in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader()); 83 } 84 85 private String getTrimmedString(String input) { 86 if (input != null && input.length() > MAX_TEXT_LENGTH) { 87 return input.substring(0, MAX_TEXT_LENGTH); 88 } 89 return input; 90 } 91 92 @Override 93 public void writeToParcel(Parcel dest, int flags) { 94 if (mId != null) { 95 dest.writeByte((byte) 1); 96 dest.writeString(mId); 97 } else { 98 dest.writeByte((byte) 0); 99 } 100 TextUtils.writeToParcel(mName, dest, flags); 101 dest.writeParcelableList(mChannels, flags); 102 } 103 104 /** 105 * Returns the id of this channel. 106 */ 107 public String getId() { 108 return mId; 109 } 110 111 /** 112 * Returns the user visible name of this channel. 113 */ 114 public CharSequence getName() { 115 return mName; 116 } 117 118 /* 119 * Returns the list of channels that belong to this group 120 * 121 * @hide 122 */ 123 public List<NotificationChannel> getChannels() { 124 return mChannels; 125 } 126 127 /** 128 * @hide 129 */ 130 public void addChannel(NotificationChannel channel) { 131 mChannels.add(channel); 132 } 133 134 /** 135 * @hide 136 */ 137 public void writeXml(XmlSerializer out) throws IOException { 138 out.startTag(null, TAG_GROUP); 139 140 out.attribute(null, ATT_ID, getId()); 141 if (getName() != null) { 142 out.attribute(null, ATT_NAME, getName().toString()); 143 } 144 145 out.endTag(null, TAG_GROUP); 146 } 147 148 /** 149 * @hide 150 */ 151 @SystemApi 152 public JSONObject toJson() throws JSONException { 153 JSONObject record = new JSONObject(); 154 record.put(ATT_ID, getId()); 155 record.put(ATT_NAME, getName()); 156 return record; 157 } 158 159 public static final Creator<NotificationChannelGroup> CREATOR = 160 new Creator<NotificationChannelGroup>() { 161 @Override 162 public NotificationChannelGroup createFromParcel(Parcel in) { 163 return new NotificationChannelGroup(in); 164 } 165 166 @Override 167 public NotificationChannelGroup[] newArray(int size) { 168 return new NotificationChannelGroup[size]; 169 } 170 }; 171 172 @Override 173 public int describeContents() { 174 return 0; 175 } 176 177 @Override 178 public boolean equals(Object o) { 179 if (this == o) return true; 180 if (o == null || getClass() != o.getClass()) return false; 181 182 NotificationChannelGroup that = (NotificationChannelGroup) o; 183 184 if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false; 185 if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) { 186 return false; 187 } 188 return true; 189 } 190 191 @Override 192 public NotificationChannelGroup clone() { 193 return new NotificationChannelGroup(getId(), getName()); 194 } 195 196 @Override 197 public int hashCode() { 198 int result = getId() != null ? getId().hashCode() : 0; 199 result = 31 * result + (getName() != null ? getName().hashCode() : 0); 200 return result; 201 } 202 203 @Override 204 public String toString() { 205 return "NotificationChannelGroup{" + 206 "mId='" + mId + '\'' + 207 ", mName=" + mName + 208 ", mChannels=" + mChannels + 209 '}'; 210 } 211} 212