Bug 1471408 - Move all top level Java classes into their own file. r=snorp
authorTudor-Gabriel Vîjială <tvijiala@mozilla.com>
Wed, 27 Jun 2018 00:02:01 +0100
changeset 424355 0259570da98eba806fa76e3f29728f81dea38acd
parent 424354 ca14c36e4280927a10e43e95b8f459e767fc8178
child 424356 865dd9ed965ce44df70722c09a50edfa283ecf29
push id34202
push userebalazs@mozilla.com
push dateFri, 29 Jun 2018 09:40:47 +0000
treeherdermozilla-central@7f2d98706144 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1471408
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1471408 - Move all top level Java classes into their own file. r=snorp MozReview-Commit-ID: 716FWeZ0q3B
mobile/android/app/build.gradle
mobile/android/app/lint.xml
mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java
mobile/android/base/java/org/mozilla/gecko/mdns/DiscoveryListener.java
mobile/android/base/java/org/mozilla/gecko/mdns/DummyMulticastDNSManager.java
mobile/android/base/java/org/mozilla/gecko/mdns/MulticastDNSEventManager.java
mobile/android/base/java/org/mozilla/gecko/mdns/MulticastDNSManager.java
mobile/android/base/java/org/mozilla/gecko/mdns/NsdMulticastDNSManager.java
mobile/android/base/java/org/mozilla/gecko/mdns/RegistrationListener.java
mobile/android/base/java/org/mozilla/gecko/mdns/ResolveListener.java
--- a/mobile/android/app/build.gradle
+++ b/mobile/android/app/build.gradle
@@ -127,16 +127,17 @@ android {
 
                 if (!mozconfig.substs.MOZ_NATIVE_DEVICES) {
                     exclude 'org/mozilla/gecko/ChromeCastDisplay.java'
                     exclude 'org/mozilla/gecko/ChromeCastPlayer.java'
                     exclude 'org/mozilla/gecko/GeckoMediaPlayer.java'
                     exclude 'org/mozilla/gecko/GeckoPresentationDisplay.java'
                     exclude 'org/mozilla/gecko/MediaPlayerManager.java'
                     exclude 'org/mozilla/gecko/RemotePresentationService.java'
+                    exclude 'org/mozilla/gecko/VirtualPresentation.java'
                 }
 
                 if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
                     exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
                 } else {
                     exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
                 }
 
--- a/mobile/android/app/lint.xml
+++ b/mobile/android/app/lint.xml
@@ -48,16 +48,17 @@
     <issue id="NewApi" severity="error">
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamPreference.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentTelemetry.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/preferences/LocaleListPreference.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/PrintHelper.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java"/>
+        <ignore path="**/mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/db/SharedBrowserDatabaseProvider.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/tabs/TabPanelBackButton.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java"/>
         <ignore path="**/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java"/>
         <ignore path="**/media/webrtc/trunk/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java"/>
         <ignore path="**/media/webrtc/trunk/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java"/>
         <ignore path="src/photon/res/values/styles.xml"/>
--- a/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
@@ -1,45 +1,23 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * vim: ts=4 sw=4 expandtab:
  * 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;
 
-import org.mozilla.gecko.ScreenManagerHelper;
-import org.mozilla.geckoview.GeckoRuntime;
-import org.mozilla.geckoview.GeckoSession;
-import org.mozilla.geckoview.GeckoSessionSettings;
-import org.mozilla.geckoview.GeckoView;
-
-import com.google.android.gms.cast.CastMediaControlIntent;
 import com.google.android.gms.cast.CastPresentation;
 import com.google.android.gms.cast.CastRemoteDisplayLocalService;
-import com.google.android.gms.common.ConnectionResult;
-import com.google.android.gms.common.GooglePlayServicesUtil;
 
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v7.media.MediaControlIntent;
-import android.support.v7.media.MediaRouteSelector;
-import android.support.v7.media.MediaRouter.RouteInfo;
-import android.support.v7.media.MediaRouter;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Display;
-import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
-import android.widget.RelativeLayout;
-
-import java.util.HashMap;
-import java.util.Map;
 
 /*
  * Service to keep the remote display running even when the app goes into the background
  */
 public class RemotePresentationService extends CastRemoteDisplayLocalService {
 
     private static final String LOGTAG = "RemotePresentationService";
     private CastPresentation presentation;
@@ -93,55 +71,8 @@ public class RemotePresentationService e
         try {
             presentation.show();
         } catch (WindowManager.InvalidDisplayException ex) {
             Log.e(LOGTAG, "Unable to show presentation, display was removed.", ex);
             dismissPresentation();
         }
     }
 }
-
-class VirtualPresentation extends CastPresentation {
-    private static final String LOGTAG = "VirtualPresentation";
-    private static final String PRESENTATION_VIEW_URI = "chrome://browser/content/PresentationView.xul";
-
-    private RelativeLayout layout;
-    private GeckoView view;
-    private String deviceId;
-    private int screenId;
-
-    public VirtualPresentation(Context context, Display display) {
-        super(context, display);
-    }
-
-    public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
-    public void setScreenId(int screenId) { this.screenId = screenId; }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        /*
-         * NOTICE: The context get from getContext() is different to the context
-         * of the application. Presentaion has its own context to get correct
-         * resources.
-         */
-
-        final GeckoSession session = new GeckoSession();
-        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
-                                        PRESENTATION_VIEW_URI + "#" + deviceId);
-        session.getSettings().setInt(GeckoSessionSettings.SCREEN_ID, screenId);
-
-        // Create new GeckoView
-        view = new GeckoView(getContext());
-        view.setSession(session, GeckoApplication.ensureRuntime(getContext()));
-        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                                              LayoutParams.MATCH_PARENT));
-
-        // Create new layout to put the GeckoView
-        layout = new RelativeLayout(getContext());
-        layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                                                LayoutParams.MATCH_PARENT));
-        layout.addView(view);
-
-        setContentView(layout);
-    }
-}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/VirtualPresentation.java
@@ -0,0 +1,67 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
+ * 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;
+
+import org.mozilla.geckoview.GeckoSession;
+import org.mozilla.geckoview.GeckoSessionSettings;
+import org.mozilla.geckoview.GeckoView;
+
+import com.google.android.gms.cast.CastPresentation;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.RelativeLayout;
+
+
+class VirtualPresentation extends CastPresentation {
+    private static final String LOGTAG = "VirtualPresentation";
+    private static final String PRESENTATION_VIEW_URI = "chrome://browser/content/PresentationView.xul";
+
+    private RelativeLayout layout;
+    private GeckoView view;
+    private String deviceId;
+    private int screenId;
+
+    public VirtualPresentation(Context context, Display display) {
+        super(context, display);
+    }
+
+    public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
+    public void setScreenId(int screenId) { this.screenId = screenId; }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        /*
+         * NOTICE: The context get from getContext() is different to the context
+         * of the application. Presentaion has its own context to get correct
+         * resources.
+         */
+
+        final GeckoSession session = new GeckoSession();
+        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
+                PRESENTATION_VIEW_URI + "#" + deviceId);
+        session.getSettings().setInt(GeckoSessionSettings.SCREEN_ID, screenId);
+
+        // Create new GeckoView
+        view = new GeckoView(getContext());
+        view.setSession(session, GeckoApplication.ensureRuntime(getContext()));
+        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT));
+
+        // Create new layout to put the GeckoView
+        layout = new RelativeLayout(getContext());
+        layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT));
+        layout.addView(view);
+
+        setContentView(layout);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/DiscoveryListener.java
@@ -0,0 +1,127 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.EventDispatcher;
+import org.mozilla.gecko.util.EventCallback;
+
+import android.annotation.TargetApi;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Log;
+
+@TargetApi(16)
+class DiscoveryListener implements NsdManager.DiscoveryListener {
+    private static final boolean DEBUG = false;
+    private static final String LOGTAG = "GeckoMDNSManager";
+    private final NsdManager nsdManager;
+
+    // Callbacks are called from different thread, and every callback can be called only once.
+    private EventCallback mStartCallback = null;
+    private EventCallback mStopCallback = null;
+
+    DiscoveryListener(final NsdManager nsdManager) {
+        this.nsdManager = nsdManager;
+    }
+
+    public void discoverServices(final String serviceType, final EventCallback callback) {
+        synchronized (this) {
+            mStartCallback = callback;
+        }
+        nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, this);
+    }
+
+    public void stopServiceDiscovery(final EventCallback callback) {
+        synchronized (this) {
+            mStopCallback = callback;
+        }
+        nsdManager.stopServiceDiscovery(this);
+    }
+
+    @Override
+    public synchronized void onDiscoveryStarted(final String serviceType) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onDiscoveryStarted: " + serviceType);
+        }
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStartCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendSuccess(serviceType);
+    }
+
+    @Override
+    public synchronized void onStartDiscoveryFailed(final String serviceType, final int errorCode) {
+        Log.e(LOGTAG, "onStartDiscoveryFailed: " + serviceType + "(" + errorCode + ")");
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStartCallback;
+        }
+
+        callback.sendError(errorCode);
+    }
+
+    @Override
+    public synchronized void onDiscoveryStopped(final String serviceType) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onDiscoveryStopped: " + serviceType);
+        }
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStopCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendSuccess(serviceType);
+    }
+
+    @Override
+    public synchronized void onStopDiscoveryFailed(final String serviceType, final int errorCode) {
+        Log.e(LOGTAG, "onStopDiscoveryFailed: " + serviceType + "(" + errorCode + ")");
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStopCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendError(errorCode);
+    }
+
+    @Override
+    public void onServiceFound(final NsdServiceInfo serviceInfo) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onServiceFound: " + serviceInfo.getServiceName());
+        }
+
+        EventDispatcher.getInstance().dispatch(
+                "NsdManager:ServiceFound", NsdMulticastDNSManager.toBundle(serviceInfo));
+    }
+
+    @Override
+    public void onServiceLost(final NsdServiceInfo serviceInfo) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onServiceLost: " + serviceInfo.getServiceName());
+        }
+
+        EventDispatcher.getInstance().dispatch(
+                "NdManager:ServiceLost", NsdMulticastDNSManager.toBundle(serviceInfo));
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/DummyMulticastDNSManager.java
@@ -0,0 +1,40 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.util.BundleEventListener;
+
+import android.util.Log;
+
+class DummyMulticastDNSManager extends MulticastDNSManager implements BundleEventListener {
+    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 // BundleEventListener
+    public void handleMessage(final String event, final GeckoBundle message,
+                              final EventCallback callback) {
+        if (DEBUG) {
+            Log.v(LOGTAG, "handleMessage: " + event);
+        }
+        callback.sendError(FAILURE_UNSUPPORTED);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/MulticastDNSEventManager.java
@@ -0,0 +1,66 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.EventDispatcher;
+import org.mozilla.gecko.util.BundleEventListener;
+import org.mozilla.gecko.util.ThreadUtils;
+
+import android.support.annotation.UiThread;
+
+/**
+ * Mix-in class for MulticastDNSManagers to call EventDispatcher.
+ */
+class MulticastDNSEventManager {
+    private BundleEventListener mListener = null;
+    private boolean mEventsRegistered = false;
+
+    MulticastDNSEventManager(final BundleEventListener listener) {
+        mListener = listener;
+    }
+
+    @UiThread
+    public void init() {
+        ThreadUtils.assertOnUiThread();
+
+        if (mEventsRegistered || mListener == null) {
+            return;
+        }
+
+        registerEvents();
+        mEventsRegistered = true;
+    }
+
+    @UiThread
+    public void tearDown() {
+        ThreadUtils.assertOnUiThread();
+
+        if (!mEventsRegistered || mListener == null) {
+            return;
+        }
+
+        unregisterEvents();
+        mEventsRegistered = false;
+    }
+
+    private void registerEvents() {
+        EventDispatcher.getInstance().registerGeckoThreadListener(mListener,
+                "NsdManager:DiscoverServices",
+                "NsdManager:StopServiceDiscovery",
+                "NsdManager:RegisterService",
+                "NsdManager:UnregisterService",
+                "NsdManager:ResolveService");
+    }
+
+    private void unregisterEvents() {
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(mListener,
+                "NsdManager:DiscoverServices",
+                "NsdManager:StopServiceDiscovery",
+                "NsdManager:RegisterService",
+                "NsdManager:UnregisterService",
+                "NsdManager:ResolveService");
+    }
+}
\ No newline at end of file
--- a/mobile/android/base/java/org/mozilla/gecko/mdns/MulticastDNSManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/MulticastDNSManager.java
@@ -1,33 +1,16 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * 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.mdns;
 
-import org.mozilla.gecko.AppConstants.Versions;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.util.GeckoBundle;
-import org.mozilla.gecko.util.BundleEventListener;
-import org.mozilla.gecko.util.ThreadUtils;
-
-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;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * This class is the bridge between XPCOM mDNS module and NsdManager.
  *
  * @See nsIDNSServiceDiscovery.idl
  */
 public abstract class MulticastDNSManager {
     protected static final boolean DEBUG = false;
@@ -39,491 +22,8 @@ public abstract class MulticastDNSManage
             instance = new DummyMulticastDNSManager();
         }
         return instance;
     }
 
     public abstract void init();
     public abstract void tearDown();
 }
-
-/**
- * Mix-in class for MulticastDNSManagers to call EventDispatcher.
- */
-class MulticastDNSEventManager {
-    private BundleEventListener mListener = null;
-    private boolean mEventsRegistered = false;
-
-    MulticastDNSEventManager(final BundleEventListener listener) {
-        mListener = listener;
-    }
-
-    @UiThread
-    public void init() {
-        ThreadUtils.assertOnUiThread();
-
-        if (mEventsRegistered || mListener == null) {
-            return;
-        }
-
-        registerEvents();
-        mEventsRegistered = true;
-    }
-
-    @UiThread
-    public void tearDown() {
-        ThreadUtils.assertOnUiThread();
-
-        if (!mEventsRegistered || mListener == null) {
-            return;
-        }
-
-        unregisterEvents();
-        mEventsRegistered = false;
-    }
-
-    private void registerEvents() {
-        EventDispatcher.getInstance().registerGeckoThreadListener(mListener,
-                "NsdManager:DiscoverServices",
-                "NsdManager:StopServiceDiscovery",
-                "NsdManager:RegisterService",
-                "NsdManager:UnregisterService",
-                "NsdManager:ResolveService");
-    }
-
-    private void unregisterEvents() {
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(mListener,
-                "NsdManager:DiscoverServices",
-                "NsdManager:StopServiceDiscovery",
-                "NsdManager:RegisterService",
-                "NsdManager:UnregisterService",
-                "NsdManager:ResolveService");
-    }
-}
-
-class NsdMulticastDNSManager extends MulticastDNSManager implements BundleEventListener {
-    private final NsdManager nsdManager;
-    private final MulticastDNSEventManager mEventManager;
-    private Map<String, DiscoveryListener> mDiscoveryListeners = null;
-    private Map<String, RegistrationListener> mRegistrationListeners = null;
-
-    @TargetApi(16)
-    public NsdMulticastDNSManager(final Context context) {
-        nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
-        mEventManager = new MulticastDNSEventManager(this);
-        mDiscoveryListeners = new ConcurrentHashMap<String, DiscoveryListener>();
-        mRegistrationListeners = new ConcurrentHashMap<String, RegistrationListener>();
-    }
-
-    @Override
-    public void init() {
-        mEventManager.init();
-    }
-
-    @Override
-    public void tearDown() {
-        mDiscoveryListeners.clear();
-        mRegistrationListeners.clear();
-
-        mEventManager.tearDown();
-    }
-
-    @Override // BundleEventListener
-    public void handleMessage(final String event, final GeckoBundle message,
-                              final EventCallback callback) {
-        if (DEBUG) {
-            Log.v(LOGTAG, "handleMessage: " + event);
-        }
-
-        switch (event) {
-            case "NsdManager:DiscoverServices": {
-                DiscoveryListener listener = new DiscoveryListener(nsdManager);
-                listener.discoverServices(message.getString("serviceType"), callback);
-                mDiscoveryListeners.put(message.getString("uniqueId"), listener);
-                break;
-            }
-            case "NsdManager:StopServiceDiscovery": {
-                String uuid = message.getString("uniqueId");
-                DiscoveryListener listener = mDiscoveryListeners.remove(uuid);
-                if (listener == null) {
-                    Log.e(LOGTAG, "DiscoveryListener " + uuid + " was not found.");
-                    return;
-                }
-                listener.stopServiceDiscovery(callback);
-                break;
-            }
-            case "NsdManager:RegisterService": {
-                RegistrationListener listener = new RegistrationListener(nsdManager);
-                listener.registerService(message.getInt("port"),
-                        message.getString("serviceName", android.os.Build.MODEL),
-                        message.getString("serviceType"),
-                        parseAttributes(message.getBundleArray("attributes")),
-                        callback);
-                mRegistrationListeners.put(message.getString("uniqueId"), listener);
-                break;
-            }
-            case "NsdManager:UnregisterService": {
-                String uuid = message.getString("uniqueId");
-                RegistrationListener listener = mRegistrationListeners.remove(uuid);
-                if (listener == null) {
-                    Log.e(LOGTAG, "RegistrationListener " + uuid + " was not found.");
-                    return;
-                }
-                listener.unregisterService(callback);
-                break;
-            }
-            case "NsdManager:ResolveService": {
-                (new ResolveListener(nsdManager)).resolveService(message.getString("serviceName"),
-                        message.getString("serviceType"),
-                        callback);
-                break;
-            }
-        }
-    }
-
-    private Map<String, String> parseAttributes(final GeckoBundle[] jsobjs) {
-        if (jsobjs == null || jsobjs.length == 0 || !Versions.feature21Plus) {
-            return null;
-        }
-
-        final Map<String, String> attributes = new HashMap<>(jsobjs.length);
-        for (final GeckoBundle obj : jsobjs) {
-            attributes.put(obj.getString("name"), obj.getString("value"));
-        }
-
-        return attributes;
-    }
-
-    @TargetApi(16)
-    public static GeckoBundle toBundle(final NsdServiceInfo serviceInfo) {
-        final GeckoBundle obj = new GeckoBundle();
-
-        final InetAddress host = serviceInfo.getHost();
-        if (host != null) {
-            obj.putString("host", host.getCanonicalHostName());
-            obj.putString("address", host.getHostAddress());
-        }
-
-        int port = serviceInfo.getPort();
-        if (port != 0) {
-            obj.putInt("port", port);
-        }
-
-        final String serviceName = serviceInfo.getServiceName();
-        if (serviceName != null) {
-            obj.putString("serviceName", serviceName);
-        }
-
-        final String serviceType = serviceInfo.getServiceType();
-        if (serviceType != null) {
-            obj.putString("serviceType", serviceType);
-        }
-
-        return obj;
-    }
-}
-
-class DummyMulticastDNSManager extends MulticastDNSManager implements BundleEventListener {
-    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 // BundleEventListener
-    public void handleMessage(final String event, final GeckoBundle message,
-                              final EventCallback callback) {
-        if (DEBUG) {
-            Log.v(LOGTAG, "handleMessage: " + event);
-        }
-        callback.sendError(FAILURE_UNSUPPORTED);
-    }
-}
-
-@TargetApi(16)
-class DiscoveryListener implements NsdManager.DiscoveryListener {
-    private static final boolean DEBUG = false;
-    private static final String LOGTAG = "GeckoMDNSManager";
-    private final NsdManager nsdManager;
-
-    // Callbacks are called from different thread, and every callback can be called only once.
-    private EventCallback mStartCallback = null;
-    private EventCallback mStopCallback = null;
-
-    DiscoveryListener(final NsdManager nsdManager) {
-        this.nsdManager = nsdManager;
-    }
-
-    public void discoverServices(final String serviceType, final EventCallback callback) {
-        synchronized (this) {
-            mStartCallback = callback;
-        }
-        nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, this);
-    }
-
-    public void stopServiceDiscovery(final EventCallback callback) {
-        synchronized (this) {
-            mStopCallback = callback;
-        }
-        nsdManager.stopServiceDiscovery(this);
-    }
-
-    @Override
-    public synchronized void onDiscoveryStarted(final String serviceType) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onDiscoveryStarted: " + serviceType);
-        }
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStartCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendSuccess(serviceType);
-    }
-
-    @Override
-    public synchronized void onStartDiscoveryFailed(final String serviceType, final int errorCode) {
-        Log.e(LOGTAG, "onStartDiscoveryFailed: " + serviceType + "(" + errorCode + ")");
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStartCallback;
-        }
-
-        callback.sendError(errorCode);
-    }
-
-    @Override
-    public synchronized void onDiscoveryStopped(final String serviceType) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onDiscoveryStopped: " + serviceType);
-        }
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStopCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendSuccess(serviceType);
-    }
-
-    @Override
-    public synchronized void onStopDiscoveryFailed(final String serviceType, final int errorCode) {
-        Log.e(LOGTAG, "onStopDiscoveryFailed: " + serviceType + "(" + errorCode + ")");
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStopCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendError(errorCode);
-    }
-
-    @Override
-    public void onServiceFound(final NsdServiceInfo serviceInfo) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onServiceFound: " + serviceInfo.getServiceName());
-        }
-
-        EventDispatcher.getInstance().dispatch(
-                "NsdManager:ServiceFound", NsdMulticastDNSManager.toBundle(serviceInfo));
-    }
-
-    @Override
-    public void onServiceLost(final NsdServiceInfo serviceInfo) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onServiceLost: " + serviceInfo.getServiceName());
-        }
-
-        EventDispatcher.getInstance().dispatch(
-                "NdManager:ServiceLost", NsdMulticastDNSManager.toBundle(serviceInfo));
-    }
-}
-
-@TargetApi(16)
-class RegistrationListener implements NsdManager.RegistrationListener {
-    private static final boolean DEBUG = false;
-    private static final String LOGTAG = "GeckoMDNSManager";
-    private final NsdManager nsdManager;
-
-    // Callbacks are called from different thread, and every callback can be called only once.
-    private EventCallback mStartCallback = null;
-    private EventCallback mStopCallback = null;
-
-    RegistrationListener(final NsdManager nsdManager) {
-        this.nsdManager = nsdManager;
-    }
-
-    public void registerService(final int port, final String serviceName, final String serviceType,
-                                final Map<String, String> attributes, final EventCallback callback) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "registerService: " + serviceName + "." + serviceType + ":" + port);
-        }
-
-        NsdServiceInfo serviceInfo = new NsdServiceInfo();
-        serviceInfo.setPort(port);
-        serviceInfo.setServiceName(serviceName);
-        serviceInfo.setServiceType(serviceType);
-        setAttributes(serviceInfo, attributes);
-
-        synchronized (this) {
-            mStartCallback = callback;
-        }
-        nsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, this);
-    }
-
-    @TargetApi(21)
-    private void setAttributes(final NsdServiceInfo serviceInfo, final Map<String, String> attributes) {
-        if (attributes == null || !Versions.feature21Plus) {
-            return;
-        }
-
-        for (Map.Entry<String, String> entry : attributes.entrySet()) {
-            serviceInfo.setAttribute(entry.getKey(), entry.getValue());
-        }
-    }
-
-    public void unregisterService(final EventCallback callback) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "unregisterService");
-        }
-        synchronized (this) {
-            mStopCallback = callback;
-        }
-
-        nsdManager.unregisterService(this);
-    }
-
-    @Override
-    public synchronized void onServiceRegistered(final NsdServiceInfo serviceInfo) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onServiceRegistered: " + serviceInfo.getServiceName());
-        }
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStartCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
-    }
-
-    @Override
-    public synchronized void onRegistrationFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
-        Log.e(LOGTAG, "onRegistrationFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStartCallback;
-        }
-
-        callback.sendError(errorCode);
-    }
-
-    @Override
-    public synchronized void onServiceUnregistered(final NsdServiceInfo serviceInfo) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onServiceUnregistered: " + serviceInfo.getServiceName());
-        }
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStopCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
-    }
-
-    @Override
-    public synchronized void onUnregistrationFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
-        Log.e(LOGTAG, "onUnregistrationFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
-
-        EventCallback callback;
-        synchronized (this) {
-            callback = mStopCallback;
-        }
-
-        if (callback == null) {
-            return;
-        }
-
-        callback.sendError(errorCode);
-    }
-}
-
-@TargetApi(16)
-class ResolveListener implements NsdManager.ResolveListener {
-    private static final boolean DEBUG = false;
-    private static final String LOGTAG = "GeckoMDNSManager";
-    private final NsdManager nsdManager;
-
-    // Callback is called from different thread, and the callback can be called only once.
-    private EventCallback mCallback = null;
-
-    public ResolveListener(final NsdManager nsdManager) {
-        this.nsdManager = nsdManager;
-    }
-
-    public void resolveService(final String serviceName, final String serviceType, final EventCallback callback) {
-        NsdServiceInfo serviceInfo = new NsdServiceInfo();
-        serviceInfo.setServiceName(serviceName);
-        serviceInfo.setServiceType(serviceType);
-
-        mCallback = callback;
-        nsdManager.resolveService(serviceInfo, this);
-    }
-
-
-    @Override
-    public synchronized void onResolveFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
-        Log.e(LOGTAG, "onResolveFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
-
-        if (mCallback == null) {
-            return;
-        }
-        mCallback.sendError(errorCode);
-    }
-
-    @Override
-    public synchronized void onServiceResolved(final NsdServiceInfo serviceInfo) {
-        if (DEBUG) {
-            Log.d(LOGTAG, "onServiceResolved: " + serviceInfo.getServiceName());
-        }
-
-        if (mCallback == null) {
-            return;
-        }
-
-        mCallback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
-    }
-}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/NsdMulticastDNSManager.java
@@ -0,0 +1,145 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.AppConstants.Versions;
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.util.BundleEventListener;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+class NsdMulticastDNSManager extends MulticastDNSManager implements BundleEventListener {
+    private final NsdManager nsdManager;
+    private final MulticastDNSEventManager mEventManager;
+    private Map<String, DiscoveryListener> mDiscoveryListeners = null;
+    private Map<String, RegistrationListener> mRegistrationListeners = null;
+
+    @TargetApi(16)
+    public NsdMulticastDNSManager(final Context context) {
+        nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
+        mEventManager = new MulticastDNSEventManager(this);
+        mDiscoveryListeners = new ConcurrentHashMap<String, DiscoveryListener>();
+        mRegistrationListeners = new ConcurrentHashMap<String, RegistrationListener>();
+    }
+
+    @Override
+    public void init() {
+        mEventManager.init();
+    }
+
+    @Override
+    public void tearDown() {
+        mDiscoveryListeners.clear();
+        mRegistrationListeners.clear();
+
+        mEventManager.tearDown();
+    }
+
+    @Override // BundleEventListener
+    public void handleMessage(final String event, final GeckoBundle message,
+                              final EventCallback callback) {
+        if (DEBUG) {
+            Log.v(LOGTAG, "handleMessage: " + event);
+        }
+
+        switch (event) {
+            case "NsdManager:DiscoverServices": {
+                DiscoveryListener listener = new DiscoveryListener(nsdManager);
+                listener.discoverServices(message.getString("serviceType"), callback);
+                mDiscoveryListeners.put(message.getString("uniqueId"), listener);
+                break;
+            }
+            case "NsdManager:StopServiceDiscovery": {
+                String uuid = message.getString("uniqueId");
+                DiscoveryListener listener = mDiscoveryListeners.remove(uuid);
+                if (listener == null) {
+                    Log.e(LOGTAG, "DiscoveryListener " + uuid + " was not found.");
+                    return;
+                }
+                listener.stopServiceDiscovery(callback);
+                break;
+            }
+            case "NsdManager:RegisterService": {
+                RegistrationListener listener = new RegistrationListener(nsdManager);
+                listener.registerService(message.getInt("port"),
+                        message.getString("serviceName", android.os.Build.MODEL),
+                        message.getString("serviceType"),
+                        parseAttributes(message.getBundleArray("attributes")),
+                        callback);
+                mRegistrationListeners.put(message.getString("uniqueId"), listener);
+                break;
+            }
+            case "NsdManager:UnregisterService": {
+                String uuid = message.getString("uniqueId");
+                RegistrationListener listener = mRegistrationListeners.remove(uuid);
+                if (listener == null) {
+                    Log.e(LOGTAG, "RegistrationListener " + uuid + " was not found.");
+                    return;
+                }
+                listener.unregisterService(callback);
+                break;
+            }
+            case "NsdManager:ResolveService": {
+                (new ResolveListener(nsdManager)).resolveService(message.getString("serviceName"),
+                        message.getString("serviceType"),
+                        callback);
+                break;
+            }
+        }
+    }
+
+    private Map<String, String> parseAttributes(final GeckoBundle[] jsobjs) {
+        if (jsobjs == null || jsobjs.length == 0 || !Versions.feature21Plus) {
+            return null;
+        }
+
+        final Map<String, String> attributes = new HashMap<>(jsobjs.length);
+        for (final GeckoBundle obj : jsobjs) {
+            attributes.put(obj.getString("name"), obj.getString("value"));
+        }
+
+        return attributes;
+    }
+
+    @TargetApi(16)
+    public static GeckoBundle toBundle(final NsdServiceInfo serviceInfo) {
+        final GeckoBundle obj = new GeckoBundle();
+
+        final InetAddress host = serviceInfo.getHost();
+        if (host != null) {
+            obj.putString("host", host.getCanonicalHostName());
+            obj.putString("address", host.getHostAddress());
+        }
+
+        int port = serviceInfo.getPort();
+        if (port != 0) {
+            obj.putInt("port", port);
+        }
+
+        final String serviceName = serviceInfo.getServiceName();
+        if (serviceName != null) {
+            obj.putString("serviceName", serviceName);
+        }
+
+        final String serviceType = serviceInfo.getServiceType();
+        if (serviceType != null) {
+            obj.putString("serviceType", serviceType);
+        }
+
+        return obj;
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/RegistrationListener.java
@@ -0,0 +1,136 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.AppConstants.Versions;
+
+import org.mozilla.gecko.util.EventCallback;
+
+import android.annotation.TargetApi;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Log;
+
+import java.util.Map;
+
+@TargetApi(16)
+class RegistrationListener implements NsdManager.RegistrationListener {
+    private static final boolean DEBUG = false;
+    private static final String LOGTAG = "GeckoMDNSManager";
+    private final NsdManager nsdManager;
+
+    // Callbacks are called from different thread, and every callback can be called only once.
+    private EventCallback mStartCallback = null;
+    private EventCallback mStopCallback = null;
+
+    RegistrationListener(final NsdManager nsdManager) {
+        this.nsdManager = nsdManager;
+    }
+
+    public void registerService(final int port, final String serviceName, final String serviceType,
+                                final Map<String, String> attributes, final EventCallback callback) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "registerService: " + serviceName + "." + serviceType + ":" + port);
+        }
+
+        NsdServiceInfo serviceInfo = new NsdServiceInfo();
+        serviceInfo.setPort(port);
+        serviceInfo.setServiceName(serviceName);
+        serviceInfo.setServiceType(serviceType);
+        setAttributes(serviceInfo, attributes);
+
+        synchronized (this) {
+            mStartCallback = callback;
+        }
+        nsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, this);
+    }
+
+    @TargetApi(21)
+    private void setAttributes(final NsdServiceInfo serviceInfo, final Map<String, String> attributes) {
+        if (attributes == null || !Versions.feature21Plus) {
+            return;
+        }
+
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            serviceInfo.setAttribute(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void unregisterService(final EventCallback callback) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "unregisterService");
+        }
+        synchronized (this) {
+            mStopCallback = callback;
+        }
+
+        nsdManager.unregisterService(this);
+    }
+
+    @Override
+    public synchronized void onServiceRegistered(final NsdServiceInfo serviceInfo) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onServiceRegistered: " + serviceInfo.getServiceName());
+        }
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStartCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
+    }
+
+    @Override
+    public synchronized void onRegistrationFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
+        Log.e(LOGTAG, "onRegistrationFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStartCallback;
+        }
+
+        callback.sendError(errorCode);
+    }
+
+    @Override
+    public synchronized void onServiceUnregistered(final NsdServiceInfo serviceInfo) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onServiceUnregistered: " + serviceInfo.getServiceName());
+        }
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStopCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
+    }
+
+    @Override
+    public synchronized void onUnregistrationFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
+        Log.e(LOGTAG, "onUnregistrationFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
+
+        EventCallback callback;
+        synchronized (this) {
+            callback = mStopCallback;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        callback.sendError(errorCode);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/mdns/ResolveListener.java
@@ -0,0 +1,60 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.mdns;
+
+import org.mozilla.gecko.util.EventCallback;
+
+import android.annotation.TargetApi;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Log;
+
+@TargetApi(16)
+class ResolveListener implements NsdManager.ResolveListener {
+    private static final boolean DEBUG = false;
+    private static final String LOGTAG = "GeckoMDNSManager";
+    private final NsdManager nsdManager;
+
+    // Callback is called from different thread, and the callback can be called only once.
+    private EventCallback mCallback = null;
+
+    public ResolveListener(final NsdManager nsdManager) {
+        this.nsdManager = nsdManager;
+    }
+
+    public void resolveService(final String serviceName, final String serviceType, final EventCallback callback) {
+        NsdServiceInfo serviceInfo = new NsdServiceInfo();
+        serviceInfo.setServiceName(serviceName);
+        serviceInfo.setServiceType(serviceType);
+
+        mCallback = callback;
+        nsdManager.resolveService(serviceInfo, this);
+    }
+
+
+    @Override
+    public synchronized void onResolveFailed(final NsdServiceInfo serviceInfo, final int errorCode) {
+        Log.e(LOGTAG, "onResolveFailed: " + serviceInfo.getServiceName() + "(" + errorCode + ")");
+
+        if (mCallback == null) {
+            return;
+        }
+        mCallback.sendError(errorCode);
+    }
+
+    @Override
+    public synchronized void onServiceResolved(final NsdServiceInfo serviceInfo) {
+        if (DEBUG) {
+            Log.d(LOGTAG, "onServiceResolved: " + serviceInfo.getServiceName());
+        }
+
+        if (mCallback == null) {
+            return;
+        }
+
+        mCallback.sendSuccess(NsdMulticastDNSManager.toBundle(serviceInfo));
+    }
+}