diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java index 7bef7c1117f0b4..1597a935ed7cc4 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java @@ -43,15 +43,9 @@ public class TvCastingApp { private static final List DISCOVERY_TARGET_DEVICE_TYPE_FILTER = Arrays.asList(35L); // Video player = 35; - // cached players that were seen before this window (in days) will not be surfaced as "discovered" - private static final long CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_DAYS = 7; - - // delay before which we assume remaining cached players may be in STR mode + // delay before which we assume undiscovered cached players may be in STR mode private static final long CHIP_DEVICE_CONFIG_STR_DISCOVERY_DELAY_SEC = 5; - // time assumed to be required for player to wake up after sending WoL magic packet - private static final long CHIP_DEVICE_CONFIG_STR_WAKE_UP_DELAY_SEC = 10; - private static TvCastingApp sInstance; private Context applicationContext; private ChipAppServer chipAppServer; @@ -200,34 +194,57 @@ private void reportSleepingCommissioners( SuccessCallback discoverySuccessCallback) { Log.d( TAG, - "reportSleepingCommissioners called with commissioner count " + "TvCastingApp.reportSleepingCommissioners called with commissioner count " + (cachedVideoPlayers != null ? cachedVideoPlayers.size() : 0)); if (cachedVideoPlayers != null) { for (VideoPlayer player : cachedVideoPlayers) { Log.d(TAG, "Cached Video Player: " + player); - // report a player if we got its MAC address previously and it was recently discoverable - // (but not now) - if (player.getMACAddress() != null - /* TODO: add a recency check - && player.getLastDiscoveredMs() - > System.currentTimeMillis() - - STR_CACHE_LAST_DISCOVERED_DAYS * 24 * 60 * 60 * 1000*/ ) { - boolean activelyDiscovered = - discoveredPlayers - .stream() - .anyMatch( - new Predicate() { - @Override - public boolean test(DiscoveredNodeData discoveredNodeData) { - return player.getHostName().equals(discoveredNodeData.getHostName()); - } - }); - if (!activelyDiscovered) { - Log.d(TAG, "Reporting sleeping player"); - player.setIsAsleep(true); - discoverySuccessCallback.handle(new DiscoveredNodeData(player)); - } + // do NOT surface this cached Player if we don't have its MACAddress + if (player.getMACAddress() == null) { + Log.d( + TAG, + "TvCastingApp.reportSleepingCommissioners Skipping Player with hostName" + + player.getHostName() + + " but no MACAddress"); + continue; + } + + // do NOT surface this cached Player if it has not been discoverable recently (in + // CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_HOURS) + if (!WasRecentlyDiscoverable(player)) { + Log.d( + TAG, + "TvCastingApp.reportSleepingCommissioners Skipping Player with hostName" + + player.getHostName() + + " that has not been discovered recently"); + continue; } + + // do NOT surface this cached Player if it was just discovered right now (in this discovery + // call) + boolean justDiscovered = + discoveredPlayers + .stream() + .anyMatch( + new Predicate() { + @Override + public boolean test(DiscoveredNodeData discoveredNodeData) { + return player.getHostName().equals(discoveredNodeData.getHostName()); + } + }); + if (justDiscovered) { + Log.d( + TAG, + "TvCastingApp.reportSleepingCommissioners Skipping Player with hostName" + + player.getHostName() + + " that was just discovered"); + continue; + } + + // DO surface this cached Player (as asleep) + Log.d(TAG, "Reporting sleeping player with hostName " + player.getHostName()); + player.setIsAsleep(true); + discoverySuccessCallback.handle(new DiscoveredNodeData(player)); } } } @@ -274,6 +291,8 @@ public native boolean openBasicCommissioningWindow( public native List readCachedVideoPlayers(); + private native boolean WasRecentlyDiscoverable(VideoPlayer player); + /*public boolean verifyOrEstablishConnection( VideoPlayer targetVideoPlayer, SuccessCallback onConnectionSuccess, diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp index ba56ae2b3fcaa5..5d4e95789c5e81 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp @@ -282,6 +282,25 @@ JNI_METHOD(jboolean, _1verifyOrEstablishConnection) return (err == CHIP_NO_ERROR); } +JNI_METHOD(jboolean, WasRecentlyDiscoverable) +(JNIEnv * env, jobject, jobject videoPlayer) +{ + chip::DeviceLayer::StackLock lock; + + ChipLogProgress(AppServer, "JNI_METHOD WasRecentlyDiscoverable called"); + + TargetVideoPlayerInfo targetVideoPlayerInfo; + CHIP_ERROR err = convertJVideoPlayerToTargetVideoPlayerInfo(videoPlayer, targetVideoPlayerInfo); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(AppServer, + "Conversion from jobject VideoPlayer to TargetVideoPlayerInfo * failed: %" CHIP_ERROR_FORMAT, + err.Format())); + return targetVideoPlayerInfo.WasRecentlyDiscoverable(); + +exit: + return false; // default to false +} + /*JNI_METHOD(jboolean, _1sendWakeOnLan) (JNIEnv * env, jobject, jobject videoPlayer) { diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CommissionerDiscoveryDelegateImpl.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CommissionerDiscoveryDelegateImpl.h index 984be998ea2ed1..e5cc681a291e9d 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CommissionerDiscoveryDelegateImpl.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CommissionerDiscoveryDelegateImpl.h @@ -79,32 +79,52 @@ class CommissionerDiscoveryDelegateImpl : public chip::Controller::DeviceDiscove CommissionerDiscoveryDelegateImpl * thiz = (CommissionerDiscoveryDelegateImpl *) context; if (thiz != nullptr && thiz->mCachedTargetVideoPlayerInfos != nullptr) { for (size_t i = 0; i < kMaxCachedVideoPlayers && thiz->mCachedTargetVideoPlayerInfos[i].IsInitialized(); i++) { - // check if there is a MACAddress to wake this Video Player up with - if (thiz->mCachedTargetVideoPlayerInfos[i].GetMACAddress() != nullptr - && thiz->mCachedTargetVideoPlayerInfos[i].GetMACAddress()->size() > 0) { - bool discovered = false; - // check if it was already discovered - for (DiscoveredNodeData * discoveredCommissioner : thiz->mDiscoveredCommissioners) { - if (strcmp((char *) [discoveredCommissioner.hostName UTF8String], - thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()) - == 0) { - discovered = true; - break; - } - } + // do NOT surface this cached Player if we don't have its MACAddress + if (thiz->mCachedTargetVideoPlayerInfos[i].GetMACAddress() == nullptr + && thiz->mCachedTargetVideoPlayerInfos[i].GetMACAddress()->size() == 0) { + ChipLogProgress(NotSpecified, + "CommissionerDiscoveryDelegateImpl().ReportSleepingCommissioners() Skipping Player with hostName %s but no " + "MACAddress", + thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()); + continue; + } - // surface the *sleeping* video player as a DiscoveredNodeData - if (!discovered) { - DiscoveredNodeData * objCDiscoveredNodeData = - [ConversionUtils convertToDiscoveredNodeDataFrom:&thiz->mCachedTargetVideoPlayerInfos[i]]; - objCDiscoveredNodeData.getConnectableVideoPlayer.isAsleep = true; + // do NOT surface this cached Player if it has not been discoverable recently + if (!thiz->mCachedTargetVideoPlayerInfos[i].WasRecentlyDiscoverable()) { + ChipLogProgress(NotSpecified, + "CommissionerDiscoveryDelegateImpl().ReportSleepingCommissioners() Skipping Player with hostName %s that " + "has not been discovered recently", + thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()); + continue; + } - // make the callback - ChipLogProgress(AppServer, - "CommissionerDiscoveryDelegateImpl().ReportSleepingCommissioners() reporting sleeping video player"); - thiz->mObjCDiscoveredCommissionerHandler(objCDiscoveredNodeData); + // do NOT surface this cached Player if it was just discovered right now (in this discovery call) + bool justDiscovered = false; + for (DiscoveredNodeData * discoveredCommissioner : thiz->mDiscoveredCommissioners) { + if (strcmp((char *) [discoveredCommissioner.hostName UTF8String], + thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()) + == 0) { + justDiscovered = true; + break; } } + if (justDiscovered) { + ChipLogProgress(NotSpecified, + "CommissionerDiscoveryDelegateImpl().ReportSleepingCommissioners() Skipping Player with hostName %s that " + "was just discovered", + thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()); + continue; + } + + // DO surface this cached Player (as asleep) + DiscoveredNodeData * objCDiscoveredNodeData = + [ConversionUtils convertToDiscoveredNodeDataFrom:&thiz->mCachedTargetVideoPlayerInfos[i]]; + objCDiscoveredNodeData.getConnectableVideoPlayer.isAsleep = true; + ChipLogProgress(AppServer, + "CommissionerDiscoveryDelegateImpl().ReportSleepingCommissioners() reporting sleeping video player with " + "hostName %s", + thiz->mCachedTargetVideoPlayerInfos[i].GetHostName()); + thiz->mObjCDiscoveredCommissionerHandler(objCDiscoveredNodeData); } } } diff --git a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h index f483486cd7e605..6cd1dc8a9ebfd8 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h +++ b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h @@ -65,10 +65,10 @@ #define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT 4 -// cached players that were seen before this window (in days) will not be surfaced as "discovered" -#define CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_DAYS 60L +// cached players that were seen before this window (in hours) will not be surfaced as "discovered" +#define CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_HOURS 7 * 24L -// delay before which we assume remaining cached players may be in STR mode +// delay before which we assume undiscovered cached players may be in STR mode #define CHIP_DEVICE_CONFIG_STR_DISCOVERY_DELAY_SEC 5 // time assumed to be required for player to wake up after sending WoL magic packet diff --git a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h index 09264276e81090..d48a854f4189de 100644 --- a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h +++ b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h @@ -88,18 +88,35 @@ class TargetVideoPlayerInfo bool IsSameAs(const chip::Dnssd::DiscoveredNodeData * discoveredNodeData); bool IsSameAs(const char * hostName, const char * deviceName, size_t numIPs, const chip::Inet::IPAddress * ipAddresses); - chip::System::Clock::Timestamp GetLastDiscovered() { return mLastDiscovered; } uint16_t GetPort() const { return mPort; } const char * GetInstanceName() const { return mInstanceName; } chip::CharSpan * GetMACAddress() { return &mMACAddress; } void SetIsAsleep(bool isAsleep) { mIsAsleep = isAsleep; } bool IsAsleep() { return mIsAsleep; } - void SetLastDiscovered(chip::System::Clock::Timestamp lastDiscovered) { mLastDiscovered = lastDiscovered; } void SetMACAddress(chip::CharSpan MACAddress) { memcpy(mMACAddressBuf, MACAddress.data(), MACAddress.size()); mMACAddress = chip::CharSpan(mMACAddressBuf, MACAddress.size()); } + chip::System::Clock::Timestamp GetLastDiscovered() + { + ChipLogProgress(NotSpecified, " TargetVideoPlayerInfo GetLastDiscovered %lu", + static_cast(mLastDiscovered.count())); + return mLastDiscovered; + } + void SetLastDiscovered(chip::System::Clock::Timestamp lastDiscovered) + { + mLastDiscovered = lastDiscovered; + ChipLogProgress(NotSpecified, " TargetVideoPlayerInfo SetLastDiscovered %lu", + static_cast(mLastDiscovered.count())); + } + bool WasRecentlyDiscoverable() + { + // it was recently discoverable if its mLastDiscovered.count is within CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_HOURS of + // current time + return mLastDiscovered.count() > chip::System::SystemClock().GetMonotonicMilliseconds64().count() - + CHIP_DEVICE_CONFIG_STR_CACHE_LAST_DISCOVERED_HOURS * 60 * 60 * 1000; + } chip::OperationalDeviceProxy * GetOperationalDeviceProxy() {