diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java index 0fda34fa7a7b84..5ff612685c515b 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java @@ -107,6 +107,18 @@ public void handle(MatterError matterError) { } }; + Button discoverButton = getView().findViewById(R.id.discoverButton); + discoverButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "Discovering on button click"); + tvCastingApp.discoverVideoPlayerCommissioners( + DISCOVERY_DURATION_SECS, successCallback, failureCallback); + } + }); + + Log.d(TAG, "Auto discovering"); tvCastingApp.discoverVideoPlayerCommissioners( DISCOVERY_DURATION_SECS, successCallback, failureCallback); } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdDiscoveryListener.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdDiscoveryListener.java index e58f639965bf4f..b0644c456cabe9 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdDiscoveryListener.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdDiscoveryListener.java @@ -71,7 +71,8 @@ public void onServiceFound(NsdServiceInfo service) { preCommissionedVideoPlayers, successCallback, failureCallback, - nsdManagerResolverAvailState)); + nsdManagerResolverAvailState, + 1)); } else { Log.d(TAG, "Ignoring discovered service: " + service.toString()); } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdResolveListener.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdResolveListener.java index 3232ed8e16a6ea..1593ab10cbcbfd 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdResolveListener.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/NsdResolveListener.java @@ -22,17 +22,23 @@ import android.util.Log; import chip.platform.NsdManagerServiceResolver; import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; public class NsdResolveListener implements NsdManager.ResolveListener { private static final String TAG = NsdResolveListener.class.getSimpleName(); + private static final int MAX_RESOLUTION_ATTEMPTS = 5; + private static final int RESOLUTION_ATTEMPT_DELAY_SECS = 1; + private final NsdManager nsdManager; private final List deviceTypeFilter; private final List preCommissionedVideoPlayers; private final SuccessCallback successCallback; private final FailureCallback failureCallback; private final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState; + private final int resolutionAttemptNumber; public NsdResolveListener( NsdManager nsdManager, @@ -40,7 +46,8 @@ public NsdResolveListener( List preCommissionedVideoPlayers, SuccessCallback successCallback, FailureCallback failureCallback, - NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState) { + NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState, + int resolutionAttemptNumber) { this.nsdManager = nsdManager; this.deviceTypeFilter = deviceTypeFilter; this.preCommissionedVideoPlayers = preCommissionedVideoPlayers; @@ -52,6 +59,7 @@ public NsdResolveListener( this.successCallback = successCallback; this.failureCallback = failureCallback; this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; + this.resolutionAttemptNumber = resolutionAttemptNumber; } @Override @@ -77,15 +85,41 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { if (nsdManagerResolverAvailState != null) { - nsdManagerResolverAvailState.signalFree(); + if (errorCode != NsdManager.FAILURE_ALREADY_ACTIVE + || resolutionAttemptNumber >= MAX_RESOLUTION_ATTEMPTS) { + nsdManagerResolverAvailState.signalFree(); + } } switch (errorCode) { case NsdManager.FAILURE_ALREADY_ACTIVE: Log.e(TAG, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo); - failureCallback.handle( - new MatterError( - 3, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo)); + if (resolutionAttemptNumber < MAX_RESOLUTION_ATTEMPTS) { + Log.d(TAG, "NsdResolveListener Scheduling a retry to resolve service " + serviceInfo); + Executors.newSingleThreadScheduledExecutor() + .schedule( + new Runnable() { + @Override + public void run() { + nsdManager.resolveService( + serviceInfo, + new NsdResolveListener( + nsdManager, + deviceTypeFilter, + preCommissionedVideoPlayers, + successCallback, + failureCallback, + nsdManagerResolverAvailState, + resolutionAttemptNumber + 1)); + } + }, + RESOLUTION_ATTEMPT_DELAY_SECS, + TimeUnit.SECONDS); + } else { // giving up + failureCallback.handle( + new MatterError( + 3, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo)); + } break; case NsdManager.FAILURE_INTERNAL_ERROR: Log.e(TAG, "NsdResolveListener FAILURE_INTERNAL_ERROR - Service: " + serviceInfo); diff --git a/examples/tv-casting-app/android/App/app/src/main/res/layout/fragment_commissioner_discovery.xml b/examples/tv-casting-app/android/App/app/src/main/res/layout/fragment_commissioner_discovery.xml index 58238b506cf8b0..c65a647957b28e 100644 --- a/examples/tv-casting-app/android/App/app/src/main/res/layout/fragment_commissioner_discovery.xml +++ b/examples/tv-casting-app/android/App/app/src/main/res/layout/fragment_commissioner_discovery.xml @@ -20,6 +20,12 @@ android:layout_height="wrap_content" android:text="Skip to manual commissioning >>" /> +