blob: 3d0e0d707a3f21183d9fda95ede7444e8389c431 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.verifier.notifications;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class MockListener extends NotificationListenerService {
static final String TAG = "MockListener";
static final String SERVICE_BASE = "android.service.notification.cts.";
static final String SERVICE_CHECK = SERVICE_BASE + "SERVICE_CHECK";
static final String SERVICE_POSTED = SERVICE_BASE + "SERVICE_POSTED";
static final String SERVICE_PAYLOADS = SERVICE_BASE + "SERVICE_PAYLOADS";
static final String SERVICE_REMOVED = SERVICE_BASE + "SERVICE_REMOVED";
static final String SERVICE_RESET = SERVICE_BASE + "SERVICE_RESET";
static final String SERVICE_CLEAR_ONE = SERVICE_BASE + "SERVICE_CLEAR_ONE";
static final String SERVICE_CLEAR_ALL = SERVICE_BASE + "SERVICE_CLEAR_ALL";
public static final String SERVICE_ORDER = SERVICE_BASE + "SERVICE_ORDER";
public static final String SERVICE_DND = SERVICE_BASE + "SERVICE_DND";
static final String EXTRA_PAYLOAD = "PAYLOAD";
static final String EXTRA_INT = "INT";
static final String EXTRA_TAG = "TAG";
static final String EXTRA_CODE = "CODE";
static final int RESULT_TIMEOUT = Activity.RESULT_FIRST_USER;
static final int RESULT_NO_SERVER = Activity.RESULT_FIRST_USER + 1;
public static final String JSON_FLAGS = "flag";
public static final String JSON_ICON = "icon";
public static final String JSON_ID = "id";
public static final String JSON_PACKAGE = "pkg";
public static final String JSON_WHEN = "when";
public static final String JSON_TAG = "tag";
public static final String JSON_RANK = "rank";
public static final String JSON_AMBIENT = "ambient";
public static final String JSON_MATCHES_ZEN_FILTER = "matches_zen_filter";
private ArrayList<String> mPosted = new ArrayList<String>();
private ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
private ArrayList<String> mRemoved = new ArrayList<String>();
private ArrayList<String> mOrder = new ArrayList<>();
private BroadcastReceiver mReceiver;
private int mDND = -1;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "created");
mPosted = new ArrayList<String>();
mRemoved = new ArrayList<String>();
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (SERVICE_CHECK.equals(action)) {
Log.d(TAG, "SERVICE_CHECK");
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_POSTED.equals(action)) {
Log.d(TAG, "SERVICE_POSTED");
Bundle bundle = new Bundle();
bundle.putStringArrayList(EXTRA_PAYLOAD, mPosted);
setResultExtras(bundle);
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_DND.equals(action)) {
Log.d(TAG, "SERVICE_DND");
Bundle bundle = new Bundle();
bundle.putInt(EXTRA_INT, mDND);
setResultExtras(bundle);
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_ORDER.equals(action)) {
Log.d(TAG, "SERVICE_ORDER");
Bundle bundle = new Bundle();
bundle.putStringArrayList(EXTRA_PAYLOAD, mOrder);
setResultExtras(bundle);
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_PAYLOADS.equals(action)) {
Log.d(TAG, "SERVICE_PAYLOADS");
Bundle bundle = new Bundle();
ArrayList<String> payloadData = new ArrayList<>(mNotifications.size());
for (JSONObject payload: mNotifications.values()) {
payloadData.add(payload.toString());
}
bundle.putStringArrayList(EXTRA_PAYLOAD, payloadData);
setResultExtras(bundle);
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_REMOVED.equals(action)) {
Log.d(TAG, "SERVICE_REMOVED");
Bundle bundle = new Bundle();
bundle.putStringArrayList(EXTRA_PAYLOAD, mRemoved);
setResultExtras(bundle);
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_CLEAR_ONE.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ONE");
MockListener.this.cancelNotification(
context.getApplicationInfo().packageName,
intent.getStringExtra(EXTRA_TAG),
intent.getIntExtra(EXTRA_CODE, 0));
} else if (SERVICE_CLEAR_ALL.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ALL");
MockListener.this.cancelAllNotifications();
} else if (SERVICE_RESET.equals(action)) {
Log.d(TAG, "SERVICE_RESET");
resetData();
} else {
Log.w(TAG, "unknown action");
setResultCode(Activity.RESULT_CANCELED);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(SERVICE_CHECK);
filter.addAction(SERVICE_DND);
filter.addAction(SERVICE_POSTED);
filter.addAction(SERVICE_ORDER);
filter.addAction(SERVICE_PAYLOADS);
filter.addAction(SERVICE_REMOVED);
filter.addAction(SERVICE_CLEAR_ONE);
filter.addAction(SERVICE_CLEAR_ALL);
filter.addAction(SERVICE_RESET);
registerReceiver(mReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
mReceiver = null;
Log.d(TAG, "destroyed");
}
@Override
public void onListenerConnected() {
super.onListenerConnected();
mDND = getCurrentInterruptionFilter();
Log.d(TAG, "initial value of CurrentInterruptionFilter is " + mDND);
}
@Override
public void onInterruptionFilterChanged(int interruptionFilter) {
super.onInterruptionFilterChanged(interruptionFilter);
mDND = interruptionFilter;
Log.d(TAG, "value of CurrentInterruptionFilter changed to " + mDND);
}
public void resetData() {
mPosted.clear();
mNotifications.clear();
mRemoved.clear();
mOrder.clear();
}
@Override
public void onNotificationRankingUpdate(RankingMap rankingMap) {
String[] orderedKeys = rankingMap.getOrderedKeys();
mOrder.clear();
Ranking rank = new Ranking();
for( int i = 0; i < orderedKeys.length; i++) {
String key = orderedKeys[i];
mOrder.add(key);
rankingMap.getRanking(key, rank);
JSONObject note = mNotifications.get(key);
if (note != null) {
try {
note.put(JSON_RANK, rank.getRank());
note.put(JSON_AMBIENT, rank.isAmbient());
note.put(JSON_MATCHES_ZEN_FILTER, rank.matchesInterruptionFilter());
} catch (JSONException e) {
Log.e(TAG, "failed to pack up notification payload", e);
}
}
}
}
@Override
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
Log.d(TAG, "posted: " + sbn.getTag());
mPosted.add(sbn.getTag());
JSONObject notification = new JSONObject();
try {
notification.put(JSON_TAG, sbn.getTag());
notification.put(JSON_ID, sbn.getId());
notification.put(JSON_PACKAGE, sbn.getPackageName());
notification.put(JSON_WHEN, sbn.getNotification().when);
notification.put(JSON_ICON, sbn.getNotification().icon);
notification.put(JSON_FLAGS, sbn.getNotification().flags);
mNotifications.put(sbn.getKey(), notification);
} catch (JSONException e) {
Log.e(TAG, "failed to pack up notification payload", e);
}
onNotificationRankingUpdate(rankingMap);
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
Log.d(TAG, "removed: " + sbn.getTag());
mRemoved.add(sbn.getTag());
mNotifications.remove(sbn.getKey());
onNotificationRankingUpdate(rankingMap);
}
public static void resetListenerData(Context context) {
sendCommand(context, SERVICE_RESET, null, 0);
}
public static void probeListenerStatus(Context context, StatusCatcher catcher) {
requestStatus(context, SERVICE_CHECK, catcher);
}
public static void probeFilter(Context context, IntegerResultCatcher catcher) {
requestIntegerResult(context, SERVICE_DND, catcher);
}
public static void probeListenerPosted(Context context, StringListResultCatcher catcher) {
requestStringListResult(context, SERVICE_POSTED, catcher);
}
public static void probeListenerOrder(Context context, StringListResultCatcher catcher) {
requestStringListResult(context, SERVICE_ORDER, catcher);
}
public static void probeListenerPayloads(Context context, StringListResultCatcher catcher) {
requestStringListResult(context, SERVICE_PAYLOADS, catcher);
}
public static void probeListenerRemoved(Context context, StringListResultCatcher catcher) {
requestStringListResult(context, SERVICE_REMOVED, catcher);
}
public static void clearOne(Context context, String tag, int code) {
sendCommand(context, SERVICE_CLEAR_ONE, tag, code);
}
public static void clearAll(Context context) {
sendCommand(context, SERVICE_CLEAR_ALL, null, 0);
}
private static void sendCommand(Context context, String action, String tag, int code) {
Intent broadcast = new Intent(action);
if (tag != null) {
broadcast.putExtra(EXTRA_TAG, tag);
broadcast.putExtra(EXTRA_CODE, code);
}
context.sendBroadcast(broadcast);
}
public abstract static class StatusCatcher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
accept(Integer.valueOf(getResultCode()));
}
abstract public void accept(int result);
}
private static void requestStatus(Context context, String action,
StatusCatcher catcher) {
Intent broadcast = new Intent(action);
context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
}
public abstract static class IntegerResultCatcher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
accept(getResultExtras(true).getInt(EXTRA_INT, -1));
}
abstract public void accept(int result);
}
private static void requestIntegerResult(Context context, String action,
IntegerResultCatcher catcher) {
Intent broadcast = new Intent(action);
context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
}
public abstract static class StringListResultCatcher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
accept(getResultExtras(true).getStringArrayList(EXTRA_PAYLOAD));
}
abstract public void accept(List<String> result);
}
private static void requestStringListResult(Context context, String action,
StringListResultCatcher catcher) {
Intent broadcast = new Intent(action);
context.sendOrderedBroadcast(broadcast, null, catcher, null, RESULT_NO_SERVER, null, null);
}
}