1 /* 2 * Copyright (C) 2019 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 */ 16 17 package com.android.systemui.statusbar.notification.collection; 18 19 import android.annotation.Nullable; 20 import android.app.Notification; 21 import android.app.NotificationChannel; 22 import android.app.NotificationManager; 23 import android.content.Context; 24 import android.content.pm.ShortcutInfo; 25 import android.os.UserHandle; 26 import android.service.notification.NotificationListenerService.Ranking; 27 import android.service.notification.SnoozeCriterion; 28 import android.service.notification.StatusBarNotification; 29 30 import com.android.internal.logging.InstanceId; 31 import com.android.systemui.statusbar.RankingBuilder; 32 import com.android.systemui.statusbar.SbnBuilder; 33 import com.android.systemui.util.time.FakeSystemClock; 34 35 import java.util.ArrayList; 36 37 import kotlin.Unit; 38 39 /** 40 * Combined builder for constructing a NotificationEntry and its associated StatusBarNotification 41 * and Ranking. Is largely a proxy for the SBN and Ranking builders, but does a little extra magic 42 * to make sure the keys match between the two, etc. 43 * 44 * Has the ability to set ListEntry properties as well. 45 * 46 * Only for use in tests. 47 */ 48 public class NotificationEntryBuilder { 49 private final SbnBuilder mSbnBuilder; 50 private final RankingBuilder mRankingBuilder; 51 private final FakeSystemClock mClock = new FakeSystemClock(); 52 private StatusBarNotification mSbn = null; 53 54 /* ListEntry properties */ 55 private GroupEntry mParent; 56 57 /* If set, use this creation time instead of mClock.uptimeMillis */ 58 private long mCreationTime = -1; 59 NotificationEntryBuilder()60 public NotificationEntryBuilder() { 61 mSbnBuilder = new SbnBuilder(); 62 mRankingBuilder = new RankingBuilder(); 63 } 64 NotificationEntryBuilder(NotificationEntry source)65 public NotificationEntryBuilder(NotificationEntry source) { 66 mSbnBuilder = new SbnBuilder(source.getSbn()); 67 mRankingBuilder = new RankingBuilder(source.getRanking()); 68 69 mParent = source.getParent(); 70 mCreationTime = source.getCreationTime(); 71 } 72 73 /** Build a new instance of NotificationEntry */ build()74 public NotificationEntry build() { 75 return buildOrApply(null); 76 } 77 78 /** Modifies [target] to match the contents of this builder */ apply(NotificationEntry target)79 public void apply(NotificationEntry target) { 80 buildOrApply(target); 81 } 82 83 /** Convenience method for Kotlin callbacks that are passed a builder and need to return Unit */ done()84 public Unit done() { 85 return Unit.INSTANCE; 86 } 87 buildOrApply(NotificationEntry target)88 private NotificationEntry buildOrApply(NotificationEntry target) { 89 final StatusBarNotification sbn = mSbn != null ? mSbn : mSbnBuilder.build(); 90 final Ranking ranking = mRankingBuilder.setKey(sbn.getKey()).build(); 91 final long creationTime = mCreationTime != -1 ? mCreationTime : mClock.uptimeMillis(); 92 93 final NotificationEntry entry; 94 if (target == null) { 95 entry = new NotificationEntry(sbn, ranking, creationTime); 96 } else { 97 entry = target; 98 entry.setSbn(sbn); 99 entry.setRanking(ranking); 100 // Note: we can't modify the creation time as it's immutable 101 } 102 103 /* ListEntry properties */ 104 entry.setParent(mParent); 105 return entry; 106 } 107 108 /** 109 * Sets the parent. 110 */ setParent(@ullable GroupEntry parent)111 public NotificationEntryBuilder setParent(@Nullable GroupEntry parent) { 112 mParent = parent; 113 return this; 114 } 115 116 /** 117 * Sets the SBN directly. If set, causes all calls to delegated SbnBuilder methods to be 118 * ignored. 119 */ setSbn(@ullable StatusBarNotification sbn)120 public NotificationEntryBuilder setSbn(@Nullable StatusBarNotification sbn) { 121 mSbn = sbn; 122 return this; 123 } 124 125 /** 126 * Set the creation time 127 */ setCreationTime(long creationTime)128 public NotificationEntryBuilder setCreationTime(long creationTime) { 129 mCreationTime = creationTime; 130 return this; 131 } 132 133 /* Delegated to SbnBuilder */ 134 setPkg(String pkg)135 public NotificationEntryBuilder setPkg(String pkg) { 136 mSbnBuilder.setPkg(pkg); 137 return this; 138 } 139 setOpPkg(String opPkg)140 public NotificationEntryBuilder setOpPkg(String opPkg) { 141 mSbnBuilder.setOpPkg(opPkg); 142 return this; 143 } 144 setId(int id)145 public NotificationEntryBuilder setId(int id) { 146 mSbnBuilder.setId(id); 147 return this; 148 } 149 setTag(String tag)150 public NotificationEntryBuilder setTag(String tag) { 151 mSbnBuilder.setTag(tag); 152 return this; 153 } 154 setUid(int uid)155 public NotificationEntryBuilder setUid(int uid) { 156 mSbnBuilder.setUid(uid); 157 return this; 158 } 159 setInitialPid(int initialPid)160 public NotificationEntryBuilder setInitialPid(int initialPid) { 161 mSbnBuilder.setInitialPid(initialPid); 162 return this; 163 } 164 setNotification(Notification notification)165 public NotificationEntryBuilder setNotification(Notification notification) { 166 mSbnBuilder.setNotification(notification); 167 return this; 168 } 169 modifyNotification(Context context)170 public Notification.Builder modifyNotification(Context context) { 171 return mSbnBuilder.modifyNotification(context); 172 } 173 setUser(UserHandle user)174 public NotificationEntryBuilder setUser(UserHandle user) { 175 mSbnBuilder.setUser(user); 176 return this; 177 } 178 setOverrideGroupKey(String overrideGroupKey)179 public NotificationEntryBuilder setOverrideGroupKey(String overrideGroupKey) { 180 mSbnBuilder.setOverrideGroupKey(overrideGroupKey); 181 return this; 182 } 183 setPostTime(long postTime)184 public NotificationEntryBuilder setPostTime(long postTime) { 185 mSbnBuilder.setPostTime(postTime); 186 return this; 187 } 188 setInstanceId(InstanceId instanceId)189 public NotificationEntryBuilder setInstanceId(InstanceId instanceId) { 190 mSbnBuilder.setInstanceId(instanceId); 191 return this; 192 } 193 194 /* Delegated to Notification.Builder (via SbnBuilder) */ 195 setContentTitle(Context context, String contentTitle)196 public NotificationEntryBuilder setContentTitle(Context context, String contentTitle) { 197 mSbnBuilder.setContentTitle(context, contentTitle); 198 return this; 199 } 200 setContentText(Context context, String contentText)201 public NotificationEntryBuilder setContentText(Context context, String contentText) { 202 mSbnBuilder.setContentText(context, contentText); 203 return this; 204 } 205 setGroup(Context context, String groupKey)206 public NotificationEntryBuilder setGroup(Context context, String groupKey) { 207 mSbnBuilder.setGroup(context, groupKey); 208 return this; 209 } 210 setGroupSummary(Context context, boolean isGroupSummary)211 public NotificationEntryBuilder setGroupSummary(Context context, boolean isGroupSummary) { 212 mSbnBuilder.setGroupSummary(context, isGroupSummary); 213 return this; 214 } 215 setFlag(Context context, int mask, boolean value)216 public NotificationEntryBuilder setFlag(Context context, int mask, boolean value) { 217 mSbnBuilder.setFlag(context, mask, value); 218 return this; 219 } 220 221 /* Delegated to RankingBuilder */ 222 setRank(int rank)223 public NotificationEntryBuilder setRank(int rank) { 224 mRankingBuilder.setRank(rank); 225 return this; 226 } 227 setMatchesInterruptionFilter( boolean matchesInterruptionFilter)228 public NotificationEntryBuilder setMatchesInterruptionFilter( 229 boolean matchesInterruptionFilter) { 230 mRankingBuilder.setMatchesInterruptionFilter(matchesInterruptionFilter); 231 return this; 232 } 233 setVisibilityOverride(int visibilityOverride)234 public NotificationEntryBuilder setVisibilityOverride(int visibilityOverride) { 235 mRankingBuilder.setVisibilityOverride(visibilityOverride); 236 return this; 237 } 238 setSuppressedVisualEffects(int suppressedVisualEffects)239 public NotificationEntryBuilder setSuppressedVisualEffects(int suppressedVisualEffects) { 240 mRankingBuilder.setSuppressedVisualEffects(suppressedVisualEffects); 241 return this; 242 } 243 setExplanation(CharSequence explanation)244 public NotificationEntryBuilder setExplanation(CharSequence explanation) { 245 mRankingBuilder.setExplanation(explanation); 246 return this; 247 } 248 setAdditionalPeople(ArrayList<String> additionalPeople)249 public NotificationEntryBuilder setAdditionalPeople(ArrayList<String> additionalPeople) { 250 mRankingBuilder.setAdditionalPeople(additionalPeople); 251 return this; 252 } 253 setSnoozeCriteria( ArrayList<SnoozeCriterion> snoozeCriteria)254 public NotificationEntryBuilder setSnoozeCriteria( 255 ArrayList<SnoozeCriterion> snoozeCriteria) { 256 mRankingBuilder.setSnoozeCriteria(snoozeCriteria); 257 return this; 258 } 259 setCanShowBadge(boolean canShowBadge)260 public NotificationEntryBuilder setCanShowBadge(boolean canShowBadge) { 261 mRankingBuilder.setCanShowBadge(canShowBadge); 262 return this; 263 } 264 setSuspended(boolean suspended)265 public NotificationEntryBuilder setSuspended(boolean suspended) { 266 mRankingBuilder.setSuspended(suspended); 267 return this; 268 } 269 setLastAudiblyAlertedMs(long lastAudiblyAlertedMs)270 public NotificationEntryBuilder setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { 271 mRankingBuilder.setLastAudiblyAlertedMs(lastAudiblyAlertedMs); 272 return this; 273 } 274 setNoisy(boolean noisy)275 public NotificationEntryBuilder setNoisy(boolean noisy) { 276 mRankingBuilder.setNoisy(noisy); 277 return this; 278 } 279 setCanBubble(boolean canBubble)280 public NotificationEntryBuilder setCanBubble(boolean canBubble) { 281 mRankingBuilder.setCanBubble(canBubble); 282 return this; 283 } 284 setImportance(@otificationManager.Importance int importance)285 public NotificationEntryBuilder setImportance(@NotificationManager.Importance int importance) { 286 mRankingBuilder.setImportance(importance); 287 return this; 288 } 289 setUserSentiment(int userSentiment)290 public NotificationEntryBuilder setUserSentiment(int userSentiment) { 291 mRankingBuilder.setUserSentiment(userSentiment); 292 return this; 293 } 294 setChannel(NotificationChannel channel)295 public NotificationEntryBuilder setChannel(NotificationChannel channel) { 296 mRankingBuilder.setChannel(channel); 297 return this; 298 } 299 setSmartActions( ArrayList<Notification.Action> smartActions)300 public NotificationEntryBuilder setSmartActions( 301 ArrayList<Notification.Action> smartActions) { 302 mRankingBuilder.setSmartActions(smartActions); 303 return this; 304 } 305 setSmartActions(Notification.Action... smartActions)306 public NotificationEntryBuilder setSmartActions(Notification.Action... smartActions) { 307 mRankingBuilder.setSmartActions(smartActions); 308 return this; 309 } 310 setSmartReplies(ArrayList<CharSequence> smartReplies)311 public NotificationEntryBuilder setSmartReplies(ArrayList<CharSequence> smartReplies) { 312 mRankingBuilder.setSmartReplies(smartReplies); 313 return this; 314 } 315 setSmartReplies(CharSequence... smartReplies)316 public NotificationEntryBuilder setSmartReplies(CharSequence... smartReplies) { 317 mRankingBuilder.setSmartReplies(smartReplies); 318 return this; 319 } 320 setShortcutInfo(ShortcutInfo shortcutInfo)321 public NotificationEntryBuilder setShortcutInfo(ShortcutInfo shortcutInfo) { 322 mRankingBuilder.setShortcutInfo(shortcutInfo); 323 return this; 324 } 325 setRankingAdjustment(int rankingAdjustment)326 public NotificationEntryBuilder setRankingAdjustment(int rankingAdjustment) { 327 mRankingBuilder.setRankingAdjustment(rankingAdjustment); 328 return this; 329 } 330 } 331