Use NsdManager for mDNS discovery on Android 14

This commit is contained in:
Cameron Gutman
2023-07-11 19:58:50 -05:00
parent 1f72c82acb
commit 38588402e3
5 changed files with 513 additions and 294 deletions

View File

@@ -3,22 +3,21 @@ package com.limelight.discovery;
import java.util.List;
import com.limelight.nvstream.mdns.MdnsComputer;
import com.limelight.nvstream.mdns.JmDNSDiscoveryAgent;
import com.limelight.nvstream.mdns.MdnsDiscoveryAgent;
import com.limelight.nvstream.mdns.MdnsDiscoveryListener;
import com.limelight.nvstream.mdns.NsdManagerDiscoveryAgent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
public class DiscoveryService extends Service {
private MdnsDiscoveryAgent discoveryAgent;
private MdnsDiscoveryListener boundListener;
private MulticastLock multicastLock;
public class DiscoveryBinder extends Binder {
public void setListener(MdnsDiscoveryListener listener) {
@@ -26,13 +25,11 @@ public class DiscoveryService extends Service {
}
public void startDiscovery(int queryIntervalMs) {
multicastLock.acquire();
discoveryAgent.startDiscovery(queryIntervalMs);
}
public void stopDiscovery() {
discoveryAgent.stopDiscovery();
multicastLock.release();
}
public List<MdnsComputer> getComputerSet() {
@@ -42,11 +39,7 @@ public class DiscoveryService extends Service {
@Override
public void onCreate() {
WifiManager wifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
multicastLock = wifiMgr.createMulticastLock("Limelight mDNS");
multicastLock.setReferenceCounted(false);
discoveryAgent = new MdnsDiscoveryAgent(new MdnsDiscoveryListener() {
MdnsDiscoveryListener listener = new MdnsDiscoveryListener() {
@Override
public void notifyComputerAdded(MdnsComputer computer) {
if (boundListener != null) {
@@ -60,7 +53,22 @@ public class DiscoveryService extends Service {
boundListener.notifyDiscoveryFailure(e);
}
}
});
};
// Prior to Android 14, NsdManager doesn't provide all the capabilities needed for parity
// with jmDNS (specifically handling multiple addresses for a single service). There are
// also documented reliability bugs early in the Android 4.x series shortly after it was
// introduced. The benefit of using NsdManager over jmDNS is that it works correctly in
// environments where mDNS proxying is required, like ChromeOS, WSA, and the emulator.
//
// As such, we use the jmDNS-based MdnsDiscoveryAgent prior to Android 14 and NsdManager
// on Android 14 and above.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
discoveryAgent = new JmDNSDiscoveryAgent(getApplicationContext(), listener);
}
else {
discoveryAgent = new NsdManagerDiscoveryAgent(getApplicationContext(), listener);
}
}
private final DiscoveryBinder binder = new DiscoveryBinder();
@@ -74,7 +82,6 @@ public class DiscoveryService extends Service {
public boolean onUnbind(Intent intent) {
// Stop any discovery session
discoveryAgent.stopDiscovery();
multicastLock.release();
// Unbind the listener
boundListener = null;