• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Activity;
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.Bundle;
24 import android.service.notification.NotificationListenerService;
25 import android.service.notification.StatusBarNotification;
26 import android.util.ArrayMap;
27 import android.util.Log;
28 
29 import org.json.JSONException;
30 import org.json.JSONObject;
31 
32 import java.lang.reflect.InvocationTargetException;
33 import java.util.ArrayList;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Set;
37 
38 public class MockListener extends NotificationListenerService {
39     static final String TAG = "MockListener";
40 
41     static final String SERVICE_BASE = "android.service.notification.cts.";
42     static final String SERVICE_CHECK = SERVICE_BASE + "SERVICE_CHECK";
43     static final String SERVICE_POSTED = SERVICE_BASE + "SERVICE_POSTED";
44     static final String SERVICE_PAYLOADS = SERVICE_BASE + "SERVICE_PAYLOADS";
45     static final String SERVICE_REMOVED = SERVICE_BASE + "SERVICE_REMOVED";
46     static final String SERVICE_RESET = SERVICE_BASE + "SERVICE_RESET";
47     static final String SERVICE_CLEAR_ONE = SERVICE_BASE + "SERVICE_CLEAR_ONE";
48     static final String SERVICE_CLEAR_ALL = SERVICE_BASE + "SERVICE_CLEAR_ALL";
49     public static final String SERVICE_ORDER = SERVICE_BASE + "SERVICE_ORDER";
50     public static final String SERVICE_DND = SERVICE_BASE + "SERVICE_DND";
51 
52     static final String EXTRA_PAYLOAD = "PAYLOAD";
53     static final String EXTRA_INT = "INT";
54     static final String EXTRA_TAG = "TAG";
55     static final String EXTRA_CODE = "CODE";
56 
57     static final int RESULT_TIMEOUT = Activity.RESULT_FIRST_USER;
58     static final int RESULT_NO_SERVER = Activity.RESULT_FIRST_USER + 1;
59 
60     public static final String JSON_FLAGS = "flag";
61     public static final String JSON_ICON = "icon";
62     public static final String JSON_ID = "id";
63     public static final String JSON_PACKAGE = "pkg";
64     public static final String JSON_WHEN = "when";
65     public static final String JSON_TAG = "tag";
66     public static final String JSON_RANK = "rank";
67     public static final String JSON_AMBIENT = "ambient";
68     public static final String JSON_MATCHES_ZEN_FILTER = "matches_zen_filter";
69 
70     private ArrayList<String> mPosted = new ArrayList<String>();
71     private ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
72     private ArrayMap<String, String> mNotificationKeys = new ArrayMap<>();
73     private ArrayList<String> mRemoved = new ArrayList<String>();
74     private ArrayList<String> mOrder = new ArrayList<>();
75     private Set<String> mTestPackages = new HashSet<>();
76     private BroadcastReceiver mReceiver;
77     private int mDND = -1;
78 
79     @Override
onCreate()80     public void onCreate() {
81         super.onCreate();
82         Log.d(TAG, "created");
83 
84         mTestPackages.add("com.android.cts.verifier");
85 
86         mPosted = new ArrayList<String>();
87         mRemoved = new ArrayList<String>();
88 
89         mReceiver = new BroadcastReceiver() {
90             @Override
91             public void onReceive(Context context, Intent intent) {
92                 String action = intent.getAction();
93                 if (SERVICE_CHECK.equals(action)) {
94                     Log.d(TAG, "SERVICE_CHECK");
95                     setResultCode(Activity.RESULT_OK);
96                 } else if (SERVICE_POSTED.equals(action)) {
97                     Log.d(TAG, "SERVICE_POSTED");
98                     Bundle bundle = new Bundle();
99                     bundle.putStringArrayList(EXTRA_PAYLOAD, mPosted);
100                     setResultExtras(bundle);
101                     setResultCode(Activity.RESULT_OK);
102                 } else if (SERVICE_DND.equals(action)) {
103                     Log.d(TAG, "SERVICE_DND");
104                     Bundle bundle = new Bundle();
105                     bundle.putInt(EXTRA_INT, mDND);
106                     setResultExtras(bundle);
107                     setResultCode(Activity.RESULT_OK);
108                 } else if (SERVICE_ORDER.equals(action)) {
109                     Log.d(TAG, "SERVICE_ORDER");
110                     Bundle bundle = new Bundle();
111                     bundle.putStringArrayList(EXTRA_PAYLOAD, mOrder);
112                     setResultExtras(bundle);
113                     setResultCode(Activity.RESULT_OK);
114                 } else if (SERVICE_PAYLOADS.equals(action)) {
115                     Log.d(TAG, "SERVICE_PAYLOADS");
116                     Bundle bundle = new Bundle();
117                     ArrayList<String> payloadData = new ArrayList<>(mNotifications.size());
118                     for (JSONObject payload: mNotifications.values()) {
119                         payloadData.add(payload.toString());
120                     }
121                     bundle.putStringArrayList(EXTRA_PAYLOAD, payloadData);
122                     setResultExtras(bundle);
123                     setResultCode(Activity.RESULT_OK);
124                 } else if (SERVICE_REMOVED.equals(action)) {
125                     Log.d(TAG, "SERVICE_REMOVED");
126                     Bundle bundle = new Bundle();
127                     bundle.putStringArrayList(EXTRA_PAYLOAD, mRemoved);
128                     setResultExtras(bundle);
129                     setResultCode(Activity.RESULT_OK);
130                 } else if (SERVICE_CLEAR_ONE.equals(action)) {
131                     Log.d(TAG, "SERVICE_CLEAR_ONE");
132                     String tag = intent.getStringExtra(EXTRA_TAG);
133                     String key = mNotificationKeys.get(tag);
134                     if (key != null) {
135                         MockListener.this.cancelNotification(key);
136                     } else {
137                         Log.w(TAG, "Notification does not exist: " + tag);
138                     }
139                 } else if (SERVICE_CLEAR_ALL.equals(action)) {
140                     Log.d(TAG, "SERVICE_CLEAR_ALL");
141                     MockListener.this.cancelAllNotifications();
142                 } else if (SERVICE_RESET.equals(action)) {
143                     Log.d(TAG, "SERVICE_RESET");
144                     resetData();
145                 } else {
146                     Log.w(TAG, "unknown action");
147                     setResultCode(Activity.RESULT_CANCELED);
148                 }
149             }
150         };
151         IntentFilter filter = new IntentFilter();
152         filter.addAction(SERVICE_CHECK);
153         filter.addAction(SERVICE_DND);
154         filter.addAction(SERVICE_POSTED);
155         filter.addAction(SERVICE_ORDER);
156         filter.addAction(SERVICE_PAYLOADS);
157         filter.addAction(SERVICE_REMOVED);
158         filter.addAction(SERVICE_CLEAR_ONE);
159         filter.addAction(SERVICE_CLEAR_ALL);
160         filter.addAction(SERVICE_RESET);
161         registerReceiver(mReceiver, filter);
162     }
163 
164     @Override
onDestroy()165     public void onDestroy() {
166         super.onDestroy();
167         unregisterReceiver(mReceiver);
168         mReceiver = null;
169         Log.d(TAG, "destroyed");
170     }
171 
172     @Override
onListenerConnected()173     public void onListenerConnected() {
174         super.onListenerConnected();
175         mDND = getCurrentInterruptionFilter();
176         Log.d(TAG, "initial value of CurrentInterruptionFilter is " + mDND);
177     }
178 
179     @Override
onInterruptionFilterChanged(int interruptionFilter)180     public void onInterruptionFilterChanged(int interruptionFilter) {
181         super.onInterruptionFilterChanged(interruptionFilter);
182         mDND = interruptionFilter;
183         Log.d(TAG, "value of CurrentInterruptionFilter changed to " + mDND);
184     }
185 
resetData()186     public void resetData() {
187         mPosted.clear();
188         mNotifications.clear();
189         mRemoved.clear();
190         mOrder.clear();
191     }
192 
193     @Override
onNotificationRankingUpdate(RankingMap rankingMap)194     public void onNotificationRankingUpdate(RankingMap rankingMap) {
195         String[] orderedKeys = rankingMap.getOrderedKeys();
196         mOrder.clear();
197         Ranking rank = new Ranking();
198         for( int i = 0; i < orderedKeys.length; i++) {
199             String key = orderedKeys[i];
200             mOrder.add(key);
201             rankingMap.getRanking(key, rank);
202             JSONObject note = mNotifications.get(key);
203             if (note != null) {
204                 try {
205                     note.put(JSON_RANK, rank.getRank());
206                     note.put(JSON_AMBIENT, rank.isAmbient());
207                     note.put(JSON_MATCHES_ZEN_FILTER, rank.matchesInterruptionFilter());
208                 } catch (JSONException e) {
209                     Log.e(TAG, "failed to pack up notification payload", e);
210                 }
211             }
212         }
213     }
214 
215     @Override
onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap)216     public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
217         if (!mTestPackages.contains(sbn.getPackageName())) { return; }
218         Log.d(TAG, "posted: " + sbn.getTag());
219         mPosted.add(sbn.getTag());
220         JSONObject notification = new JSONObject();
221         try {
222             notification.put(JSON_TAG, sbn.getTag());
223             notification.put(JSON_ID, sbn.getId());
224             notification.put(JSON_PACKAGE, sbn.getPackageName());
225             notification.put(JSON_WHEN, sbn.getNotification().when);
226             notification.put(JSON_ICON, sbn.getNotification().icon);
227             notification.put(JSON_FLAGS, sbn.getNotification().flags);
228             mNotifications.put(sbn.getKey(), notification);
229             mNotificationKeys.put(sbn.getTag(), sbn.getKey());
230         } catch (JSONException e) {
231             Log.e(TAG, "failed to pack up notification payload", e);
232         }
233         onNotificationRankingUpdate(rankingMap);
234     }
235 
236     @Override
onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap)237     public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
238         Log.d(TAG, "removed: " + sbn.getTag());
239         mRemoved.add(sbn.getTag());
240         mNotifications.remove(sbn.getKey());
241         onNotificationRankingUpdate(rankingMap);
242         mNotificationKeys.remove(sbn.getTag());
243     }
244 
resetListenerData(Context context)245     public static void resetListenerData(Context context) {
246         sendCommand(context, SERVICE_RESET, null, 0);
247     }
248 
probeListenerStatus(Context context, StatusCatcher catcher)249     public static void probeListenerStatus(Context context, StatusCatcher catcher) {
250         requestStatus(context, SERVICE_CHECK, catcher);
251     }
252 
probeFilter(Context context, IntegerResultCatcher catcher)253     public static void probeFilter(Context context, IntegerResultCatcher catcher) {
254         requestIntegerResult(context, SERVICE_DND, catcher);
255     }
256 
probeListenerPosted(Context context, StringListResultCatcher catcher)257     public static void probeListenerPosted(Context context, StringListResultCatcher catcher) {
258         requestStringListResult(context, SERVICE_POSTED, catcher);
259     }
260 
probeListenerOrder(Context context, StringListResultCatcher catcher)261     public static void probeListenerOrder(Context context, StringListResultCatcher catcher) {
262         requestStringListResult(context, SERVICE_ORDER, catcher);
263     }
264 
probeListenerPayloads(Context context, StringListResultCatcher catcher)265     public static void probeListenerPayloads(Context context, StringListResultCatcher catcher) {
266         requestStringListResult(context, SERVICE_PAYLOADS, catcher);
267     }
268 
probeListenerRemoved(Context context, StringListResultCatcher catcher)269     public static void probeListenerRemoved(Context context, StringListResultCatcher catcher) {
270         requestStringListResult(context, SERVICE_REMOVED, catcher);
271     }
272 
clearOne(Context context, String tag, int code)273     public static void clearOne(Context context, String tag, int code) {
274         sendCommand(context, SERVICE_CLEAR_ONE, tag, code);
275     }
276 
clearAll(Context context)277     public static void clearAll(Context context) {
278         sendCommand(context, SERVICE_CLEAR_ALL, null, 0);
279     }
280 
sendCommand(Context context, String action, String tag, int code)281     private static void sendCommand(Context context, String action, String tag, int code) {
282         Intent broadcast = new Intent(action);
283         if (tag != null) {
284             broadcast.putExtra(EXTRA_TAG, tag);
285             broadcast.putExtra(EXTRA_CODE, code);
286         }
287         context.sendBroadcast(broadcast);
288     }
289 
290     public abstract static class StatusCatcher extends BroadcastReceiver {
291         @Override
onReceive(Context context, Intent intent)292         public void onReceive(Context context, Intent intent) {
293             accept(Integer.valueOf(getResultCode()));
294         }
295 
accept(int result)296         abstract public void accept(int result);
297     }
298 
requestStatus(Context context, String action, StatusCatcher catcher)299     private static void requestStatus(Context context, String action,
300             StatusCatcher catcher) {
301         Intent broadcast = new Intent(action);
302         context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
303     }
304 
305     public abstract static class IntegerResultCatcher extends BroadcastReceiver {
306         @Override
onReceive(Context context, Intent intent)307         public void onReceive(Context context, Intent intent) {
308             accept(getResultExtras(true).getInt(EXTRA_INT, -1));
309         }
310 
accept(int result)311         abstract public void accept(int result);
312     }
313 
requestIntegerResult(Context context, String action, IntegerResultCatcher catcher)314     private static void requestIntegerResult(Context context, String action,
315             IntegerResultCatcher catcher) {
316         Intent broadcast = new Intent(action);
317         context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
318     }
319 
320     public abstract static class StringListResultCatcher extends BroadcastReceiver {
321         @Override
onReceive(Context context, Intent intent)322         public void onReceive(Context context, Intent intent) {
323             accept(getResultExtras(true).getStringArrayList(EXTRA_PAYLOAD));
324         }
325 
accept(List<String> result)326         abstract public void accept(List<String> result);
327     }
328 
requestStringListResult(Context context, String action, StringListResultCatcher catcher)329     private static void requestStringListResult(Context context, String action,
330             StringListResultCatcher catcher) {
331         Intent broadcast = new Intent(action);
332         context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
333     }
334 }
335