Skip to content

Commit

Permalink
[Android] Fix discover Commissionable Device API issue when discovere…
Browse files Browse the repository at this point in the history
…d multiple devices (project-chip#32459)

* Fix Android Commissionable Device API when searched multiple devices

* Fix Android Commissionable Device API when searched multiple devices

* Fix from comment, fix edge case issue

* Restyled by google-java-format

---------

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
joonhaengHeo and restyled-commits authored Mar 12, 2024
1 parent a31de1d commit 9a947d8
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ object ChipClient {
AndroidBleManager(context),
PreferencesKeyValueStoreManager(context),
PreferencesConfigurationManager(context),
NsdManagerServiceResolver(context),
NsdManagerServiceResolver(
context,
NsdManagerServiceResolver.NsdManagerResolverAvailState()
),
NsdManagerServiceBrowser(context),
ChipMdnsCallbackImpl(),
DiagnosticDataProviderImpl(context)
Expand Down
3 changes: 2 additions & 1 deletion src/controller/AbstractDnssdDiscoveryController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ void AbstractDnssdDiscoveryController::OnNodeDiscovered(const chip::Dnssd::Disco
continue;
}
if (strcmp(discoveredNode.resolutionData.hostName, nodeData.resolutionData.hostName) == 0 &&
discoveredNode.resolutionData.port == nodeData.resolutionData.port)
discoveredNode.resolutionData.port == nodeData.resolutionData.port &&
discoveredNode.resolutionData.ipAddress == nodeData.resolutionData.ipAddress)
{
discoveredNode = nodeData;
if (mDeviceDiscoveryDelegate != nullptr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Long, NsdManagerDiscovery> 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());

Expand All @@ -46,6 +55,7 @@ public NsdManagerServiceBrowser(Context context) {
.createMulticastLock("chipBrowseMulticastLock");
this.multicastLock.setReferenceCounted(true);
callbackMap = new HashMap<>();
this.timeout = timeout;
}

@Override
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@
import android.net.nsd.NsdServiceInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Expand All @@ -38,30 +39,38 @@ public class NsdManagerServiceResolver implements ServiceResolver {
private static final long RESOLVE_SERVICE_TIMEOUT = 30000;
private final NsdManager nsdManager;
private MulticastLock multicastLock;
private Handler mainThreadHandler;
private List<NsdManager.RegistrationListener> registrationListeners = new ArrayList<>();
private final CopyOnWriteArrayList<String> 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
Expand All @@ -82,6 +91,10 @@ public void resolve(
+ serviceType
+ "'");

if (nsdManagerResolverAvailState != null) {
nsdManagerResolverAvailState.acquireResolver();
}

Runnable timeoutRunnable =
new Runnable() {
@Override
Expand All @@ -92,28 +105,29 @@ 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,
serviceInfo,
callbackHandle,
contextHandle,
chipMdnsCallback,
timeoutRunnable,
multicastLock,
mainThreadHandler,
resolveTimeoutExecutor,
nsdManagerResolverAvailState);
serviceFinderResolver.start();

mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.Handler;
import android.util.Log;
import androidx.annotation.Nullable;
import java.util.concurrent.Executors;
Expand All @@ -38,9 +37,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;
Expand All @@ -53,18 +51,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;
}

Expand Down Expand Up @@ -101,16 +97,9 @@ public void onServiceFound(NsdServiceInfo service) {

if (stopDiscoveryRunnable.cancel(false)) {
nsdManager.stopServiceDiscovery(this);
if (multicastLock.isHeld()) {
multicastLock.release();
}
}

if (nsdManagerResolverAvailState != null) {
nsdManagerResolverAvailState.acquireResolver();
}

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);
}
Expand All @@ -120,8 +109,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() {
Expand Down Expand Up @@ -152,7 +140,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
nsdManagerResolverAvailState.signalFree();
}
}
mainThreadHandler.removeCallbacks(timeoutRunnable);
resolveTimeoutExecutor.cancel(false);
}

@Override
Expand Down Expand Up @@ -188,7 +176,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) {
nsdManagerResolverAvailState.signalFree();
}
}
mainThreadHandler.removeCallbacks(timeoutRunnable);
resolveTimeoutExecutor.cancel(false);
}
});
}
Expand Down

0 comments on commit 9a947d8

Please sign in to comment.