diff --git a/mobile/android/base/mdns/MulticastDNSManager.java b/mobile/android/base/mdns/MulticastDNSManager.java index ed3a78de9264..004b720eaba3 100644 --- a/mobile/android/base/mdns/MulticastDNSManager.java +++ b/mobile/android/base/mdns/MulticastDNSManager.java @@ -12,6 +12,7 @@ import org.mozilla.gecko.util.EventCallback; import org.mozilla.gecko.util.GeckoRequest; import org.mozilla.gecko.util.NativeEventListener; import org.mozilla.gecko.util.NativeJSObject; +import org.mozilla.gecko.util.ThreadUtils; import org.json.JSONException; import org.json.JSONObject; @@ -20,6 +21,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; +import android.support.annotation.UiThread; import android.util.Log; import java.net.InetAddress; @@ -51,28 +53,43 @@ public abstract class MulticastDNSManager { public abstract void tearDown(); } -class NsdMulticastDNSManager extends MulticastDNSManager implements NativeEventListener { - private final NsdManager nsdManager; - private DiscoveryListener mDiscoveryListener = null; - private RegistrationListener mRegistrationListener = null; +/** + * Mix-in class for MulticastDNSManagers to call EventDispatcher. + */ +class MulticastDNSEventManager { + private NativeEventListener mListener = null; + private boolean mEventsRegistered = false; - @TargetApi(16) - public NsdMulticastDNSManager(final Context context) { - nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); + MulticastDNSEventManager(NativeEventListener listener) { + mListener = listener; } - @Override + @UiThread public void init() { + ThreadUtils.assertOnUiThread(); + + if (mEventsRegistered || mListener == null) { + return; + } + registerEvents(); + mEventsRegistered = true; } - @Override + @UiThread public void tearDown() { + ThreadUtils.assertOnUiThread(); + + if (!mEventsRegistered || mListener == null) { + return; + } + unregisterEvents(); + mEventsRegistered = false; } private void registerEvents() { - EventDispatcher.getInstance().registerGeckoThreadListener(this, + EventDispatcher.getInstance().registerGeckoThreadListener(mListener, "NsdManager:DiscoverServices", "NsdManager:StopServiceDiscovery", "NsdManager:RegisterService", @@ -81,13 +98,36 @@ class NsdMulticastDNSManager extends MulticastDNSManager implements NativeEventL } private void unregisterEvents() { - EventDispatcher.getInstance().unregisterGeckoThreadListener(this, + EventDispatcher.getInstance().unregisterGeckoThreadListener(mListener, "NsdManager:DiscoverServices", "NsdManager:StopServiceDiscovery", "NsdManager:RegisterService", "NsdManager:UnregisterService", "NsdManager:ResolveService"); } +} + +class NsdMulticastDNSManager extends MulticastDNSManager implements NativeEventListener { + private final NsdManager nsdManager; + private final MulticastDNSEventManager mEventManager; + private DiscoveryListener mDiscoveryListener = null; + private RegistrationListener mRegistrationListener = null; + + @TargetApi(16) + public NsdMulticastDNSManager(final Context context) { + nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); + mEventManager = new MulticastDNSEventManager(this); + } + + @Override + public void init() { + mEventManager.init(); + } + + @Override + public void tearDown() { + mEventManager.tearDown(); + } @Override public void handleMessage(final String event, final NativeJSObject message, final EventCallback callback) { @@ -173,16 +213,28 @@ class NsdMulticastDNSManager extends MulticastDNSManager implements NativeEventL } } -class DummyMulticastDNSManager extends MulticastDNSManager { +class DummyMulticastDNSManager extends MulticastDNSManager implements NativeEventListener { + static final int FAILURE_UNSUPPORTED = -65544; + private final MulticastDNSEventManager mEventManager; + public DummyMulticastDNSManager() { + mEventManager = new MulticastDNSEventManager(this); } @Override public void init() { + mEventManager.init(); } @Override public void tearDown() { + mEventManager.tearDown(); + } + + @Override + public void handleMessage(final String event, final NativeJSObject message, final EventCallback callback) { + Log.v(LOGTAG, "handleMessage: " + event); + callback.sendError(FAILURE_UNSUPPORTED); } } diff --git a/mobile/android/modules/MulticastDNS.jsm b/mobile/android/modules/MulticastDNS.jsm index de8ae1a82b42..38f41803c613 100644 --- a/mobile/android/modules/MulticastDNS.jsm +++ b/mobile/android/modules/MulticastDNS.jsm @@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/Messaging.jsm"); Cu.import("resource://gre/modules/Services.jsm"); let log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "MulticastDNS"); +const FAILURE_INTERNAL_ERROR = -65537; + // Helper function for sending commands to Java. function send(type, data, callback) { let msg = { @@ -27,7 +29,8 @@ function send(type, data, callback) { } Messaging.sendRequestForResult(msg) - .then(result => callback(result, null), err => callback(null, err)); + .then(result => callback(result, null), + err => callback(null, typeof err === "number" ? err : FAILURE_INTERNAL_ERROR)); } // Receives service found/lost event from NsdManager @@ -149,7 +152,7 @@ MulticastDNS.prototype = { send("NsdManager:DiscoverServices", { serviceType: aServiceType }, (result, err) => { if (err) { log("onStartDiscoveryFailed: " + aServiceType + " (" + err + ")"); - this.unregisterEvent(); + this.serviceManager.removeListener(aServiceType, aListener); aListener.onStartDiscoveryFailed(aServiceType, err); } else { aListener.onDiscoveryStarted(result);