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.nls; 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.Log; 27 28 import org.json.JSONException; 29 import org.json.JSONObject; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 public class MockListener extends NotificationListenerService { 35 static final String TAG = "MockListener"; 36 37 static final String SERVICE_CHECK = "android.service.notification.cts.SERVICE_CHECK"; 38 static final String SERVICE_POSTED = "android.service.notification.cts.SERVICE_POSTED"; 39 static final String SERVICE_PAYLOADS = "android.service.notification.cts.SERVICE_PAYLOADS"; 40 static final String SERVICE_REMOVED = "android.service.notification.cts.SERVICE_REMOVED"; 41 static final String SERVICE_RESET = "android.service.notification.cts.SERVICE_RESET"; 42 static final String SERVICE_CLEAR_ONE = "android.service.notification.cts.SERVICE_CLEAR_ONE"; 43 static final String SERVICE_CLEAR_ALL = "android.service.notification.cts.SERVICE_CLEAR_ALL"; 44 45 static final String EXTRA_PAYLOAD = "TAGS"; 46 static final String EXTRA_TAG = "TAG"; 47 static final String EXTRA_CODE = "CODE"; 48 49 static final int RESULT_TIMEOUT = Activity.RESULT_FIRST_USER; 50 static final int RESULT_NO_SERVER = Activity.RESULT_FIRST_USER + 1; 51 52 public static final String JSON_FLAGS = "flag"; 53 public static final String JSON_ICON = "icon"; 54 public static final String JSON_ID = "id"; 55 public static final String JSON_PACKAGE = "pkg"; 56 public static final String JSON_WHEN = "when"; 57 public static final String JSON_TAG = "tag"; 58 59 private ArrayList<String> mPosted = new ArrayList<String>(); 60 private ArrayList<String> mPayloads = new ArrayList<String>(); 61 private ArrayList<String> mRemoved = new ArrayList<String>(); 62 private BroadcastReceiver mReceiver; 63 64 @Override 65 public void onCreate() { 66 super.onCreate(); 67 Log.d(TAG, "created"); 68 69 mPosted = new ArrayList<String>(); 70 mRemoved = new ArrayList<String>(); 71 72 mReceiver = new BroadcastReceiver() { 73 @Override 74 public void onReceive(Context context, Intent intent) { 75 String action = intent.getAction(); 76 if (SERVICE_CHECK.equals(action)) { 77 Log.d(TAG, "SERVICE_CHECK"); 78 setResultCode(Activity.RESULT_OK); 79 } else if (SERVICE_POSTED.equals(action)) { 80 Log.d(TAG, "SERVICE_POSTED"); 81 Bundle bundle = new Bundle(); 82 bundle.putStringArrayList(EXTRA_PAYLOAD, mPosted); 83 setResultExtras(bundle); 84 setResultCode(Activity.RESULT_OK); 85 } else if (SERVICE_PAYLOADS.equals(action)) { 86 Log.d(TAG, "SERVICE_PAYLOADS"); 87 Bundle bundle = new Bundle(); 88 bundle.putStringArrayList(EXTRA_PAYLOAD, mPayloads); 89 setResultExtras(bundle); 90 setResultCode(Activity.RESULT_OK); 91 } else if (SERVICE_REMOVED.equals(action)) { 92 Log.d(TAG, "SERVICE_REMOVED"); 93 Bundle bundle = new Bundle(); 94 bundle.putStringArrayList(EXTRA_PAYLOAD, mRemoved); 95 setResultExtras(bundle); 96 setResultCode(Activity.RESULT_OK); 97 } else if (SERVICE_CLEAR_ONE.equals(action)) { 98 Log.d(TAG, "SERVICE_CLEAR_ONE"); 99 MockListener.this.cancelNotification( 100 context.getApplicationInfo().packageName, 101 intent.getStringExtra(EXTRA_TAG), 102 intent.getIntExtra(EXTRA_CODE, 0)); 103 } else if (SERVICE_CLEAR_ALL.equals(action)) { 104 Log.d(TAG, "SERVICE_CLEAR_ALL"); 105 MockListener.this.cancelAllNotifications(); 106 } else if (SERVICE_RESET.equals(action)) { 107 Log.d(TAG, "SERVICE_RESET"); 108 resetData(); 109 } else { 110 Log.w(TAG, "unknown action"); 111 setResultCode(Activity.RESULT_CANCELED); 112 } 113 } 114 }; 115 IntentFilter filter = new IntentFilter(); 116 filter.addAction(SERVICE_CHECK); 117 filter.addAction(SERVICE_POSTED); 118 filter.addAction(SERVICE_PAYLOADS); 119 filter.addAction(SERVICE_REMOVED); 120 filter.addAction(SERVICE_CLEAR_ONE); 121 filter.addAction(SERVICE_CLEAR_ALL); 122 filter.addAction(SERVICE_RESET); 123 registerReceiver(mReceiver, filter); 124 } 125 126 @Override 127 public void onDestroy() { 128 super.onDestroy(); 129 unregisterReceiver(mReceiver); 130 mReceiver = null; 131 Log.d(TAG, "destroyed"); 132 } 133 134 public void resetData() { 135 mPosted.clear(); 136 mPayloads.clear(); 137 mRemoved.clear(); 138 } 139 140 @Override 141 public void onNotificationPosted(StatusBarNotification sbn) { 142 Log.d(TAG, "posted: " + sbn.getTag()); 143 mPosted.add(sbn.getTag()); 144 JSONObject payload = new JSONObject(); 145 try { 146 payload.put(JSON_TAG, sbn.getTag()); 147 payload.put(JSON_ID, sbn.getId()); 148 payload.put(JSON_PACKAGE, sbn.getPackageName()); 149 payload.put(JSON_WHEN, sbn.getNotification().when); 150 payload.put(JSON_ICON, sbn.getNotification().icon); 151 payload.put(JSON_FLAGS, sbn.getNotification().flags); 152 mPayloads.add(payload.toString()); 153 } catch (JSONException e) { 154 Log.e(TAG, "failed to pack up notification payload", e); 155 } 156 } 157 158 @Override 159 public void onNotificationRemoved(StatusBarNotification sbn) { 160 Log.d(TAG, "removed: " + sbn.getTag()); 161 mRemoved.add(sbn.getTag()); 162 } 163 164 public static void resetListenerData(Context context) { 165 sendCommand(context, SERVICE_RESET, null, 0); 166 } 167 168 public static void probeListenerStatus(Context context, IntegerResultCatcher catcher) { 169 requestIntegerResult(context, SERVICE_CHECK, catcher); 170 } 171 172 public static void probeListenerPosted(Context context, StringListResultCatcher catcher) { 173 requestStringListResult(context, SERVICE_POSTED, catcher); 174 } 175 176 public static void probeListenerPayloads(Context context, StringListResultCatcher catcher) { 177 requestStringListResult(context, SERVICE_PAYLOADS, catcher); 178 } 179 180 public static void probeListenerRemoved(Context context, StringListResultCatcher catcher) { 181 requestStringListResult(context, SERVICE_REMOVED, catcher); 182 } 183 184 public static void clearOne(Context context, String tag, int code) { 185 sendCommand(context, SERVICE_CLEAR_ONE, tag, code); 186 } 187 188 public static void clearAll(Context context) { 189 sendCommand(context, SERVICE_CLEAR_ALL, null, 0); 190 } 191 192 private static void sendCommand(Context context, String action, String tag, int code) { 193 Intent broadcast = new Intent(action); 194 if (tag != null) { 195 broadcast.putExtra(EXTRA_TAG, tag); 196 broadcast.putExtra(EXTRA_CODE, code); 197 } 198 context.sendBroadcast(broadcast); 199 } 200 201 public abstract static class IntegerResultCatcher extends BroadcastReceiver { 202 @Override 203 public void onReceive(Context context, Intent intent) { 204 accept(Integer.valueOf(getResultCode())); 205 } 206 207 abstract public void accept(int result); 208 } 209 210 private static void requestIntegerResult(Context context, String action, 211 IntegerResultCatcher catcher) { 212 Intent broadcast = new Intent(action); 213 context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null); 214 } 215 216 public abstract static class StringListResultCatcher extends BroadcastReceiver { 217 @Override 218 public void onReceive(Context context, Intent intent) { 219 accept(getResultExtras(true).getStringArrayList(EXTRA_PAYLOAD)); 220 } 221 222 abstract public void accept(List<String> result); 223 } 224 225 private static void requestStringListResult(Context context, String action, 226 StringListResultCatcher catcher) { 227 Intent broadcast = new Intent(action); 228 context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null); 229 } 230 } 231