package org.fdroid.fdroid.localrepo.type; import android.content.Context; import android.support.annotation.Nullable; import android.util.Log; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.localrepo.SwapService; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import javax.jmdns.JmDNS; import javax.jmdns.ServiceInfo; /** * Sends a {@link SwapService#BONJOUR_STATE_CHANGE} broadcasts when starting, started or stopped. */ public class BonjourBroadcast extends SwapType { private static final String TAG = "BonjourBroadcast"; private JmDNS jmdns; private ServiceInfo pairService; public BonjourBroadcast(Context context) { super(context); } @Override public void start() { Utils.debugLog(TAG, "Preparing to start Bonjour service."); sendBroadcast(SwapService.EXTRA_STARTING); InetAddress address = getDeviceAddress(); if (address == null) { Log.e(TAG, "Starting Bonjour service, but couldn't ascertain IP address. Seems we are not connected to a network."); return; } /* * a ServiceInfo can only be registered with a single instance * of JmDNS, and there is only ever a single LocalHTTPD port to * advertise anyway. */ if (pairService != null || jmdns != null) { clearCurrentMDNSService(); } String repoName = Preferences.get().getLocalRepoName(); HashMap<String, String> values = new HashMap<>(); values.put("path", "/fdroid/repo"); values.put("name", repoName); values.put("fingerprint", FDroidApp.repo.fingerprint); String type; if (Preferences.get().isLocalRepoHttpsEnabled()) { values.put("type", "fdroidrepos"); type = "_https._tcp.local."; } else { values.put("type", "fdroidrepo"); type = "_http._tcp.local."; } try { Utils.debugLog(TAG, "Starting bonjour service..."); pairService = ServiceInfo.create(type, repoName, FDroidApp.port, 0, 0, values); jmdns = JmDNS.create(address); jmdns.registerService(pairService); setConnected(true); Utils.debugLog(TAG, "... Bounjour service started."); } catch (IOException e) { Log.e(TAG, "Error while registering jmdns service", e); setConnected(false); } } @Override public void stop() { Utils.debugLog(TAG, "Unregistering MDNS service..."); clearCurrentMDNSService(); setConnected(false); } private void clearCurrentMDNSService() { if (jmdns != null) { jmdns.unregisterAllServices(); Utils.closeQuietly(jmdns); pairService = null; jmdns = null; } } @Override public String getBroadcastAction() { return SwapService.BONJOUR_STATE_CHANGE; } @Nullable private InetAddress getDeviceAddress() { if (FDroidApp.ipAddressString != null) { try { return InetAddress.getByName(FDroidApp.ipAddressString); } catch (UnknownHostException ignored) { } } return null; } }