2012-08-02 15:12:35 -07:00
|
|
|
/* 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/. */
|
|
|
|
|
2014-02-11 09:16:00 -08:00
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
|
|
|
import org.mozilla.gecko.GeckoAppShell;
|
|
|
|
import org.mozilla.gecko.GeckoEvent;
|
|
|
|
import org.mozilla.gecko.util.GeckoEventListener;
|
2012-08-02 15:12:35 -07:00
|
|
|
|
|
|
|
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 {
|
2013-02-25 11:42:06 -08:00
|
|
|
private static final String LOGTAG = "GeckoEventDispatcher";
|
2014-02-11 09:16:00 -08:00
|
|
|
private static final String GUID = "__guid__";
|
2012-08-02 15:12:35 -07:00
|
|
|
|
|
|
|
private final Map<String, CopyOnWriteArrayList<GeckoEventListener>> mEventListeners
|
|
|
|
= new HashMap<String, CopyOnWriteArrayList<GeckoEventListener>>();
|
|
|
|
|
|
|
|
public void registerEventListener(String event, GeckoEventListener listener) {
|
|
|
|
synchronized (mEventListeners) {
|
|
|
|
CopyOnWriteArrayList<GeckoEventListener> 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<GeckoEventListener>();
|
|
|
|
} else if (listeners.contains(listener)) {
|
2013-04-02 14:28:59 -07:00
|
|
|
Log.w(LOGTAG, "EventListener already registered for event '" + event + "'",
|
2012-08-02 15:12:35 -07:00
|
|
|
new IllegalArgumentException());
|
|
|
|
}
|
|
|
|
listeners.add(listener);
|
|
|
|
mEventListeners.put(event, listeners);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void unregisterEventListener(String event, GeckoEventListener listener) {
|
|
|
|
synchronized (mEventListeners) {
|
|
|
|
CopyOnWriteArrayList<GeckoEventListener> listeners = mEventListeners.get(event);
|
|
|
|
if (listeners == null) {
|
2013-04-02 14:28:59 -07:00
|
|
|
Log.w(LOGTAG, "unregisterEventListener: event '" + event + "' has no listeners");
|
2012-08-02 15:12:35 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-04-02 14:28:59 -07:00
|
|
|
if (!listeners.remove(listener)) {
|
|
|
|
Log.w(LOGTAG, "unregisterEventListener: tried to remove an unregistered listener " +
|
|
|
|
"for event '" + event + "'");
|
|
|
|
}
|
2012-08-02 15:12:35 -07:00
|
|
|
if (listeners.size() == 0) {
|
|
|
|
mEventListeners.remove(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-11 09:16:00 -08:00
|
|
|
public void dispatchEvent(String message) {
|
2013-05-30 17:42:56 -07:00
|
|
|
try {
|
|
|
|
JSONObject json = new JSONObject(message);
|
2014-02-11 09:16:00 -08:00
|
|
|
dispatchEvent(json);
|
2013-05-30 17:42:56 -07:00
|
|
|
} catch (Exception e) {
|
|
|
|
Log.e(LOGTAG, "dispatchEvent: malformed JSON.", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-11 09:16:00 -08:00
|
|
|
public void dispatchEvent(JSONObject json) {
|
2013-02-01 17:36:38 -08:00
|
|
|
// {
|
|
|
|
// "type": "value",
|
|
|
|
// "event_specific": "value",
|
|
|
|
// ...
|
2012-08-02 15:12:35 -07:00
|
|
|
try {
|
2013-04-02 14:28:59 -07:00
|
|
|
JSONObject gecko = json.has("gecko") ? json.getJSONObject("gecko") : null;
|
|
|
|
if (gecko != null) {
|
|
|
|
json = gecko;
|
2013-02-01 17:36:38 -08:00
|
|
|
}
|
2013-04-02 14:28:59 -07:00
|
|
|
|
2013-02-01 17:36:38 -08:00
|
|
|
String type = json.getString("type");
|
2012-08-02 15:12:35 -07:00
|
|
|
|
2013-04-02 14:28:59 -07:00
|
|
|
if (gecko != null) {
|
|
|
|
Log.w(LOGTAG, "Message '" + type + "' has deprecated 'gecko' property!");
|
|
|
|
}
|
|
|
|
|
2012-08-02 15:12:35 -07:00
|
|
|
CopyOnWriteArrayList<GeckoEventListener> listeners;
|
|
|
|
synchronized (mEventListeners) {
|
|
|
|
listeners = mEventListeners.get(type);
|
|
|
|
}
|
|
|
|
|
2013-04-02 14:28:59 -07:00
|
|
|
if (listeners == null || listeners.size() == 0) {
|
|
|
|
Log.d(LOGTAG, "dispatchEvent: no listeners registered for event '" + type + "'");
|
2014-02-11 09:16:00 -08:00
|
|
|
return;
|
2013-04-02 14:28:59 -07:00
|
|
|
}
|
2012-08-02 15:12:35 -07:00
|
|
|
|
|
|
|
for (GeckoEventListener listener : listeners) {
|
2013-02-01 17:36:38 -08:00
|
|
|
listener.handleMessage(type, json);
|
2012-08-02 15:12:35 -07:00
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
Log.e(LOGTAG, "handleGeckoMessage throws " + e, e);
|
|
|
|
}
|
|
|
|
|
2014-02-11 09:16:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void sendResponse(JSONObject message, JSONObject response) {
|
|
|
|
try {
|
|
|
|
response.put(GUID, message.getString(GUID));
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(message.getString("type") + ":Return", response.toString()));
|
2014-02-25 05:19:41 -08:00
|
|
|
} catch (Exception ex) {
|
|
|
|
Log.e(LOGTAG, "Unable to send response", ex);
|
|
|
|
}
|
2014-02-11 09:16:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void sendError(JSONObject message, JSONObject error) {
|
|
|
|
try {
|
|
|
|
error.put(GUID, message.getString(GUID));
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(message.getString("type") + ":Error", error.toString()));
|
2014-02-25 05:19:41 -08:00
|
|
|
} catch (Exception ex) {
|
|
|
|
Log.e(LOGTAG, "Unable to send error", ex);
|
|
|
|
}
|
2012-08-02 15:12:35 -07:00
|
|
|
}
|
|
|
|
}
|