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 static org.junit.Assert.assertNotNull;
20 
21 import android.app.NotificationChannel;
22 import android.os.UserHandle;
23 import android.service.notification.NotificationListenerService.Ranking;
24 import android.service.notification.NotificationListenerService.RankingMap;
25 import android.service.notification.StatusBarNotification;
26 import android.util.ArrayMap;
27 
28 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Map;
33 
34 /**
35  * Simulates a NotificationManager
36  *
37  * You can post and retract notifications, each with an accompanying Ranking. The simulator will
38  * keep its RankingMap up to date and call appropriate event listeners.
39  */
40 public class NoManSimulator {
41     private final List<NotificationHandler> mListeners = new ArrayList<>();
42     private final Map<String, Ranking> mRankings = new ArrayMap<>();
43 
NoManSimulator()44     public NoManSimulator() {
45     }
46 
addListener(NotificationHandler listener)47     public void addListener(NotificationHandler listener) {
48         mListeners.add(listener);
49     }
50 
postNotif(NotificationEntryBuilder builder)51     public NotifEvent postNotif(NotificationEntryBuilder builder) {
52         final NotificationEntry entry = builder.build();
53         mRankings.put(entry.getKey(), entry.getRanking());
54         final RankingMap rankingMap = buildRankingMap();
55         for (NotificationHandler listener : mListeners) {
56             listener.onNotificationPosted(entry.getSbn(), rankingMap);
57         }
58         return new NotifEvent(entry.getSbn(), entry.getRanking(), rankingMap);
59     }
60 
retractNotif(StatusBarNotification sbn, int reason)61     public NotifEvent retractNotif(StatusBarNotification sbn, int reason) {
62         assertNotNull(mRankings.remove(sbn.getKey()));
63         final RankingMap rankingMap = buildRankingMap();
64         for (NotificationHandler listener : mListeners) {
65             listener.onNotificationRemoved(sbn, rankingMap, reason);
66         }
67         return new NotifEvent(sbn, null, rankingMap);
68     }
69 
issueRankingUpdate()70     public void issueRankingUpdate() {
71         final RankingMap rankingMap = buildRankingMap();
72         for (NotificationHandler listener : mListeners) {
73             listener.onNotificationRankingUpdate(rankingMap);
74         }
75     }
76 
issueChannelModification( String pkg, UserHandle user, NotificationChannel channel, int modificationType)77     public void issueChannelModification(
78             String pkg, UserHandle user, NotificationChannel channel, int modificationType) {
79         for (NotificationHandler listener : mListeners) {
80             listener.onNotificationChannelModified(pkg, user, channel, modificationType);
81         }
82     }
83 
setRanking(String key, Ranking ranking)84     public void setRanking(String key, Ranking ranking) {
85         mRankings.put(key, ranking);
86     }
87 
88     /** This is for testing error cases: b/216384850 */
removeRankingWithoutEvent(String key)89     public Ranking removeRankingWithoutEvent(String key) {
90         return mRankings.remove(key);
91     }
92 
buildRankingMap()93     private RankingMap buildRankingMap() {
94         return new RankingMap(mRankings.values().toArray(new Ranking[0]));
95     }
96 
97     public static class NotifEvent {
98         public final String key;
99         public final StatusBarNotification sbn;
100         public final Ranking ranking;
101         public final RankingMap rankingMap;
102 
NotifEvent( StatusBarNotification sbn, Ranking ranking, RankingMap rankingMap)103         private NotifEvent(
104                 StatusBarNotification sbn,
105                 Ranking ranking,
106                 RankingMap rankingMap) {
107             this.key = sbn.getKey();
108             this.sbn = sbn;
109             this.ranking = ranking;
110             this.rankingMap = rankingMap;
111         }
112     }
113 }
114