diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java b/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java index 3532182f65d483..f98acdfb1c7278 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java @@ -34,10 +34,19 @@ public class NsdManagerServiceBrowser implements ServiceBrowser { private final NsdManager nsdManager; private MulticastLock multicastLock; private Handler mainThreadHandler; + private final long timeout; private HashMap callbackMap; public NsdManagerServiceBrowser(Context context) { + this(context, BROWSE_SERVICE_TIMEOUT); + } + + /** + * @param context application context + * @param timeout Timeout value in case there is no response after calling browse + */ + public NsdManagerServiceBrowser(Context context, long timeout) { this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); this.mainThreadHandler = new Handler(Looper.getMainLooper()); @@ -46,6 +55,7 @@ public NsdManagerServiceBrowser(Context context) { .createMulticastLock("chipBrowseMulticastLock"); this.multicastLock.setReferenceCounted(true); callbackMap = new HashMap<>(); + this.timeout = timeout; } @Override @@ -62,7 +72,7 @@ public void run() { } }; startDiscover(serviceType, callbackHandle, contextHandle, chipMdnsCallback); - mainThreadHandler.postDelayed(timeoutRunnable, BROWSE_SERVICE_TIMEOUT); + mainThreadHandler.postDelayed(timeoutRunnable, timeout); } public void startDiscover( diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index f89e7445c7d716..a0a85b390b023c 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -32,36 +32,45 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; public class NsdManagerServiceResolver implements ServiceResolver { private static final String TAG = NsdManagerServiceResolver.class.getSimpleName(); private static final long RESOLVE_SERVICE_TIMEOUT = 30000; private final NsdManager nsdManager; private MulticastLock multicastLock; - private Handler mainThreadHandler; private List registrationListeners = new ArrayList<>(); private final CopyOnWriteArrayList mMFServiceName = new CopyOnWriteArrayList<>(); @Nullable private final NsdManagerResolverAvailState nsdManagerResolverAvailState; + private final long timeout; /** * @param context application context * @param nsdManagerResolverAvailState Passing NsdManagerResolverAvailState allows * NsdManagerServiceResolver to synchronize on the usage of NsdManager's resolveService() API + * @param timeout Timeout value in case there is no response after calling resolve */ public NsdManagerServiceResolver( - Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState) { + Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState, long timeout) { this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); - this.mainThreadHandler = new Handler(Looper.getMainLooper()); this.multicastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)) .createMulticastLock("chipMulticastLock"); this.multicastLock.setReferenceCounted(true); this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; + this.timeout = timeout; } public NsdManagerServiceResolver(Context context) { - this(context, null); + this(context, null, RESOLVE_SERVICE_TIMEOUT); + } + + public NsdManagerServiceResolver( + Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState) { + this(context, nsdManagerResolverAvailState, RESOLVE_SERVICE_TIMEOUT); } @Override @@ -96,14 +105,21 @@ public void run() { Log.d(TAG, "resolve: Timing out"); if (multicastLock.isHeld()) { multicastLock.release(); + } - if (nsdManagerResolverAvailState != null) { - nsdManagerResolverAvailState.signalFree(); - } + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.signalFree(); } } }; + ScheduledFuture resolveTimeoutExecutor = + Executors.newSingleThreadScheduledExecutor() + .schedule( + timeoutRunnable, + timeout, + TimeUnit.MILLISECONDS); + NsdServiceFinderAndResolver serviceFinderResolver = new NsdServiceFinderAndResolver( this.nsdManager, @@ -111,13 +127,10 @@ public void run() { callbackHandle, contextHandle, chipMdnsCallback, - timeoutRunnable, multicastLock, - mainThreadHandler, + resolveTimeoutExecutor, nsdManagerResolverAvailState); serviceFinderResolver.start(); - - mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT); } @Override diff --git a/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java b/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java index e98013e0eee342..c6b6291ad9da15 100644 --- a/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java +++ b/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java @@ -38,9 +38,8 @@ class NsdServiceFinderAndResolver implements NsdManager.DiscoveryListener { private final long callbackHandle; private final long contextHandle; private final ChipMdnsCallback chipMdnsCallback; - private final Runnable timeoutRunnable; private final MulticastLock multicastLock; - private final Handler mainThreadHandler; + private final ScheduledFuture resolveTimeoutExecutor; @Nullable private final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState; @@ -53,18 +52,16 @@ public NsdServiceFinderAndResolver( final long callbackHandle, final long contextHandle, final ChipMdnsCallback chipMdnsCallback, - final Runnable timeoutRunnable, final MulticastLock multicastLock, - final Handler mainThreadHandler, + final ScheduledFuture resolveTimeoutExecutor, final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState) { this.nsdManager = nsdManager; this.targetServiceInfo = targetServiceInfo; this.callbackHandle = callbackHandle; this.contextHandle = contextHandle; this.chipMdnsCallback = chipMdnsCallback; - this.timeoutRunnable = timeoutRunnable; this.multicastLock = multicastLock; - this.mainThreadHandler = mainThreadHandler; + this.resolveTimeoutExecutor = resolveTimeoutExecutor; this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; } @@ -103,7 +100,7 @@ public void onServiceFound(NsdServiceInfo service) { nsdManager.stopServiceDiscovery(this); } - resolveService(service, callbackHandle, contextHandle, chipMdnsCallback, timeoutRunnable); + resolveService(service, callbackHandle, contextHandle, chipMdnsCallback); } else { Log.d(TAG, "onServiceFound: found service not a target for resolution, ignoring " + service); } @@ -113,8 +110,7 @@ private void resolveService( NsdServiceInfo serviceInfo, final long callbackHandle, final long contextHandle, - final ChipMdnsCallback chipMdnsCallback, - Runnable timeoutRunnable) { + final ChipMdnsCallback chipMdnsCallback) { this.nsdManager.resolveService( serviceInfo, new NsdManager.ResolveListener() { @@ -145,7 +141,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { nsdManagerResolverAvailState.signalFree(); } } - mainThreadHandler.removeCallbacks(timeoutRunnable); + resolveTimeoutExecutor.cancel(false); } @Override @@ -181,7 +177,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { nsdManagerResolverAvailState.signalFree(); } } - mainThreadHandler.removeCallbacks(timeoutRunnable); + resolveTimeoutExecutor.cancel(false); } }); }