2 * Copyright 2011 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.ipc.invalidation.testing.android;
19 import com.google.ipc.invalidation.external.client.InvalidationClient;
20 import com.google.ipc.invalidation.external.client.InvalidationListener;
21 import com.google.ipc.invalidation.external.client.SystemResources.Logger;
22 import com.google.ipc.invalidation.external.client.android.AndroidInvalidationClient;
23 import com.google.ipc.invalidation.external.client.android.AndroidInvalidationListener;
24 import com.google.ipc.invalidation.external.client.android.service.AndroidLogger;
25 import com.google.ipc.invalidation.external.client.android.service.Event;
26 import com.google.ipc.invalidation.external.client.android.service.Response;
27 import com.google.ipc.invalidation.external.client.types.AckHandle;
28 import com.google.ipc.invalidation.external.client.types.ErrorInfo;
29 import com.google.ipc.invalidation.external.client.types.Invalidation;
30 import com.google.ipc.invalidation.external.client.types.ObjectId;
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.os.Bundle;
38 import java.util.concurrent.ConcurrentHashMap;
41 * TestListener service maintains a mapping of listeners by client key and forwards received events
42 * to an InvalidationListener instance. The listener should be registered in
43 * {@code Android-Manifest.xml} as follows:
47 * android:name="com.google.ipc.invalidation.testing.android.InvalidationTestListener">
49 * <action android:name="com.google.ipc.invalidation.EVENTS"/>
55 public class InvalidationTestListener extends AndroidInvalidationListener {
58 private static final Logger logger = AndroidLogger.forTag("InvTestListener");
60 private static final Map<String, InvalidationListener> listenerMap =
61 new ConcurrentHashMap<String, InvalidationListener>();
64 * Creates and returns an intent that is valid for use in creating a new invalidation client
65 * that will deliver events to the test listener.
67 public static Intent getEventIntent(Context context) {
68 Intent eventIntent = new Intent(Event.LISTENER_INTENT);
69 ComponentName component = new ComponentName(context.getPackageName(),
70 InvalidationTestListener.class.getName());
71 eventIntent.setComponent(component);
76 * Sets the invalidation listener delegate to receive events for a given clientKey.
78 public static void setInvalidationListener(String clientKey, InvalidationListener listener) {
79 logger.fine("setListener %s for %s", listener, clientKey);
80 listenerMap.put(clientKey, listener);
84 * Removes the invalidation listener delegate to receive events for a given clientKey.
86 public static void removeInvalidationListener(String clientKey) {
87 listenerMap.remove(clientKey);
92 protected void handleEvent(Bundle input, Bundle output) {
94 // Ignore events that target a client key where there is no listener registered
95 // It's likely that these are late-delivered events for an earlier test case.
96 Event event = new Event(input);
97 String clientKey = event.getClientKey();
98 if (!listenerMap.containsKey(clientKey)) {
99 logger.fine("Ignoring %s event to %s", event.getAction(), clientKey);
100 Response.Builder response = Response.newBuilder(event.getActionOrdinal(), output);
101 response.setStatus(Response.Status.SUCCESS);
105 super.handleEvent(input, output);
109 public void ready(InvalidationClient client) {
110 InvalidationListener listener = getListener(client);
111 logger.fine("Received READY for %s: %s", getClientKey(client), listener);
112 if (listener != null) {
113 listener.ready(client);
118 public void invalidate(
119 InvalidationClient client, Invalidation invalidation, AckHandle ackHandle) {
120 InvalidationListener listener = getListener(client);
121 logger.fine("Received INVALIDATE for %s: %s", getClientKey(client), listener);
122 if (listener != null) {
123 listener.invalidate(client, invalidation, ackHandle);
128 public void invalidateUnknownVersion(
129 InvalidationClient client, ObjectId objectId, AckHandle ackHandle) {
130 InvalidationListener listener = getListener(client);
131 logger.fine("Received INVALIDATE_UNKNOWN_VERSION for %s: %s", getClientKey(client), listener);
132 if (listener != null) {
133 listener.invalidateUnknownVersion(client, objectId, ackHandle);
138 public void invalidateAll(InvalidationClient client, AckHandle ackHandle) {
139 InvalidationListener listener = getListener(client);
140 logger.fine("Received INVALIDATE_ALL for %s: %s", getClientKey(client), listener);
141 if (listener != null) {
142 listener.invalidateAll(client, ackHandle);
147 public void informRegistrationStatus(
148 InvalidationClient client, ObjectId objectId, RegistrationState regState) {
149 InvalidationListener listener = getListener(client);
150 logger.fine("Received INFORM_REGISTRATION_STATUS for %s: %s", getClientKey(client), listener);
151 if (listener != null) {
152 listener.informRegistrationStatus(client, objectId, regState);
157 public void informRegistrationFailure(
158 InvalidationClient client, ObjectId objectId, boolean isTransient, String errorMessage) {
159 InvalidationListener listener = getListener(client);
160 logger.fine("Received INFORM_REGISTRATION_FAILURE for %s: %s", getClientKey(client), listener);
161 if (listener != null) {
162 listener.informRegistrationFailure(client, objectId, isTransient, errorMessage);
167 public void reissueRegistrations(InvalidationClient client, byte[] prefix, int prefixLength) {
168 InvalidationListener listener = getListener(client);
169 logger.fine("Received REISSUE_REGISTRATIONS for %s: %s", getClientKey(client), listener);
170 if (listener != null) {
171 listener.reissueRegistrations(client, prefix, prefixLength);
176 public void informError(InvalidationClient client, ErrorInfo errorInfo) {
177 InvalidationListener listener = getListener(client);
178 logger.fine("Received INFORM_ERROR for %s: %s", getClientKey(client), listener);
179 if (listener != null) {
180 listener.informError(client, errorInfo);
184 private String getClientKey(InvalidationClient client) {
185 return ((AndroidInvalidationClient) client).getClientKey();
188 private InvalidationListener getListener(InvalidationClient client) {
189 String clientKey = getClientKey(client);
190 return listenerMap.get(clientKey);