1 /*
2  * Copyright (C) 2013 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 package com.android.cts.verifier.notifications;
17 
18 import android.app.Notification;
19 import android.content.ComponentName;
20 import android.service.notification.NotificationListenerService;
21 import android.service.notification.NotificationStats;
22 import android.service.notification.StatusBarNotification;
23 import android.util.ArrayMap;
24 import android.util.Log;
25 
26 import org.json.JSONException;
27 import org.json.JSONObject;
28 
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.HashSet;
32 import java.util.Set;
33 
34 public class MockListener extends NotificationListenerService {
35     static final String TAG = "MockListener";
36 
37     public static final ComponentName COMPONENT_NAME =
38             new ComponentName("com.android.cts.verifier", MockListener.class.getName());
39 
40 
41     public static final String JSON_FLAGS = "flag";
42     public static final String JSON_ICON = "icon";
43     public static final String JSON_ID = "id";
44     public static final String JSON_PACKAGE = "pkg";
45     public static final String JSON_WHEN = "when";
46     public static final String JSON_TAG = "tag";
47     public static final String JSON_RANK = "rank";
48     public static final String JSON_AMBIENT = "ambient";
49     public static final String JSON_MATCHES_ZEN_FILTER = "matches_zen_filter";
50     public static final String JSON_REASON = "reason";
51     public static final String JSON_STATS = "stats";
52     public static final String JSON_LAST_AUDIBLY_ALERTED = "last_audibly_alerted";
53 
54     ArrayList<String> mPosted = new ArrayList<String>();
55     ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
56     ArrayMap<String, String> mNotificationKeys = new ArrayMap<>();
57     ArrayList<String> mRemoved = new ArrayList<String>();
58     ArrayMap<String, JSONObject> mRemovedReason = new ArrayMap<>();
59     ArrayList<String> mSnoozed = new ArrayList<>();
60     ArrayList<String> mOrder = new ArrayList<>();
61     Set<String> mTestPackages = new HashSet<>();
62     int mDND = -1;
63     ArrayList<Notification> mPostedNotifications = new ArrayList<Notification>();
64     private static MockListener sNotificationListenerInstance = null;
65     boolean isConnected;
66 
67     @Override
onCreate()68     public void onCreate() {
69         super.onCreate();
70         Log.d(TAG, "created");
71 
72         mTestPackages.add("com.android.cts.verifier");
73         mTestPackages.add("com.android.cts.robot");
74     }
75 
getPosted()76     protected Collection<JSONObject> getPosted() {
77         return mNotifications.values();
78     }
79 
getKeyForTag(String tag)80     protected String getKeyForTag(String tag) {
81         return mNotificationKeys.get(tag);
82     }
83 
84     @Override
onDestroy()85     public void onDestroy() {
86         super.onDestroy();
87         Log.d(TAG, "destroyed");
88     }
89 
90     @Override
onListenerConnected()91     public void onListenerConnected() {
92         super.onListenerConnected();
93         mDND = getCurrentInterruptionFilter();
94         Log.d(TAG, "initial value of CurrentInterruptionFilter is " + mDND);
95         sNotificationListenerInstance = this;
96         isConnected = true;
97     }
98 
99     @Override
onListenerDisconnected()100     public void onListenerDisconnected() {
101         isConnected = false;
102     }
103 
104     @Override
onInterruptionFilterChanged(int interruptionFilter)105     public void onInterruptionFilterChanged(int interruptionFilter) {
106         super.onInterruptionFilterChanged(interruptionFilter);
107         mDND = interruptionFilter;
108         Log.d(TAG, "value of CurrentInterruptionFilter changed to " + mDND);
109     }
110 
getInstance()111     public static MockListener getInstance() {
112         return sNotificationListenerInstance;
113     }
114 
resetData()115     public void resetData() {
116         mPosted.clear();
117         mNotifications.clear();
118         mRemoved.clear();
119         mOrder.clear();
120         mRemovedReason.clear();
121         mSnoozed.clear();
122         mPostedNotifications.clear();
123     }
124 
125     @Override
onNotificationRankingUpdate(RankingMap rankingMap)126     public void onNotificationRankingUpdate(RankingMap rankingMap) {
127         String[] orderedKeys = rankingMap.getOrderedKeys();
128         mOrder.clear();
129         Ranking rank = new Ranking();
130         for( int i = 0; i < orderedKeys.length; i++) {
131             String key = orderedKeys[i];
132             mOrder.add(key);
133             rankingMap.getRanking(key, rank);
134             JSONObject note = mNotifications.get(key);
135             if (note != null) {
136                 try {
137                     note.put(JSON_RANK, rank.getRank());
138                     note.put(JSON_AMBIENT, rank.isAmbient());
139                     note.put(JSON_MATCHES_ZEN_FILTER, rank.matchesInterruptionFilter());
140                     note.put(JSON_LAST_AUDIBLY_ALERTED, rank.getLastAudiblyAlertedMillis());
141                 } catch (JSONException e) {
142                     Log.e(TAG, "failed to pack up notification payload", e);
143                 }
144             }
145         }
146     }
147 
148     @Override
onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap)149     public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
150         if (!mTestPackages.contains(sbn.getPackageName())) { return; }
151         Log.d(TAG, "posted: " + sbn.getTag());
152         mPosted.add(sbn.getTag());
153         mPostedNotifications.add(sbn.getNotification());
154         JSONObject notification = new JSONObject();
155         try {
156             notification.put(JSON_TAG, sbn.getTag());
157             notification.put(JSON_ID, sbn.getId());
158             notification.put(JSON_PACKAGE, sbn.getPackageName());
159             notification.put(JSON_WHEN, sbn.getNotification().when);
160             notification.put(JSON_ICON, sbn.getNotification().icon);
161             notification.put(JSON_FLAGS, sbn.getNotification().flags);
162             mNotifications.put(sbn.getKey(), notification);
163             mNotificationKeys.put(sbn.getTag(), sbn.getKey());
164         } catch (JSONException e) {
165             Log.e(TAG, "failed to pack up notification payload", e);
166         }
167         onNotificationRankingUpdate(rankingMap);
168     }
169 
170     @Override
onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap)171     public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
172         Log.d(TAG, "removed: " + sbn.getTag());
173         mRemoved.add(sbn.getTag());
174         mNotifications.remove(sbn.getKey());
175         mNotificationKeys.remove(sbn.getTag());
176         onNotificationRankingUpdate(rankingMap);
177     }
178 
179     @Override
onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, NotificationStats stats, int reason)180     public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
181             NotificationStats stats, int reason) {
182         Log.d(TAG, "removed: " + sbn.getTag() + " for reason " + reason);
183         mRemoved.add(sbn.getTag());
184         JSONObject removed = new JSONObject();
185         try {
186             removed.put(JSON_TAG, sbn.getTag());
187             removed.put(JSON_REASON, reason);
188             removed.put(JSON_STATS, stats != null);
189         } catch (JSONException e) {
190             Log.e(TAG, "failed to pack up notification payload", e);
191         }
192         mNotifications.remove(sbn.getKey());
193         mNotificationKeys.remove(sbn.getTag());
194         mRemovedReason.put(sbn.getTag(), removed);
195         onNotificationRankingUpdate(rankingMap);
196     }
197 }
198