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<StatusBarNotification> mPosted = new ArrayList<>(); 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 getPosted(String tag)80 protected StatusBarNotification getPosted(String tag) { 81 for (StatusBarNotification sbn : mPosted) { 82 if (sbn.getTag().equals(tag)) { 83 return sbn; 84 } 85 } 86 return null; 87 } 88 getKeyForTag(String tag)89 protected String getKeyForTag(String tag) { 90 return mNotificationKeys.get(tag); 91 } 92 93 @Override onDestroy()94 public void onDestroy() { 95 super.onDestroy(); 96 Log.d(TAG, "destroyed"); 97 } 98 99 @Override onListenerConnected()100 public void onListenerConnected() { 101 super.onListenerConnected(); 102 mDND = getCurrentInterruptionFilter(); 103 Log.d(TAG, "initial value of CurrentInterruptionFilter is " + mDND); 104 sNotificationListenerInstance = this; 105 isConnected = true; 106 } 107 108 @Override onListenerDisconnected()109 public void onListenerDisconnected() { 110 isConnected = false; 111 } 112 113 @Override onInterruptionFilterChanged(int interruptionFilter)114 public void onInterruptionFilterChanged(int interruptionFilter) { 115 super.onInterruptionFilterChanged(interruptionFilter); 116 mDND = interruptionFilter; 117 Log.d(TAG, "value of CurrentInterruptionFilter changed to " + mDND); 118 } 119 getInstance()120 public static MockListener getInstance() { 121 return sNotificationListenerInstance; 122 } 123 resetData()124 public void resetData() { 125 mPosted.clear(); 126 mNotifications.clear(); 127 mRemoved.clear(); 128 mOrder.clear(); 129 mRemovedReason.clear(); 130 mSnoozed.clear(); 131 mPostedNotifications.clear(); 132 } 133 134 @Override onNotificationRankingUpdate(RankingMap rankingMap)135 public void onNotificationRankingUpdate(RankingMap rankingMap) { 136 String[] orderedKeys = rankingMap.getOrderedKeys(); 137 mOrder.clear(); 138 Ranking rank = new Ranking(); 139 for( int i = 0; i < orderedKeys.length; i++) { 140 String key = orderedKeys[i]; 141 mOrder.add(key); 142 rankingMap.getRanking(key, rank); 143 JSONObject note = mNotifications.get(key); 144 if (note != null) { 145 try { 146 note.put(JSON_RANK, rank.getRank()); 147 note.put(JSON_AMBIENT, rank.isAmbient()); 148 note.put(JSON_MATCHES_ZEN_FILTER, rank.matchesInterruptionFilter()); 149 note.put(JSON_LAST_AUDIBLY_ALERTED, rank.getLastAudiblyAlertedMillis()); 150 } catch (JSONException e) { 151 Log.e(TAG, "failed to pack up notification payload", e); 152 } 153 } 154 } 155 } 156 157 @Override onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap)158 public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) { 159 if (!mTestPackages.contains(sbn.getPackageName())) { return; } 160 Log.d(TAG, "posted: " + sbn.getTag()); 161 mPosted.add(sbn); 162 mPostedNotifications.add(sbn.getNotification()); 163 JSONObject notification = new JSONObject(); 164 try { 165 notification.put(JSON_TAG, sbn.getTag()); 166 notification.put(JSON_ID, sbn.getId()); 167 notification.put(JSON_PACKAGE, sbn.getPackageName()); 168 notification.put(JSON_WHEN, sbn.getNotification().when); 169 notification.put(JSON_ICON, sbn.getNotification().icon); 170 notification.put(JSON_FLAGS, sbn.getNotification().flags); 171 mNotifications.put(sbn.getKey(), notification); 172 mNotificationKeys.put(sbn.getTag(), sbn.getKey()); 173 } catch (JSONException e) { 174 Log.e(TAG, "failed to pack up notification payload", e); 175 } 176 onNotificationRankingUpdate(rankingMap); 177 } 178 179 @Override onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap)180 public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) { 181 Log.d(TAG, "removed: " + sbn.getTag()); 182 mRemoved.add(sbn.getTag()); 183 mNotifications.remove(sbn.getKey()); 184 mNotificationKeys.remove(sbn.getTag()); 185 onNotificationRankingUpdate(rankingMap); 186 } 187 188 @Override onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, NotificationStats stats, int reason)189 public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, 190 NotificationStats stats, int reason) { 191 Log.d(TAG, "removed: " + sbn.getTag() + " for reason " + reason); 192 mRemoved.add(sbn.getTag()); 193 JSONObject removed = new JSONObject(); 194 try { 195 removed.put(JSON_TAG, sbn.getTag()); 196 removed.put(JSON_REASON, reason); 197 removed.put(JSON_STATS, stats != null); 198 } catch (JSONException e) { 199 Log.e(TAG, "failed to pack up notification payload", e); 200 } 201 mNotifications.remove(sbn.getKey()); 202 mNotificationKeys.remove(sbn.getTag()); 203 mRemovedReason.put(sbn.getTag(), removed); 204 onNotificationRankingUpdate(rankingMap); 205 } 206 } 207