/* * Copyright 2011 Google Inc. * * 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.google.ipc.invalidation.testing.android; import com.google.ipc.invalidation.external.client.InvalidationClient; import com.google.ipc.invalidation.external.client.InvalidationListener; import com.google.ipc.invalidation.external.client.SystemResources.Logger; import com.google.ipc.invalidation.external.client.android.AndroidInvalidationClient; import com.google.ipc.invalidation.external.client.android.AndroidInvalidationListener; import com.google.ipc.invalidation.external.client.android.service.AndroidLogger; import com.google.ipc.invalidation.external.client.android.service.Event; import com.google.ipc.invalidation.external.client.android.service.Response; import com.google.ipc.invalidation.external.client.types.AckHandle; import com.google.ipc.invalidation.external.client.types.ErrorInfo; import com.google.ipc.invalidation.external.client.types.Invalidation; import com.google.ipc.invalidation.external.client.types.ObjectId; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * TestListener service maintains a mapping of listeners by client key and forwards received events * to an InvalidationListener instance. The listener should be registered in * {@code Android-Manifest.xml} as follows: * * {@code * <service * android:name="com.google.ipc.invalidation.testing.android.InvalidationTestListener"> * <intent-filter> * <action android:name="com.google.ipc.invalidation.EVENTS"/> * </intent-filter> * </service> * } * */ public class InvalidationTestListener extends AndroidInvalidationListener { /** Logger */ private static final Logger logger = AndroidLogger.forTag("InvTestListener"); private static final Map<String, InvalidationListener> listenerMap = new ConcurrentHashMap<String, InvalidationListener>(); /** * Creates and returns an intent that is valid for use in creating a new invalidation client * that will deliver events to the test listener. */ public static Intent getEventIntent(Context context) { Intent eventIntent = new Intent(Event.LISTENER_INTENT); ComponentName component = new ComponentName(context.getPackageName(), InvalidationTestListener.class.getName()); eventIntent.setComponent(component); return eventIntent; } /** * Sets the invalidation listener delegate to receive events for a given clientKey. */ public static void setInvalidationListener(String clientKey, InvalidationListener listener) { logger.fine("setListener %s for %s", listener, clientKey); listenerMap.put(clientKey, listener); } /** * Removes the invalidation listener delegate to receive events for a given clientKey. */ public static void removeInvalidationListener(String clientKey) { listenerMap.remove(clientKey); } @Override protected void handleEvent(Bundle input, Bundle output) { // Ignore events that target a client key where there is no listener registered // It's likely that these are late-delivered events for an earlier test case. Event event = new Event(input); String clientKey = event.getClientKey(); if (!listenerMap.containsKey(clientKey)) { logger.fine("Ignoring %s event to %s", event.getAction(), clientKey); Response.Builder response = Response.newBuilder(event.getActionOrdinal(), output); response.setStatus(Response.Status.SUCCESS); return; } super.handleEvent(input, output); } @Override public void ready(InvalidationClient client) { InvalidationListener listener = getListener(client); logger.fine("Received READY for %s: %s", getClientKey(client), listener); if (listener != null) { listener.ready(client); } } @Override public void invalidate( InvalidationClient client, Invalidation invalidation, AckHandle ackHandle) { InvalidationListener listener = getListener(client); logger.fine("Received INVALIDATE for %s: %s", getClientKey(client), listener); if (listener != null) { listener.invalidate(client, invalidation, ackHandle); } } @Override public void invalidateUnknownVersion( InvalidationClient client, ObjectId objectId, AckHandle ackHandle) { InvalidationListener listener = getListener(client); logger.fine("Received INVALIDATE_UNKNOWN_VERSION for %s: %s", getClientKey(client), listener); if (listener != null) { listener.invalidateUnknownVersion(client, objectId, ackHandle); } } @Override public void invalidateAll(InvalidationClient client, AckHandle ackHandle) { InvalidationListener listener = getListener(client); logger.fine("Received INVALIDATE_ALL for %s: %s", getClientKey(client), listener); if (listener != null) { listener.invalidateAll(client, ackHandle); } } @Override public void informRegistrationStatus( InvalidationClient client, ObjectId objectId, RegistrationState regState) { InvalidationListener listener = getListener(client); logger.fine("Received INFORM_REGISTRATION_STATUS for %s: %s", getClientKey(client), listener); if (listener != null) { listener.informRegistrationStatus(client, objectId, regState); } } @Override public void informRegistrationFailure( InvalidationClient client, ObjectId objectId, boolean isTransient, String errorMessage) { InvalidationListener listener = getListener(client); logger.fine("Received INFORM_REGISTRATION_FAILURE for %s: %s", getClientKey(client), listener); if (listener != null) { listener.informRegistrationFailure(client, objectId, isTransient, errorMessage); } } @Override public void reissueRegistrations(InvalidationClient client, byte[] prefix, int prefixLength) { InvalidationListener listener = getListener(client); logger.fine("Received REISSUE_REGISTRATIONS for %s: %s", getClientKey(client), listener); if (listener != null) { listener.reissueRegistrations(client, prefix, prefixLength); } } @Override public void informError(InvalidationClient client, ErrorInfo errorInfo) { InvalidationListener listener = getListener(client); logger.fine("Received INFORM_ERROR for %s: %s", getClientKey(client), listener); if (listener != null) { listener.informError(client, errorInfo); } } private String getClientKey(InvalidationClient client) { return ((AndroidInvalidationClient) client).getClientKey(); } private InvalidationListener getListener(InvalidationClient client) { String clientKey = getClientKey(client); return listenerMap.get(clientKey); } }