Skip to content

Commit 9a947d8

Browse files
[Android] Fix discover Commissionable Device API issue when discovered 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 <commits@restyled.io>
1 parent a31de1d commit 9a947d8

File tree

5 files changed

+51
-35
lines changed

5 files changed

+51
-35
lines changed

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ object ChipClient {
7474
AndroidBleManager(context),
7575
PreferencesKeyValueStoreManager(context),
7676
PreferencesConfigurationManager(context),
77-
NsdManagerServiceResolver(context),
77+
NsdManagerServiceResolver(
78+
context,
79+
NsdManagerServiceResolver.NsdManagerResolverAvailState()
80+
),
7881
NsdManagerServiceBrowser(context),
7982
ChipMdnsCallbackImpl(),
8083
DiagnosticDataProviderImpl(context)

src/controller/AbstractDnssdDiscoveryController.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ void AbstractDnssdDiscoveryController::OnNodeDiscovered(const chip::Dnssd::Disco
3535
continue;
3636
}
3737
if (strcmp(discoveredNode.resolutionData.hostName, nodeData.resolutionData.hostName) == 0 &&
38-
discoveredNode.resolutionData.port == nodeData.resolutionData.port)
38+
discoveredNode.resolutionData.port == nodeData.resolutionData.port &&
39+
discoveredNode.resolutionData.ipAddress == nodeData.resolutionData.ipAddress)
3940
{
4041
discoveredNode = nodeData;
4142
if (mDeviceDiscoveryDelegate != nullptr)

src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,19 @@ public class NsdManagerServiceBrowser implements ServiceBrowser {
3434
private final NsdManager nsdManager;
3535
private MulticastLock multicastLock;
3636
private Handler mainThreadHandler;
37+
private final long timeout;
3738

3839
private HashMap<Long, NsdManagerDiscovery> callbackMap;
3940

4041
public NsdManagerServiceBrowser(Context context) {
42+
this(context, BROWSE_SERVICE_TIMEOUT);
43+
}
44+
45+
/**
46+
* @param context application context
47+
* @param timeout Timeout value in case there is no response after calling browse
48+
*/
49+
public NsdManagerServiceBrowser(Context context, long timeout) {
4150
this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
4251
this.mainThreadHandler = new Handler(Looper.getMainLooper());
4352

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

5161
@Override
@@ -62,7 +72,7 @@ public void run() {
6272
}
6373
};
6474
startDiscover(serviceType, callbackHandle, contextHandle, chipMdnsCallback);
65-
mainThreadHandler.postDelayed(timeoutRunnable, BROWSE_SERVICE_TIMEOUT);
75+
mainThreadHandler.postDelayed(timeoutRunnable, timeout);
6676
}
6777

6878
public void startDiscover(

src/platform/android/java/chip/platform/NsdManagerServiceResolver.java

+27-13
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222
import android.net.nsd.NsdServiceInfo;
2323
import android.net.wifi.WifiManager;
2424
import android.net.wifi.WifiManager.MulticastLock;
25-
import android.os.Handler;
26-
import android.os.Looper;
2725
import android.util.Log;
2826
import androidx.annotation.Nullable;
2927
import java.util.ArrayList;
3028
import java.util.List;
3129
import java.util.concurrent.CopyOnWriteArrayList;
30+
import java.util.concurrent.Executors;
31+
import java.util.concurrent.ScheduledFuture;
32+
import java.util.concurrent.TimeUnit;
3233
import java.util.concurrent.locks.Condition;
3334
import java.util.concurrent.locks.Lock;
3435
import java.util.concurrent.locks.ReentrantLock;
@@ -38,30 +39,38 @@ public class NsdManagerServiceResolver implements ServiceResolver {
3839
private static final long RESOLVE_SERVICE_TIMEOUT = 30000;
3940
private final NsdManager nsdManager;
4041
private MulticastLock multicastLock;
41-
private Handler mainThreadHandler;
4242
private List<NsdManager.RegistrationListener> registrationListeners = new ArrayList<>();
4343
private final CopyOnWriteArrayList<String> mMFServiceName = new CopyOnWriteArrayList<>();
4444
@Nullable private final NsdManagerResolverAvailState nsdManagerResolverAvailState;
45+
private final long timeout;
4546

4647
/**
4748
* @param context application context
4849
* @param nsdManagerResolverAvailState Passing NsdManagerResolverAvailState allows
4950
* NsdManagerServiceResolver to synchronize on the usage of NsdManager's resolveService() API
51+
* @param timeout Timeout value in case there is no response after calling resolve
5052
*/
5153
public NsdManagerServiceResolver(
52-
Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState) {
54+
Context context,
55+
@Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState,
56+
long timeout) {
5357
this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
54-
this.mainThreadHandler = new Handler(Looper.getMainLooper());
5558

5659
this.multicastLock =
5760
((WifiManager) context.getSystemService(Context.WIFI_SERVICE))
5861
.createMulticastLock("chipMulticastLock");
5962
this.multicastLock.setReferenceCounted(true);
6063
this.nsdManagerResolverAvailState = nsdManagerResolverAvailState;
64+
this.timeout = timeout;
6165
}
6266

6367
public NsdManagerServiceResolver(Context context) {
64-
this(context, null);
68+
this(context, null, RESOLVE_SERVICE_TIMEOUT);
69+
}
70+
71+
public NsdManagerServiceResolver(
72+
Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState) {
73+
this(context, nsdManagerResolverAvailState, RESOLVE_SERVICE_TIMEOUT);
6574
}
6675

6776
@Override
@@ -82,6 +91,10 @@ public void resolve(
8291
+ serviceType
8392
+ "'");
8493

94+
if (nsdManagerResolverAvailState != null) {
95+
nsdManagerResolverAvailState.acquireResolver();
96+
}
97+
8598
Runnable timeoutRunnable =
8699
new Runnable() {
87100
@Override
@@ -92,28 +105,29 @@ public void run() {
92105
Log.d(TAG, "resolve: Timing out");
93106
if (multicastLock.isHeld()) {
94107
multicastLock.release();
108+
}
95109

96-
if (nsdManagerResolverAvailState != null) {
97-
nsdManagerResolverAvailState.signalFree();
98-
}
110+
if (nsdManagerResolverAvailState != null) {
111+
nsdManagerResolverAvailState.signalFree();
99112
}
100113
}
101114
};
102115

116+
ScheduledFuture<?> resolveTimeoutExecutor =
117+
Executors.newSingleThreadScheduledExecutor()
118+
.schedule(timeoutRunnable, timeout, TimeUnit.MILLISECONDS);
119+
103120
NsdServiceFinderAndResolver serviceFinderResolver =
104121
new NsdServiceFinderAndResolver(
105122
this.nsdManager,
106123
serviceInfo,
107124
callbackHandle,
108125
contextHandle,
109126
chipMdnsCallback,
110-
timeoutRunnable,
111127
multicastLock,
112-
mainThreadHandler,
128+
resolveTimeoutExecutor,
113129
nsdManagerResolverAvailState);
114130
serviceFinderResolver.start();
115-
116-
mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT);
117131
}
118132

119133
@Override

src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java

+7-19
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import android.net.nsd.NsdManager;
2222
import android.net.nsd.NsdServiceInfo;
2323
import android.net.wifi.WifiManager.MulticastLock;
24-
import android.os.Handler;
2524
import android.util.Log;
2625
import androidx.annotation.Nullable;
2726
import java.util.concurrent.Executors;
@@ -38,9 +37,8 @@ class NsdServiceFinderAndResolver implements NsdManager.DiscoveryListener {
3837
private final long callbackHandle;
3938
private final long contextHandle;
4039
private final ChipMdnsCallback chipMdnsCallback;
41-
private final Runnable timeoutRunnable;
4240
private final MulticastLock multicastLock;
43-
private final Handler mainThreadHandler;
41+
private final ScheduledFuture<?> resolveTimeoutExecutor;
4442

4543
@Nullable
4644
private final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState;
@@ -53,18 +51,16 @@ public NsdServiceFinderAndResolver(
5351
final long callbackHandle,
5452
final long contextHandle,
5553
final ChipMdnsCallback chipMdnsCallback,
56-
final Runnable timeoutRunnable,
5754
final MulticastLock multicastLock,
58-
final Handler mainThreadHandler,
55+
final ScheduledFuture<?> resolveTimeoutExecutor,
5956
final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState) {
6057
this.nsdManager = nsdManager;
6158
this.targetServiceInfo = targetServiceInfo;
6259
this.callbackHandle = callbackHandle;
6360
this.contextHandle = contextHandle;
6461
this.chipMdnsCallback = chipMdnsCallback;
65-
this.timeoutRunnable = timeoutRunnable;
6662
this.multicastLock = multicastLock;
67-
this.mainThreadHandler = mainThreadHandler;
63+
this.resolveTimeoutExecutor = resolveTimeoutExecutor;
6864
this.nsdManagerResolverAvailState = nsdManagerResolverAvailState;
6965
}
7066

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

10298
if (stopDiscoveryRunnable.cancel(false)) {
10399
nsdManager.stopServiceDiscovery(this);
104-
if (multicastLock.isHeld()) {
105-
multicastLock.release();
106-
}
107100
}
108101

109-
if (nsdManagerResolverAvailState != null) {
110-
nsdManagerResolverAvailState.acquireResolver();
111-
}
112-
113-
resolveService(service, callbackHandle, contextHandle, chipMdnsCallback, timeoutRunnable);
102+
resolveService(service, callbackHandle, contextHandle, chipMdnsCallback);
114103
} else {
115104
Log.d(TAG, "onServiceFound: found service not a target for resolution, ignoring " + service);
116105
}
@@ -120,8 +109,7 @@ private void resolveService(
120109
NsdServiceInfo serviceInfo,
121110
final long callbackHandle,
122111
final long contextHandle,
123-
final ChipMdnsCallback chipMdnsCallback,
124-
Runnable timeoutRunnable) {
112+
final ChipMdnsCallback chipMdnsCallback) {
125113
this.nsdManager.resolveService(
126114
serviceInfo,
127115
new NsdManager.ResolveListener() {
@@ -152,7 +140,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
152140
nsdManagerResolverAvailState.signalFree();
153141
}
154142
}
155-
mainThreadHandler.removeCallbacks(timeoutRunnable);
143+
resolveTimeoutExecutor.cancel(false);
156144
}
157145

158146
@Override
@@ -188,7 +176,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) {
188176
nsdManagerResolverAvailState.signalFree();
189177
}
190178
}
191-
mainThreadHandler.removeCallbacks(timeoutRunnable);
179+
resolveTimeoutExecutor.cancel(false);
192180
}
193181
});
194182
}

0 commit comments

Comments
 (0)