/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.util; import org.json.JSONObject; import android.util.Log; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; public final class EventDispatcher { private static final String LOGTAG = "GeckoEventDispatcher"; private final Map> mEventListeners = new HashMap>(); public void registerEventListener(String event, GeckoEventListener listener) { synchronized (mEventListeners) { CopyOnWriteArrayList listeners = mEventListeners.get(event); if (listeners == null) { // create a CopyOnWriteArrayList so that we can modify it // concurrently with iterating through it in handleGeckoMessage. // Otherwise we could end up throwing a ConcurrentModificationException. listeners = new CopyOnWriteArrayList(); } else if (listeners.contains(listener)) { Log.w(LOGTAG, "EventListener already registered for event \"" + event + "\"", new IllegalArgumentException()); } listeners.add(listener); mEventListeners.put(event, listeners); } } public void unregisterEventListener(String event, GeckoEventListener listener) { synchronized (mEventListeners) { CopyOnWriteArrayList listeners = mEventListeners.get(event); if (listeners == null) { return; } listeners.remove(listener); if (listeners.size() == 0) { mEventListeners.remove(event); } } } public String dispatchEvent(String message) { // { // "type": "value", // "event_specific": "value", // ... try { JSONObject json = new JSONObject(message); if (json.has("gecko")) { json = json.getJSONObject("gecko"); Log.w(LOGTAG, "The 'gecko' property of the sendMessageToJava parameter is deprecated; message of type " + json.getString("type")); } String type = json.getString("type"); CopyOnWriteArrayList listeners; synchronized (mEventListeners) { listeners = mEventListeners.get(type); } if (listeners == null) return ""; String response = null; for (GeckoEventListener listener : listeners) { listener.handleMessage(type, json); if (listener instanceof GeckoEventResponder) { String newResponse = ((GeckoEventResponder)listener).getResponse(); if (response != null && newResponse != null) { Log.e(LOGTAG, "Received two responses for message of type " + type); } response = newResponse; } } if (response != null) return response; } catch (Exception e) { Log.e(LOGTAG, "handleGeckoMessage throws " + e, e); } return ""; } }