From 70be7827171e52139a726534bca0b32584d9ec72 Mon Sep 17 00:00:00 2001 From: Sharad Binjola Date: Thu, 13 Oct 2022 13:55:02 -0700 Subject: [PATCH] iOS/TvCasting app: Cache/recall/re-target previously connected VideoPlayers/Endpoints --- .../project.pbxproj | 28 +- .../CastingServerBridge.h | 314 +++++++--- .../CastingServerBridge.mm | 579 ++++++++++++++---- ...eredNodeDataConverter.hpp => ContentApp.h} | 32 +- .../MatterTvCastingBridge/ContentApp.mm | 80 +++ .../MatterTvCastingBridge/ConversionUtils.hpp | 56 ++ .../MatterTvCastingBridge/ConversionUtils.mm | 149 +++++ .../DiscoveredNodeDataConverter.mm | 58 -- .../MatterTvCastingBridge/VideoPlayer.h | 61 ++ .../MatterTvCastingBridge/VideoPlayer.m | 59 ++ .../TvCasting.xcodeproj/project.pbxproj | 40 +- .../TvCasting/CommissionerDiscoveryView.swift | 4 +- .../TvCasting/CommissioningView.swift | 32 +- .../TvCasting/CommissioningViewModel.swift | 43 +- .../TvCasting/TvCasting/ConnectionView.swift | 78 +++ .../TvCasting/ConnectionViewModel.swift | 63 ++ .../TvCasting/ContentLauncherView.swift | 93 ++- .../TvCasting/ContentLauncherViewModel.swift | 46 +- .../TvCasting/TvCasting/ContentView.swift | 3 +- .../TvCasting/MediaPlaybackView.swift | 105 ++++ .../TvCasting/MediaPlaybackViewModel.swift | 120 ++++ .../TvCasting/TvCasting/MediaPlayerView.swift | 76 --- .../TvCasting/MediaPlayerViewModel.swift | 77 --- .../TvCasting/StartFromCacheView.swift | 74 +++ .../TvCasting/StartFromCacheViewModel.swift | 38 ++ .../tv-casting-app/linux/CastingUtils.cpp | 6 +- .../tv-casting-common/include/CastingServer.h | 7 +- .../tv-casting-common/include/MediaBase.h | 2 +- .../include/TargetVideoPlayerInfo.h | 4 +- 29 files changed, 1827 insertions(+), 500 deletions(-) rename examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/{DiscoveredNodeDataConverter.hpp => ContentApp.h} (53%) create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.hpp create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.mm delete mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.m create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionView.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionViewModel.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackView.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackViewModel.swift delete mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift delete mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheView.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheViewModel.swift diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj index 0a4ab42cb3c900..b03d64304cf41e 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj @@ -11,15 +11,17 @@ 3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */; }; 3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */; }; 3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */; }; + 3C81C74C28F7A777001CB9D1 /* ContentApp.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C74B28F7A777001CB9D1 /* ContentApp.mm */; }; + 3C81C75028F7A7D3001CB9D1 /* VideoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C74F28F7A7D3001CB9D1 /* VideoPlayer.m */; }; 3CCB87212869085400771BAD /* MatterTvCastingBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB87202869085400771BAD /* MatterTvCastingBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3CCB8737286A555500771BAD /* libTvCastingCommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CCB8735286A555500771BAD /* libTvCastingCommon.a */; }; 3CCB8738286A555500771BAD /* libmbedtls.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CCB8736286A555500771BAD /* libmbedtls.a */; settings = {ATTRIBUTES = (Required, ); }; }; 3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB8739286A593700771BAD /* DiscoveredNodeData.mm */; }; 3CCB8740286A593700771BAD /* CastingServerBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873A286A593700771BAD /* CastingServerBridge.h */; }; 3CCB8741286A593700771BAD /* DiscoveredNodeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873B286A593700771BAD /* DiscoveredNodeData.h */; }; - 3CCB8742286A593700771BAD /* DiscoveredNodeDataConverter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */; }; + 3CCB8742286A593700771BAD /* ConversionUtils.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873C286A593700771BAD /* ConversionUtils.hpp */; }; 3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873D286A593700771BAD /* CastingServerBridge.mm */; }; - 3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */; }; + 3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* ConversionUtils.mm */; }; 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF8532628E37F1000F07B9F /* MatterError.mm */; }; /* End PBXBuildFile section */ @@ -31,6 +33,10 @@ 3C4E53B328E5185F00F293E8 /* TargetNavigatorTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TargetNavigatorTypes.h; sourceTree = ""; }; 3C4E53B428E5593700F293E8 /* ContentLauncherTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentLauncherTypes.h; sourceTree = ""; }; 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentLauncherTypes.mm; sourceTree = ""; }; + 3C81C74B28F7A777001CB9D1 /* ContentApp.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentApp.mm; sourceTree = ""; }; + 3C81C74E28F7A7AE001CB9D1 /* ContentApp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentApp.h; sourceTree = ""; }; + 3C81C74F28F7A7D3001CB9D1 /* VideoPlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VideoPlayer.m; sourceTree = ""; }; + 3C81C75128F7A7DF001CB9D1 /* VideoPlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VideoPlayer.h; sourceTree = ""; }; 3CA1CA7728E243750023ED44 /* MediaPlaybackTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTypes.h; sourceTree = ""; }; 3CCB871D2869085400771BAD /* MatterTvCastingBridge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MatterTvCastingBridge.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3CCB87202869085400771BAD /* MatterTvCastingBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterTvCastingBridge.h; sourceTree = ""; }; @@ -39,9 +45,9 @@ 3CCB8739286A593700771BAD /* DiscoveredNodeData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DiscoveredNodeData.mm; sourceTree = ""; }; 3CCB873A286A593700771BAD /* CastingServerBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CastingServerBridge.h; sourceTree = ""; }; 3CCB873B286A593700771BAD /* DiscoveredNodeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscoveredNodeData.h; sourceTree = ""; }; - 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiscoveredNodeDataConverter.hpp; sourceTree = ""; }; + 3CCB873C286A593700771BAD /* ConversionUtils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConversionUtils.hpp; sourceTree = ""; }; 3CCB873D286A593700771BAD /* CastingServerBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CastingServerBridge.mm; sourceTree = ""; }; - 3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DiscoveredNodeDataConverter.mm; sourceTree = ""; }; + 3CCB873E286A593700771BAD /* ConversionUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConversionUtils.mm; sourceTree = ""; }; 3CF8532528E37ED800F07B9F /* MatterError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterError.h; sourceTree = ""; }; 3CF8532628E37F1000F07B9F /* MatterError.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MatterError.mm; sourceTree = ""; }; /* End PBXFileReference section */ @@ -85,10 +91,14 @@ 3CCB873D286A593700771BAD /* CastingServerBridge.mm */, 3CCB873B286A593700771BAD /* DiscoveredNodeData.h */, 3CCB8739286A593700771BAD /* DiscoveredNodeData.mm */, - 3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */, - 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */, + 3CCB873C286A593700771BAD /* ConversionUtils.hpp */, + 3CCB873E286A593700771BAD /* ConversionUtils.mm */, 3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */, 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */, + 3C81C74E28F7A7AE001CB9D1 /* ContentApp.h */, + 3C81C74B28F7A777001CB9D1 /* ContentApp.mm */, + 3C81C75128F7A7DF001CB9D1 /* VideoPlayer.h */, + 3C81C74F28F7A7D3001CB9D1 /* VideoPlayer.m */, 3CF8532528E37ED800F07B9F /* MatterError.h */, 3CF8532628E37F1000F07B9F /* MatterError.mm */, 3C4E53B428E5593700F293E8 /* ContentLauncherTypes.h */, @@ -109,7 +119,7 @@ buildActionMask = 2147483647; files = ( 3CCB8740286A593700771BAD /* CastingServerBridge.h in Headers */, - 3CCB8742286A593700771BAD /* DiscoveredNodeDataConverter.hpp in Headers */, + 3CCB8742286A593700771BAD /* ConversionUtils.hpp in Headers */, 3CCB8741286A593700771BAD /* DiscoveredNodeData.h in Headers */, 3CCB87212869085400771BAD /* MatterTvCastingBridge.h in Headers */, ); @@ -208,9 +218,11 @@ 3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */, 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */, 3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */, - 3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */, + 3C81C75028F7A7D3001CB9D1 /* VideoPlayer.m in Sources */, + 3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */, 3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */, 3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */, + 3C81C74C28F7A777001CB9D1 /* ContentApp.mm in Sources */, 3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h index 6d43a0d280c659..f828ae5f01c70f 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h @@ -15,12 +15,14 @@ * limitations under the License. */ +#import "ContentApp.h" #import "ContentLauncherTypes.h" #import "DiscoveredNodeData.h" #import "MatterError.h" #import "MediaPlaybackTypes.h" #import "OnboardingPayload.h" #import "TargetNavigatorTypes.h" +#import "VideoPlayer.h" #import #ifndef CastingServerBridge_h @@ -72,6 +74,19 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue udcRequestSentHandler:(nullable void (^)(bool))udcRequestSentHandler; +/*! + @brief Send a User Directed Commissioning request to a commissioner TV + + @param commissioner Commissioner to request commissioning from + + @param clientQueue Queue to dispatch the call to the udcRequestSentHandler on + + @param udcRequestSentHandler Handler to call on sending the User Directed Commissioning request + */ +- (void)sendUserDirectedCommissioningRequest:(DiscoveredNodeData * _Nonnull)commissioner + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + udcRequestSentHandler:(nullable void (^)(bool))udcRequestSentHandler; + /*! @brief Return the onboarding payload for this app (setup passcode, discriminator) @@ -82,31 +97,87 @@ /*! @brief Request opening of a basic commissioning window + @param clientQueue Queue to dispatch the call to the commissioningWindowRequestedHandler on + @param commissioningCompleteCallback Callback for when commissioning of this app has been completed via a call to the general commissioning cluster (by usually an on-network TV/Media device acting as a Matter commissioner) - @param clientQueue Queue to dispatch the call to the commissioningWindowRequestedHandler on + @param onConnectionSuccessCallback Handles a VideoPlayer * once connection is successfully established + + @param onConnectionFailureCallback Handles MatterError if there is a failure in establishing connection + + @param onNewOrUpdatedEndpointCallback Handles a ContentApp * for each new ContentApp is found. May be called multiple times based + on the number of ContentApp @param commissioningWindowRequestedHandler Handler to call on requesting the opening of a commissioning window */ -- (void)openBasicCommissioningWindow:(void (^_Nonnull)(bool))commissioningCompleteCallback - clientQueue:(dispatch_queue_t _Nonnull)clientQueue - commissioningWindowRequestedHandler:(void (^_Nonnull)(bool))commissioningWindowRequestedHandler; +- (void)openBasicCommissioningWindow:(dispatch_queue_t _Nonnull)clientQueue + commissioningWindowRequestedHandler:(void (^_Nonnull)(bool))commissioningWindowRequestedHandler + commissioningCompleteCallback:(void (^_Nonnull)(bool))commissioningCompleteCallback + onConnectionSuccessCallback:(void (^_Nonnull)(VideoPlayer * _Nonnull))onConnectionSuccessCallback + onConnectionFailureCallback:(void (^_Nonnull)(MatterError * _Nonnull))onConnectionFailureCallback + onNewOrUpdatedEndpointCallback:(void (^_Nonnull)(ContentApp * _Nonnull))onNewOrUpdatedEndpointCallback; + +/*! + @brief Gets the list of VideoPlayers currently connected + + @param clientQueue Queue to invoke callbacks on + + @param activeTargetVideoPlayersHandler Handles NSMutableArray of active/currently connected VideoPlayers. Nil, if no such + VideoPlayers are found. + */ +- (void)getActiveTargetVideoPlayers:(dispatch_queue_t _Nonnull)clientQueue + activeTargetVideoPlayersHandler:(nullable void (^)(NSMutableArray * _Nullable))activeTargetVideoPlayersHandler; + +/*! + @brief Reads all previously connected video players from cache. These are not connected. + + @param clientQueue Queue to invoke callbacks on + + @param readCachedVideoPlayersHandler Handles NSMutableArray of VideoPlayers from the cache. Empty, if no such VideoPlayers are + found. + */ +- (void)readCachedVideoPlayers:(dispatch_queue_t _Nonnull)clientQueue + readCachedVideoPlayersHandler:(nullable void (^)(NSMutableArray * _Nullable))readCachedVideoPlayersHandler; + +/*! + @brief Verify if a connection exists or connect to the VideoPlayer passed in as parameter. + + @param clientQueue Queue to invoke callbacks on + + @param requestSentHandler Handles MatterError and called after the request has been sent + + @param onConnectionSuccessCallback Handles a VideoPlayer * once connection is successfully established + + @param onConnectionFailureCallback Handles MatterError if there is a failure in establishing connection + + @param onNewOrUpdatedEndpointCallback Handles a ContentApp * for each new ContentApp is found. May be called multiple times based + on the number of ContentApp + */ +- (void)verifyOrEstablishConnection:(VideoPlayer * _Nonnull)videoPlayer + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(nullable void (^)(MatterError * _Nonnull))requestSentHandler + onConnectionSuccessCallback:(void (^_Nonnull)(VideoPlayer * _Nonnull))onConnectionSuccessCallback + onConnectionFailureCallback:(void (^_Nonnull)(MatterError * _Nonnull))onConnectionFailureCallback + onNewOrUpdatedEndpointCallback:(void (^_Nonnull)(ContentApp * _Nonnull))onNewOrUpdatedEndpointCallback; /*! @brief Send a ContentLauncher:LaunchURL request to a TV + @param contentApp Content app endpoint to target + @param contentUrl URL of the content to launch on the TV @param contentDisplayStr Display string value corresponding to the content @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl +- (void)contentLauncher_launchUrl:(ContentApp * _Nonnull)contentApp + contentUrl:(NSString * _Nonnull)contentUrl contentDisplayStr:(NSString * _Nonnull)contentDisplayStr responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue @@ -115,6 +186,8 @@ /*! @brief Send a ContentLauncher:LaunchContent request to a TV + @param contentApp Content app endpoint to target + @param contentSearch Indicates the content to launch @param autoPlay Play Best match automatically if true, otherwise display matches @@ -123,11 +196,12 @@ @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull)contentSearch +- (void)contentLauncher_launchContent:(ContentApp * _Nonnull)contentApp + contentSearch:(ContentLauncher_ContentSearch * _Nonnull)contentSearch autoPlay:(bool)autoPlay data:(NSString * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback @@ -137,11 +211,13 @@ /*! @brief Subscribe to ContentLauncher:SupportedStreamingProtocols + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -151,7 +227,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval +- (void)contentLauncher_subscribeSupportedStreamingProtocols:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -162,6 +239,8 @@ /*! @brief Send a LevelControl:Step request to a TV + @param contentApp Content app endpoint to target + @param stepMode Increase (0x00) or Decrease (0x01) the device’s level @param stepSize Number of units to step the device's level by @@ -174,11 +253,12 @@ @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)levelControl_step:(uint8_t)stepMode +- (void)levelControl_step:(ContentApp * _Nonnull)contentApp + stepMode:(uint8_t)stepMode stepSize:(uint8_t)stepSize transitionTime:(uint16_t)transitionTime optionMask:(uint8_t)optionMask @@ -190,6 +270,8 @@ /*! @brief Send a LevelControl:MoveToLevel request to a TV + @param contentApp Content app endpoint to target + @param level the level to which the device should move @param transitionTime Time that SHALL be taken to perform the step, in tenths of a second @@ -200,11 +282,12 @@ @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)levelControl_moveToLevel:(uint8_t)level +- (void)levelControl_moveToLevel:(ContentApp * _Nonnull)contentApp + level:(uint8_t)level transitionTime:(uint16_t)transitionTime optionMask:(uint8_t)optionMask optionOverride:(uint8_t)optionOverride @@ -215,11 +298,13 @@ /*! @brief Subscribe to LevelControl:CurrentLevel + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -229,7 +314,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval +- (void)levelControl_subscribeCurrentLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -240,11 +326,13 @@ /*! @brief Subscribe to LevelControl:MinLevel + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -254,7 +342,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval +- (void)levelControl_subscribeMinLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -265,11 +354,13 @@ /*! @brief Subscribe to LevelControl:MaxLevel + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -279,7 +370,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval +- (void)levelControl_subscribeMaxLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -290,67 +382,82 @@ /*! @brief Send a MediaPlayback:Play request to a TV + @param contentApp Content app endpoint to target + @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_play:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_play:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; /*! @brief Send a MediaPlayback:Pause request to a TV + @param contentApp Content app endpoint to target + @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_pause:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_pause:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; /*! @brief Send a MediaPlayback:StopPlayback request to a TV + @param contentApp Content app endpoint to target + @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_stopPlayback:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_stopPlayback:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; /*! @brief Send a MediaPlayback:Next request to a TV + @param contentApp Content app endpoint to target + @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_next:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_next:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; /*! @brief Send a MediaPlayback:Seek request to a TV + @param contentApp Content app endpoint to target + @param position the position (in milliseconds) in the media to seek to @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_seek:(uint8_t)position +- (void)mediaPlayback_seek:(ContentApp * _Nonnull)contentApp + position:(uint8_t)position responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; @@ -358,15 +465,18 @@ /*! @brief Send a MediaPlayback:SkipForward request to a TV + @param contentApp Content app endpoint to target + @param deltaPositionMilliseconds the duration of the time span to skip forward in the media, in milliseconds @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_skipForward:(uint64_t)deltaPositionMilliseconds +- (void)mediaPlayback_skipForward:(ContentApp * _Nonnull)contentApp + deltaPositionMilliseconds:(uint64_t)deltaPositionMilliseconds responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; @@ -374,15 +484,18 @@ /*! @brief Send a MediaPlayback:SkipBackward request to a TV + @param contentApp Content app endpoint to target + @param deltaPositionMilliseconds the duration of the time span to skip backward in the media, in milliseconds @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds +- (void)mediaPlayback_skipBackward:(ContentApp * _Nonnull)contentApp + deltaPositionMilliseconds:(uint64_t)deltaPositionMilliseconds responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; @@ -390,11 +503,13 @@ /*! @brief Subscribe to MediaPlayback:CurrentState + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -404,7 +519,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval +- (void)mediaPlayback_subscribeCurrentState:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -415,11 +531,13 @@ /*! @brief Subscribe to MediaPlayback:StartTime + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -429,7 +547,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval +- (void)mediaPlayback_subscribeStartTime:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -440,11 +559,13 @@ /*! @brief Subscribe to MediaPlayback:Duration + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -454,7 +575,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval +- (void)mediaPlayback_subscribeDuration:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -465,11 +587,13 @@ /*! @brief Subscribe to MediaPlayback:SampledPosition + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -479,7 +603,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSampledPosition:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -490,11 +615,13 @@ /*! @brief Subscribe to MediaPlayback:PlaybackSpeed + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -504,7 +631,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval +- (void)mediaPlayback_subscribePlaybackSpeed:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -515,11 +643,13 @@ /*! @brief Subscribe to MediaPlayback:SeekRangeEnd + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -529,7 +659,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSeekRangeEnd:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -540,11 +671,13 @@ /*! @brief Subscribe to MediaPlayback:SeekRangeStart + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -554,7 +687,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSeekRangeStart:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -564,6 +698,8 @@ /*! @brief Send a ApplicationLauncher:LaunchApp request to a TV + @param contentApp Content app endpoint to target + @param catalogVendorId CSA-issued vendor ID for the catalog @param applicationId application identifier, unique within a catalog, expressed as a string, such as "PruneVideo" or "Company X" @@ -572,11 +708,12 @@ @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_launchApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId data:(NSData * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback @@ -586,17 +723,20 @@ /*! @brief Send a ApplicationLauncher:StopApp request to a TV + @param contentApp Content app endpoint to target + @param catalogVendorId CSA-issued vendor ID for the catalog @param applicationId application identifier, unique within a catalog, expressed as a string, such as "PruneVideo" or "Company X" @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_stopApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue @@ -605,17 +745,20 @@ /*! @brief Send a ApplicationLauncher:HideApp request to a TV + @param contentApp Content app endpoint to target + @param catalogVendorId CSA-issued vendor ID for the catalog @param applicationId application identifier, unique within a catalog, expressed as a string, such as "PruneVideo" or "Company X" @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_hideApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue @@ -624,6 +767,8 @@ /*! @brief Send a TargetNavigator:NavigateTarget request to a TV + @param contentApp Content app endpoint to target + @param target Identifier for the target for UX navigation, contained within one of the TargetInfo objects in the TargetList attribute list. @@ -631,11 +776,12 @@ @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)targetNavigator_navigateTarget:(uint8_t)target +- (void)targetNavigator_navigateTarget:(ContentApp * _Nonnull)contentApp + target:(uint8_t)target data:(NSString * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue @@ -644,11 +790,13 @@ /*! @brief Subscribe to TargetNavigator:TargetList + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -658,7 +806,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval +- (void)targetNavigator_subscribeTargetList:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -669,11 +818,13 @@ /*! @brief Subscribe to TargetNavigator:CurrentTarget + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -683,7 +834,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval +- (void)targetNavigator_subscribeCurrentTarget:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -694,17 +846,20 @@ /*! @brief Send a KeypadInput:SendKey request to a TV + @param contentApp Content app endpoint to target + @param keyCode Key Code to process. If a second SendKey request with the same KeyCode value is received within 200ms, then the endpoint will consider the first key press to be a press and hold. When such a repeat KeyCode value is not received within 200ms, then the endpoint will consider the last key press to be a release. @param responseCallback Callback for when the response has been received - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request */ -- (void)keypadInput_sendKey:(uint8_t)keyCode +- (void)keypadInput_sendKey:(ContentApp * _Nonnull)contentApp + keyCode:(uint8_t)keyCode responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; @@ -712,11 +867,13 @@ /*! @brief Subscribe to ApplicationBasic:VendorName + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -726,7 +883,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval +- (void)applicationBasic_subscribeVendorName:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -737,11 +895,13 @@ /*! @brief Subscribe to ApplicationBasic:VendorID + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -751,7 +911,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval +- (void)applicationBasic_subscribeVendorID:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -762,11 +923,13 @@ /*! @brief Subscribe to ApplicationBasic:ApplicationName + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -776,7 +939,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval +- (void)applicationBasic_subscribeApplicationName:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -787,11 +951,13 @@ /*! @brief Subscribe to ApplicationBasic:ProductID + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -801,7 +967,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval +- (void)applicationBasic_subscribeProductID:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -812,11 +979,13 @@ /*! @brief Subscribe to ApplicationBasic:ApplicationVersion + @param contentApp Content app endpoint to target + @param minInterval Minimum interval between attribute read reports @param maxInterval Maximum interval between attribute read reports - @param clientQueue Queue to dispatch the call to the requestSentHandler on + @param clientQueue Queue to invoke callbacks on @param requestSentHandler Handler to call on sending the request @@ -826,7 +995,8 @@ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully */ -- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval +- (void)applicationBasic_subscribeApplicationVersion:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm index c690e49af7ef7c..59a44a76756e46 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm @@ -18,7 +18,7 @@ #import "CastingServerBridge.h" #import "CastingServer.h" -#import "DiscoveredNodeDataConverter.hpp" +#import "ConversionUtils.hpp" #import "MatterCallbacks.h" #import "OnboardingPayload.h" @@ -40,6 +40,12 @@ @interface CastingServerBridge () @property void (^_Nonnull commissioningCompleteCallback)(bool); +@property void (^_Nonnull onConnectionSuccessCallback)(VideoPlayer *); + +@property void (^_Nonnull onConnectionFailureCallback)(MatterError *); + +@property void (^_Nonnull onNewOrUpdatedEndpointCallback)(ContentApp *); + @property NSMutableDictionary * commandResponseCallbacks; @property NSMutableDictionary * subscriptionEstablishedCallbacks; @@ -148,10 +154,10 @@ - (void)getDiscoveredCommissioner:(int)index dispatch_async(_chipWorkQueue, ^{ DiscoveredNodeData * commissioner = nil; - const chip::Dnssd::DiscoveredNodeData * chipDiscoveredNodeData + const chip::Dnssd::DiscoveredNodeData * cppDiscoveredNodeData = CastingServer::GetInstance()->GetDiscoveredCommissioner(index); - if (chipDiscoveredNodeData != nullptr) { - commissioner = [DiscoveredNodeDataConverter convertToObjC:chipDiscoveredNodeData]; + if (cppDiscoveredNodeData != nullptr) { + commissioner = [ConversionUtils convertToObjCDiscoveredNodeDataFrom:cppDiscoveredNodeData]; } dispatch_async(clientQueue, ^{ @@ -198,21 +204,81 @@ - (void)sendUserDirectedCommissioningRequest:(NSString * _Nonnull)commissionerIp }); } +- (void)sendUserDirectedCommissioningRequest:(DiscoveredNodeData * _Nonnull)commissioner + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + udcRequestSentHandler:(nullable void (^)(bool))udcRequestSentHandler +{ + ChipLogProgress(AppServer, + "CastingServerBridge().sendUserDirectedCommissioningRequest() called with IP %s port %d platformInterface %d deviceName: " + "%s", + [commissioner.ipAddresses[0] UTF8String], commissioner.port, commissioner.platformInterface, + [commissioner.deviceName UTF8String]); + + dispatch_async(_chipWorkQueue, ^{ + bool udcRequestStatus; + + chip::Dnssd::DiscoveredNodeData cppCommissioner; + if ([ConversionUtils convertToCppDiscoveredNodeDataFrom:commissioner outDiscoveredNodeData:cppCommissioner] + != CHIP_NO_ERROR) { + ChipLogError(AppServer, + "CastingServerBridge().sendUserDirectedCommissioningRequest() failed to convert Commissioner(DiscoveredNodeData) " + "to Cpp type"); + udcRequestStatus = false; + } else { + CHIP_ERROR err = CastingServer::GetInstance()->SendUserDirectedCommissioningRequest(&cppCommissioner); + if (err != CHIP_NO_ERROR) { + ChipLogError(AppServer, "CastingServerBridge().sendUserDirectedCommissioningRequest() failed: %" CHIP_ERROR_FORMAT, + err.Format()); + udcRequestStatus = false; + } else { + udcRequestStatus = true; + } + } + + dispatch_async(clientQueue, ^{ + udcRequestSentHandler(udcRequestStatus); + }); + }); +} + - (OnboardingPayload *)getOnboardingPaylod { return _onboardingPayload; } -- (void)openBasicCommissioningWindow:(void (^_Nonnull)(bool))commissioningCompleteCallback - clientQueue:(dispatch_queue_t _Nonnull)clientQueue +- (void)openBasicCommissioningWindow:(dispatch_queue_t _Nonnull)clientQueue commissioningWindowRequestedHandler:(void (^_Nonnull)(bool))commissioningWindowRequestedHandler + commissioningCompleteCallback:(void (^_Nonnull)(bool))commissioningCompleteCallback + onConnectionSuccessCallback:(void (^_Nonnull)(VideoPlayer * _Nonnull))onConnectionSuccessCallback + onConnectionFailureCallback:(void (^_Nonnull)(MatterError * _Nonnull))onConnectionFailureCallback + onNewOrUpdatedEndpointCallback:(void (^_Nonnull)(ContentApp * _Nonnull))onNewOrUpdatedEndpointCallback { ChipLogProgress(AppServer, "CastingServerBridge().openBasicCommissioningWindow() called"); _commissioningCompleteCallback = commissioningCompleteCallback; + _onConnectionSuccessCallback = onConnectionSuccessCallback; + _onConnectionFailureCallback = onConnectionFailureCallback; + _onNewOrUpdatedEndpointCallback = onNewOrUpdatedEndpointCallback; + + CHIP_ERROR OpenBasicCommissioningWindow(std::function commissioningCompleteCallback, + std::function onConnectionSuccess, std::function onConnectionFailure, + std::function onNewOrUpdatedEndpoint); + dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->OpenBasicCommissioningWindow( - [](CHIP_ERROR err) { [CastingServerBridge getSharedInstance].commissioningCompleteCallback(CHIP_NO_ERROR == err); }); + [](CHIP_ERROR err) { [CastingServerBridge getSharedInstance].commissioningCompleteCallback(CHIP_NO_ERROR == err); }, + [](TargetVideoPlayerInfo * cppTargetVideoPlayerInfo) { + VideoPlayer * videoPlayer = [ConversionUtils convertToObjCVideoPlayerFrom:cppTargetVideoPlayerInfo]; + [CastingServerBridge getSharedInstance].onConnectionSuccessCallback(videoPlayer); + }, + [](CHIP_ERROR err) { + [CastingServerBridge getSharedInstance].onConnectionFailureCallback( + [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + [](TargetEndpointInfo * cppTargetEndpointInfo) { + ContentApp * contentApp = [ConversionUtils convertToObjCContentAppFrom:cppTargetEndpointInfo]; + [CastingServerBridge getSharedInstance].onNewOrUpdatedEndpointCallback(contentApp); + }); dispatch_async(clientQueue, ^{ commissioningWindowRequestedHandler(CHIP_NO_ERROR == err); @@ -220,19 +286,105 @@ - (void)openBasicCommissioningWindow:(void (^_Nonnull)(bool))commissioningComple }); } -- (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl +- (void)getActiveTargetVideoPlayers:(dispatch_queue_t _Nonnull)clientQueue + activeTargetVideoPlayersHandler:(nullable void (^)(NSMutableArray * _Nullable))activeTargetVideoPlayersHandler +{ + ChipLogProgress(AppServer, "CastingServerBridge().getActiveTargetVideoPlayers() called"); + + dispatch_async(_chipWorkQueue, ^{ + NSMutableArray * videoPlayers = nil; + TargetVideoPlayerInfo * cppTargetVideoPlayerInfo = CastingServer::GetInstance()->GetActiveTargetVideoPlayer(); + if (cppTargetVideoPlayerInfo != nullptr) { + videoPlayers = [NSMutableArray new]; + videoPlayers[0] = [ConversionUtils convertToObjCVideoPlayerFrom:cppTargetVideoPlayerInfo]; + } + + dispatch_async(clientQueue, ^{ + activeTargetVideoPlayersHandler(videoPlayers); + }); + }); +} + +- (void)readCachedVideoPlayers:(dispatch_queue_t _Nonnull)clientQueue + readCachedVideoPlayersHandler:(nullable void (^)(NSMutableArray * _Nullable))readCachedVideoPlayersHandler +{ + ChipLogProgress(AppServer, "CastingServerBridge().readCachedVideoPlayers() called"); + + dispatch_async(_chipWorkQueue, ^{ + NSMutableArray * videoPlayers = nil; + TargetVideoPlayerInfo * cppTargetVideoPlayerInfos = CastingServer::GetInstance()->ReadCachedTargetVideoPlayerInfos(); + if (cppTargetVideoPlayerInfos != nullptr) { + videoPlayers = [NSMutableArray new]; + for (size_t i = 0; cppTargetVideoPlayerInfos[i].IsInitialized(); i++) { + ChipLogProgress(AppServer, + "CastingServerBridge().readCachedVideoPlayers() with nodeId: %lu fabricIndex: %d deviceName: %s vendorId: %d", + cppTargetVideoPlayerInfos[i].GetNodeId(), cppTargetVideoPlayerInfos[i].GetFabricIndex(), + cppTargetVideoPlayerInfos[i].GetDeviceName(), cppTargetVideoPlayerInfos[i].GetVendorId()); + videoPlayers[i] = [ConversionUtils convertToObjCVideoPlayerFrom:&cppTargetVideoPlayerInfos[i]]; + } + } + + dispatch_async(clientQueue, ^{ + readCachedVideoPlayersHandler(videoPlayers); + }); + }); +} + +- (void)verifyOrEstablishConnection:(VideoPlayer * _Nonnull)videoPlayer + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(nullable void (^)(MatterError * _Nonnull))requestSentHandler + onConnectionSuccessCallback:(void (^_Nonnull)(VideoPlayer * _Nonnull))onConnectionSuccessCallback + onConnectionFailureCallback:(void (^_Nonnull)(MatterError * _Nonnull))onConnectionFailureCallback + onNewOrUpdatedEndpointCallback:(void (^_Nonnull)(ContentApp * _Nonnull))onNewOrUpdatedEndpointCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().verifyOrEstablishConnection() called"); + _onConnectionSuccessCallback = onConnectionSuccessCallback; + _onConnectionFailureCallback = onConnectionFailureCallback; + _onNewOrUpdatedEndpointCallback = onNewOrUpdatedEndpointCallback; + + dispatch_async(_chipWorkQueue, ^{ + TargetVideoPlayerInfo targetVideoPlayerInfo; + [ConversionUtils convertToCppTargetVideoPlayerInfoFrom:videoPlayer outTargetVideoPlayerInfo:targetVideoPlayerInfo]; + + CHIP_ERROR err = CastingServer::GetInstance()->VerifyOrEstablishConnection( + targetVideoPlayerInfo, + [](TargetVideoPlayerInfo * cppTargetVideoPlayerInfo) { + VideoPlayer * videoPlayer = [ConversionUtils convertToObjCVideoPlayerFrom:cppTargetVideoPlayerInfo]; + [CastingServerBridge getSharedInstance].onConnectionSuccessCallback(videoPlayer); + }, + [](CHIP_ERROR err) { + [CastingServerBridge getSharedInstance].onConnectionFailureCallback( + [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + [](TargetEndpointInfo * cppTargetEndpointInfo) { + ContentApp * contentApp = [ConversionUtils convertToObjCContentAppFrom:cppTargetEndpointInfo]; + [CastingServerBridge getSharedInstance].onNewOrUpdatedEndpointCallback(contentApp); + }); + + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)contentLauncher_launchUrl:(ContentApp * _Nonnull)contentApp + contentUrl:(NSString * _Nonnull)contentUrl contentDisplayStr:(NSString * _Nonnull)contentDisplayStr responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchUrl() called"); + ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchUrl() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchUrl"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncherLaunchURL( - [contentUrl UTF8String], [contentDisplayStr UTF8String], [](CHIP_ERROR err) { + &endpoint, [contentUrl UTF8String], [contentDisplayStr UTF8String], [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"contentLauncher_launchUrl"]; responseCallback(CHIP_NO_ERROR == err); @@ -243,14 +395,16 @@ - (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl }); } -- (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull)contentSearch +- (void)contentLauncher_launchContent:(ContentApp * _Nonnull)contentApp + contentSearch:(ContentLauncher_ContentSearch * _Nonnull)contentSearch autoPlay:(bool)autoPlay data:(NSString * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchContent() called"); + ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchContent() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchContent"]; @@ -259,6 +413,9 @@ - (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull) data = [data copy]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + ListFreer listFreer; chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type cppSearch; if (contentSearch.parameterList.count > 0) { @@ -301,7 +458,7 @@ - (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull) } } - CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_LaunchContent(cppSearch, autoPlay, + CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_LaunchContent(&endpoint, cppSearch, autoPlay, MakeOptional(chip::CharSpan([data UTF8String], [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding])), [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks @@ -314,7 +471,8 @@ - (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull) }); } -- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval +- (void)contentLauncher_subscribeSupportedStreamingProtocols:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -322,7 +480,9 @@ - (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterv failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_subscribeSupportedStreamingProtocols() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().contentLauncher_subscribeSupportedStreamingProtocols() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; @@ -330,8 +490,11 @@ - (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterv forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_SubscribeToSupportedStreamingProtocols( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo::DecodableArgType supportedStreamingProtocols) { @@ -357,7 +520,8 @@ - (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterv }); } -- (void)levelControl_step:(uint8_t)stepMode +- (void)levelControl_step:(ContentApp * _Nonnull)contentApp + stepMode:(uint8_t)stepMode stepSize:(uint8_t)stepSize transitionTime:(uint16_t)transitionTime optionMask:(uint8_t)optionMask @@ -366,24 +530,29 @@ - (void)levelControl_step:(uint8_t)stepMode clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().levelControl_step() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().levelControl_step() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"levelControl_step"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err - = CastingServer::GetInstance()->LevelControl_Step(static_cast(stepMode), - stepSize, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) { - void (^responseCallback)(bool) = - [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_step"]; - responseCallback(CHIP_NO_ERROR == err); - }); + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_Step(&endpoint, + static_cast(stepMode), stepSize, transitionTime, optionMask, + optionOverride, [](CHIP_ERROR err) { + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_step"]; + responseCallback(CHIP_NO_ERROR == err); + }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); }); }); } -- (void)levelControl_moveToLevel:(uint8_t)level +- (void)levelControl_moveToLevel:(ContentApp * _Nonnull)contentApp + level:(uint8_t)level transitionTime:(uint16_t)transitionTime optionMask:(uint8_t)optionMask optionOverride:(uint8_t)optionOverride @@ -391,12 +560,16 @@ - (void)levelControl_moveToLevel:(uint8_t)level clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().levelControl_moveToLevel() called"); + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_moveToLevel() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"levelControl_moveToLevel"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_MoveToLevel( - level, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) { + &endpoint, level, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_moveToLevel"]; responseCallback(CHIP_NO_ERROR == err); @@ -407,7 +580,8 @@ - (void)levelControl_moveToLevel:(uint8_t)level }); } -- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval +- (void)levelControl_subscribeCurrentLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -415,15 +589,20 @@ - (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeCurrentLevel() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().levelControl_subscribeCurrentLevel() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeCurrentLevel"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeCurrentLevel"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeCurrentLevel"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToCurrentLevel( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType currentLevel) { void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -448,7 +627,8 @@ - (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval }); } -- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval +- (void)levelControl_subscribeMinLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -456,15 +636,19 @@ - (void)levelControl_subscribeMinLevel:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMinLevel() called"); + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMinLevel() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMinLevel"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMinLevel"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMinLevel"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMinLevel( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType minLevel) { void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"levelControl_subscribeMinLevel"]; @@ -488,7 +672,8 @@ - (void)levelControl_subscribeMinLevel:(uint16_t)minInterval }); } -- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval +- (void)levelControl_subscribeMaxLevel:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -496,15 +681,19 @@ - (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMaxLevel() called"); + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMaxLevel() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMaxLevel"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMaxLevel"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMaxLevel"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMaxLevel( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType maxLevel) { void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"levelControl_subscribeMaxLevel"]; @@ -528,15 +717,20 @@ - (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval }); } -- (void)mediaPlayback_play:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_play:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_play() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().mediaPlayback_play() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_play"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Play([](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Play(&endpoint, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_play"]; responseCallback(CHIP_NO_ERROR == err); @@ -547,15 +741,20 @@ - (void)mediaPlayback_play:(void (^_Nonnull)(bool))responseCallback }); } -- (void)mediaPlayback_pause:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_pause:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_pause() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().mediaPlayback_pause() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_pause"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Pause([](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Pause(&endpoint, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_pause"]; responseCallback(CHIP_NO_ERROR == err); @@ -566,15 +765,20 @@ - (void)mediaPlayback_pause:(void (^_Nonnull)(bool))responseCallback }); } -- (void)mediaPlayback_stopPlayback:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_stopPlayback:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_stopPlayback() called"); + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_stopPlayback() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_stopPlayback"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_StopPlayback([](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_StopPlayback(&endpoint, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_stopPlayback"]; responseCallback(CHIP_NO_ERROR == err); @@ -585,15 +789,20 @@ - (void)mediaPlayback_stopPlayback:(void (^_Nonnull)(bool))responseCallback }); } -- (void)mediaPlayback_next:(void (^_Nonnull)(bool))responseCallback +- (void)mediaPlayback_next:(ContentApp * _Nonnull)contentApp + responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_next() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().mediaPlayback_next() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_next"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Next([](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Next(&endpoint, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_next"]; responseCallback(CHIP_NO_ERROR == err); @@ -604,16 +813,21 @@ - (void)mediaPlayback_next:(void (^_Nonnull)(bool))responseCallback }); } -- (void)mediaPlayback_seek:(uint8_t)position +- (void)mediaPlayback_seek:(ContentApp * _Nonnull)contentApp + position:(uint8_t)position responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_seek() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().mediaPlayback_seek() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_seek"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Seek(position, [](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Seek(&endpoint, position, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_seek"]; responseCallback(CHIP_NO_ERROR == err); @@ -624,47 +838,60 @@ - (void)mediaPlayback_seek:(uint8_t)position }); } -- (void)mediaPlayback_skipForward:(uint64_t)deltaPositionMilliseconds +- (void)mediaPlayback_skipForward:(ContentApp * _Nonnull)contentApp + deltaPositionMilliseconds:(uint64_t)deltaPositionMilliseconds responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipForward() called"); + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipForward() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipForward"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipForward(deltaPositionMilliseconds, [](CHIP_ERROR err) { - void (^responseCallback)(bool) = - [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipForward"]; - responseCallback(CHIP_NO_ERROR == err); - }); + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err + = CastingServer::GetInstance()->MediaPlayback_SkipForward(&endpoint, deltaPositionMilliseconds, [](CHIP_ERROR err) { + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipForward"]; + responseCallback(CHIP_NO_ERROR == err); + }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); }); }); } -- (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds +- (void)mediaPlayback_skipBackward:(ContentApp * _Nonnull)contentApp + deltaPositionMilliseconds:(uint64_t)deltaPositionMilliseconds responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipBackward() called"); + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipBackward() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipBackward"]; dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipBackward(deltaPositionMilliseconds, [](CHIP_ERROR err) { - void (^responseCallback)(bool) = - [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipBackward"]; - responseCallback(CHIP_NO_ERROR == err); - }); + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err + = CastingServer::GetInstance()->MediaPlayback_SkipBackward(&endpoint, deltaPositionMilliseconds, [](CHIP_ERROR err) { + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipBackward"]; + responseCallback(CHIP_NO_ERROR == err); + }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); }); }); } -- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval +- (void)mediaPlayback_subscribeCurrentState:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -672,15 +899,20 @@ - (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeCurrentState() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().mediaPlayback_subscribeCurrentState() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeCurrentState"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeCurrentState"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeCurrentState"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType currentState) { void (^callback)(MediaPlayback_PlaybackState) = @@ -706,7 +938,8 @@ - (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval +- (void)mediaPlayback_subscribeStartTime:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -714,15 +947,19 @@ - (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeStartTime() called"); + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeStartTime() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeStartTime"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeStartTime"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeStartTime"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToStartTime( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType startTime) { void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"mediaPlayback_subscribeStartTime"]; @@ -746,7 +983,8 @@ - (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval +- (void)mediaPlayback_subscribeDuration:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -754,15 +992,19 @@ - (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeDuration() called"); + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeDuration() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeDuration"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeDuration"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeDuration"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType startTime) { void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"mediaPlayback_subscribeDuration"]; @@ -786,7 +1028,8 @@ - (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSampledPosition:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -794,15 +1037,20 @@ - (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSampledPosition() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().mediaPlayback_subscribeSampledPosition() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToSampledPosition( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType playbackPosition) { void (^callback)(MediaPlayback_PlaybackPosition * _Nullable) = @@ -840,7 +1088,8 @@ - (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval +- (void)mediaPlayback_subscribePlaybackSpeed:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -848,15 +1097,20 @@ - (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribePlaybackSpeed() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().mediaPlayback_subscribePlaybackSpeed() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToPlaybackSpeed( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType playbackSpeed) { void (^callback)(float) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -881,7 +1135,8 @@ - (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSeekRangeEnd:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -889,15 +1144,20 @@ - (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeEnd() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().mediaPlayback_subscribeSeekRangeEnd() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeEnd) { void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -922,7 +1182,8 @@ - (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval }); } -- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval +- (void)mediaPlayback_subscribeSeekRangeStart:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -930,15 +1191,20 @@ - (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeStart() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().mediaPlayback_subscribeSeekRangeStart() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeStart) { void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -963,14 +1229,16 @@ - (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval }); } -- (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_launchApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId data:(NSData * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_launchApp() called"); + ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_launchApp() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_launchApp"]; @@ -979,7 +1247,10 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId application.applicationId = chip::CharSpan::fromCharString([applicationId UTF8String]); dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_LaunchApp(application, + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_LaunchApp(&endpoint, application, chip::MakeOptional(chip::ByteSpan(static_cast(data.bytes), data.length)), [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_launchApp"]; @@ -991,13 +1262,15 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId }); } -- (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_stopApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_stopApp() called"); + ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_stopApp() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_stopApp"]; @@ -1006,7 +1279,10 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId application.applicationId = chip::CharSpan::fromCharString([applicationId UTF8String]); dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_StopApp(application, [](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_StopApp(&endpoint, application, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_stopApp"]; responseCallback(CHIP_NO_ERROR == err); @@ -1017,13 +1293,15 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId }); } -- (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId +- (void)applicationLauncher_hideApp:(ContentApp * _Nonnull)contentApp + catalogVendorId:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_hideApp() called"); + ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_hideApp() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_hideApp"]; @@ -1032,7 +1310,10 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId application.applicationId = chip::CharSpan::fromCharString([applicationId UTF8String]); dispatch_async(_chipWorkQueue, ^{ - CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_HideApp(application, [](CHIP_ERROR err) { + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_HideApp(&endpoint, application, [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_hideApp"]; responseCallback(CHIP_NO_ERROR == err); @@ -1043,19 +1324,24 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId }); } -- (void)targetNavigator_navigateTarget:(uint8_t)target +- (void)targetNavigator_navigateTarget:(ContentApp * _Nonnull)contentApp + target:(uint8_t)target data:(NSString * _Nullable)data responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_navigateTarget() called"); + ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_navigateTarget() called on Content App with endpoint ID %d", + contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"targetNavigator_navigateTarget"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_NavigateTarget( - target, chip::MakeOptional(chip::CharSpan::fromCharString([data UTF8String])), [](CHIP_ERROR err) { + &endpoint, target, chip::MakeOptional(chip::CharSpan::fromCharString([data UTF8String])), [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"targetNavigator_navigateTarget"]; responseCallback(CHIP_NO_ERROR == err); @@ -1066,7 +1352,8 @@ - (void)targetNavigator_navigateTarget:(uint8_t)target }); } -- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval +- (void)targetNavigator_subscribeTargetList:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1074,15 +1361,20 @@ - (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeTargetList() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().targetNavigator_subscribeTargetList() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeTargetList"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeTargetList"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeTargetList"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToTargetList( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType targetList) { void (^callback)(NSMutableArray *) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -1122,7 +1414,8 @@ - (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval }); } -- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval +- (void)targetNavigator_subscribeCurrentTarget:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1130,15 +1423,20 @@ - (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeCurrentTarget() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().targetNavigator_subscribeCurrentTarget() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToCurrentTarget( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType currentTarget) { void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -1163,18 +1461,23 @@ - (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval }); } -- (void)keypadInput_sendKey:(uint8_t)keyCode +- (void)keypadInput_sendKey:(ContentApp * _Nonnull)contentApp + keyCode:(uint8_t)keyCode responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { - ChipLogProgress(AppServer, "CastingServerBridge().keypadInput_sendKey() called"); + ChipLogProgress( + AppServer, "CastingServerBridge().keypadInput_sendKey() called on Content App with endpoint ID %d", contentApp.endpointId); [_commandResponseCallbacks setObject:responseCallback forKey:@"keypadInput_sendKey"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->KeypadInput_SendKey( - static_cast(keyCode), [](CHIP_ERROR err) { + &endpoint, static_cast(keyCode), [](CHIP_ERROR err) { void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"keypadInput_sendKey"]; responseCallback(CHIP_NO_ERROR == err); @@ -1185,7 +1488,8 @@ - (void)keypadInput_sendKey:(uint8_t)keyCode }); } -- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval +- (void)applicationBasic_subscribeVendorName:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1193,15 +1497,20 @@ - (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorName() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().applicationBasic_subscribeVendorName() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorName"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorName"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorName"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorName( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::VendorName::TypeInfo::DecodableArgType vendorName) { void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -1226,7 +1535,8 @@ - (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval }); } -- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval +- (void)applicationBasic_subscribeVendorID:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1234,15 +1544,20 @@ - (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorID() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().applicationBasic_subscribeVendorID() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorID"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorID"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorID"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorID( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::VendorID::TypeInfo::DecodableArgType vendorID) { void (^callback)(NSNumber * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"applicationBasic_subscribeVendorID"]; @@ -1266,7 +1581,8 @@ - (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval }); } -- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval +- (void)applicationBasic_subscribeApplicationName:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1274,7 +1590,9 @@ - (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationName() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().applicationBasic_subscribeApplicationName() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationName"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationName"]; @@ -1282,8 +1600,11 @@ - (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval forKey:@"applicationBasic_subscribeApplicationName"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationName( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::ApplicationName::TypeInfo::DecodableArgType applicationName) { void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks @@ -1308,7 +1629,8 @@ - (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval }); } -- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval +- (void)applicationBasic_subscribeProductID:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1316,15 +1638,20 @@ - (void)applicationBasic_subscribeProductID:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeProductID() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().applicationBasic_subscribeProductID() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeProductID"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeProductID"]; [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeProductID"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToProductID( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::ProductID::TypeInfo::DecodableArgType productID) { void (^callback)(uint16_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks objectForKey:@"applicationBasic_subscribeProductID"]; @@ -1348,7 +1675,8 @@ - (void)applicationBasic_subscribeProductID:(uint16_t)minInterval }); } -- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval +- (void)applicationBasic_subscribeApplicationVersion:(ContentApp * _Nonnull)contentApp + minInterval:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler @@ -1356,7 +1684,9 @@ - (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback { - ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationVersion() called"); + ChipLogProgress(AppServer, + "CastingServerBridge().applicationBasic_subscribeApplicationVersion() called on Content App with endpoint ID %d", + contentApp.endpointId); [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationVersion"]; [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationVersion"]; @@ -1364,8 +1694,11 @@ - (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval forKey:@"applicationBasic_subscribeApplicationVersion"]; dispatch_async(_chipWorkQueue, ^{ + TargetEndpointInfo endpoint; + [ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:endpoint]; + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationVersion( - nullptr, + &endpoint, nullptr, [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::TypeInfo::DecodableArgType applicationVersion) { diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.hpp b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.h similarity index 53% rename from examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.hpp rename to examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.h index 3833767bcae2c4..b9a7384b0a3f7e 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.hpp +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.h @@ -17,16 +17,34 @@ #import -#import "DiscoveredNodeData.h" -#include +#ifndef ContentApp_h +#define ContentApp_h -#ifndef DiscoveredNodeDataConverter_h -#define DiscoveredNodeDataConverter_h +@interface ContentApp : NSObject -@interface DiscoveredNodeDataConverter : NSObject +@property uint16_t endpointId; -+ (DiscoveredNodeData *)convertToObjC:(const chip::Dnssd::DiscoveredNodeData *)chipDiscoveredNodedata; +@property NSMutableArray * clusterIds; + +/** + @brief true, if all the fields are initialized, false otherwise + */ +@property BOOL isInitialized; + +- (instancetype)initWithEndpointId:(uint16_t)endpointId clusterIds:(NSMutableArray *)clusterIds; + +- (BOOL)supportsClusterWithId:(uint32_t)clusterId; + +- (BOOL)supportsApplicationLauncher; + +- (BOOL)supportsContentLauncher; + +- (BOOL)supportsMediaPlayback; + +- (BOOL)supportsLevelControl; + +- (BOOL)supportsTargetNavigator; @end -#endif /* DiscoveredNodeDataConverter_h */ +#endif /* ContentApp_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.mm new file mode 100644 index 00000000000000..5497224aabce2c --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentApp.mm @@ -0,0 +1,80 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "ContentApp.h" + +#include + +@implementation ContentApp + +- (instancetype)init +{ + if (self = [super init]) { + _isInitialized = false; + } + return self; +} + +- (instancetype)initWithEndpointId:(uint16_t)endpointId clusterIds:(NSMutableArray *)clusterIds +{ + if (self = [super init]) { + _endpointId = endpointId; + _clusterIds = clusterIds; + _isInitialized = true; + } + return self; +} + +- (BOOL)supportsClusterWithId:(uint32_t)clusterId +{ + if (_clusterIds != nil) { + for (NSNumber * clusterIdNSNumber in _clusterIds) { + if ([clusterIdNSNumber unsignedIntValue] == clusterId) { + return true; + } + } + } + return false; +} + +- (BOOL)supportsApplicationLauncher +{ + return [self supportsClusterWithId:chip::app::Clusters::ApplicationLauncher::Id]; +} + +- (BOOL)supportsContentLauncher +{ + return [self supportsClusterWithId:chip::app::Clusters::ContentLauncher::Id]; +} + +- (BOOL)supportsMediaPlayback +{ + return [self supportsClusterWithId:chip::app::Clusters::MediaPlayback::Id]; +} + +- (BOOL)supportsLevelControl +{ + return [self supportsClusterWithId:chip::app::Clusters::LevelControl::Id]; +} + +- (BOOL)supportsTargetNavigator +{ + return [self supportsClusterWithId:chip::app::Clusters::TargetNavigator::Id]; +} +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.hpp b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.hpp new file mode 100644 index 00000000000000..df6a0360816ce8 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.hpp @@ -0,0 +1,56 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "ContentApp.h" +#import "DiscoveredNodeData.h" +#import "VideoPlayer.h" + +#import +#import +#include + +#ifndef ConversionUtils_h +#define ConversionUtils_h + +@interface ConversionUtils : NSObject +/** + * @brief Objective C to C++ converters + */ ++ (CHIP_ERROR)convertToCppTargetEndpointInfoFrom:(ContentApp * _Nonnull)objCContentApp + outTargetEndpointInfo:(TargetEndpointInfo &)outTargetEndpointInfo; + ++ (CHIP_ERROR)convertToCppTargetVideoPlayerInfoFrom:(VideoPlayer * _Nonnull)objCVideoPlayer + outTargetVideoPlayerInfo:(TargetVideoPlayerInfo &)outTargetVideoPlayerInfo; + ++ (CHIP_ERROR)convertToCppDiscoveredNodeDataFrom:(DiscoveredNodeData * _Nonnull)objCDiscoveredNodeData + outDiscoveredNodeData:(chip::Dnssd::DiscoveredNodeData &)outDiscoveredNodeData; + +/** + * @brief C++ to Objective C converters + */ ++ (ContentApp * _Nonnull)convertToObjCContentAppFrom:(TargetEndpointInfo * _Nonnull)cppTargetEndpointInfo; + ++ (DiscoveredNodeData * _Nonnull)convertToObjCDiscoveredNodeDataFrom: + (const chip::Dnssd::DiscoveredNodeData * _Nonnull)cppDiscoveredNodedata; + ++ (VideoPlayer * _Nonnull)convertToObjCVideoPlayerFrom:(TargetVideoPlayerInfo * _Nonnull)cppTargetVideoPlayerInfo; + +@end + +#endif /* ConversionUtils_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.mm new file mode 100644 index 00000000000000..1c3e6d3e75bd3e --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ConversionUtils.mm @@ -0,0 +1,149 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import + +#import "ConversionUtils.hpp" + +@implementation ConversionUtils + ++ (CHIP_ERROR)convertToCppTargetEndpointInfoFrom:(ContentApp * _Nonnull)objCContentApp + outTargetEndpointInfo:(TargetEndpointInfo &)outTargetEndpointInfo +{ + VerifyOrReturnError(objCContentApp.isInitialized, CHIP_ERROR_INVALID_ARGUMENT); + outTargetEndpointInfo.Initialize(objCContentApp.endpointId); + for (NSNumber * clusterId in objCContentApp.clusterIds) { + VerifyOrReturnError(outTargetEndpointInfo.AddCluster([clusterId unsignedIntValue]), CHIP_ERROR_INVALID_ARGUMENT); + } + return CHIP_NO_ERROR; +} + ++ (CHIP_ERROR)convertToCppDiscoveredNodeDataFrom:(DiscoveredNodeData * _Nonnull)objCDiscoveredNodeData + outDiscoveredNodeData:(chip::Dnssd::DiscoveredNodeData &)outDiscoveredNodeData +{ + // setting CommissionNodeData + outDiscoveredNodeData.commissionData.deviceType = objCDiscoveredNodeData.deviceType; + outDiscoveredNodeData.commissionData.vendorId = objCDiscoveredNodeData.vendorId; + outDiscoveredNodeData.commissionData.productId = objCDiscoveredNodeData.productId; + outDiscoveredNodeData.commissionData.longDiscriminator = objCDiscoveredNodeData.longDiscriminator; + outDiscoveredNodeData.commissionData.commissioningMode = objCDiscoveredNodeData.commissioningMode; + outDiscoveredNodeData.commissionData.pairingHint = objCDiscoveredNodeData.pairingHint; + chip::Platform::CopyString(outDiscoveredNodeData.commissionData.deviceName, chip::Dnssd::kMaxDeviceNameLen + 1, + [objCDiscoveredNodeData.deviceName UTF8String]); + outDiscoveredNodeData.commissionData.rotatingIdLen = objCDiscoveredNodeData.rotatingIdLen; + memcpy( + outDiscoveredNodeData.commissionData.rotatingId, objCDiscoveredNodeData.rotatingId, objCDiscoveredNodeData.rotatingIdLen); + + // setting CommonResolutionData + outDiscoveredNodeData.resolutionData.port = objCDiscoveredNodeData.port; + chip::Platform::CopyString(outDiscoveredNodeData.resolutionData.hostName, chip::Dnssd::kHostNameMaxLength + 1, + [objCDiscoveredNodeData.hostName UTF8String]); + outDiscoveredNodeData.resolutionData.interfaceId = chip::Inet::InterfaceId(objCDiscoveredNodeData.platformInterface); + outDiscoveredNodeData.resolutionData.numIPs = objCDiscoveredNodeData.numIPs; + for (size_t i = 0; i < objCDiscoveredNodeData.numIPs; i++) { + chip::Inet::IPAddress::FromString( + [objCDiscoveredNodeData.ipAddresses[i] UTF8String], outDiscoveredNodeData.resolutionData.ipAddress[i]); + } + return CHIP_NO_ERROR; +} + ++ (CHIP_ERROR)convertToCppTargetVideoPlayerInfoFrom:(VideoPlayer * _Nonnull)objCVideoPlayer + outTargetVideoPlayerInfo:(TargetVideoPlayerInfo &)outTargetVideoPlayerInfo +{ + VerifyOrReturnError(objCVideoPlayer.isInitialized, CHIP_ERROR_INVALID_ARGUMENT); + ReturnErrorOnFailure(outTargetVideoPlayerInfo.Initialize(objCVideoPlayer.nodeId, objCVideoPlayer.fabricIndex, nullptr, nullptr, + objCVideoPlayer.vendorId, objCVideoPlayer.productId, objCVideoPlayer.deviceType, [objCVideoPlayer.deviceName UTF8String])); + for (ContentApp * contentApp in objCVideoPlayer.contentApps) { + TargetEndpointInfo * endpoint = outTargetVideoPlayerInfo.GetOrAddEndpoint(contentApp.endpointId); + VerifyOrReturnError(endpoint != nullptr, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure([ConversionUtils convertToCppTargetEndpointInfoFrom:contentApp outTargetEndpointInfo:*endpoint]); + } + return CHIP_NO_ERROR; +} + ++ (ContentApp *)convertToObjCContentAppFrom:(TargetEndpointInfo * _Nonnull)cppTargetEndpointInfo +{ + ContentApp * objCContentApp = [ContentApp new]; + if (cppTargetEndpointInfo->IsInitialized()) { + objCContentApp.endpointId = cppTargetEndpointInfo->GetEndpointId(); + objCContentApp.clusterIds = [NSMutableArray new]; + chip::ClusterId * clusterIds = cppTargetEndpointInfo->getClusters(); + for (size_t i = 0; i < kMaxNumberOfClustersPerEndpoint && clusterIds[i] != chip::kInvalidClusterId; i++) { + objCContentApp.clusterIds[i] = @(clusterIds[i]); + } + objCContentApp.isInitialized = true; + } + return objCContentApp; +} + ++ (DiscoveredNodeData *)convertToObjCDiscoveredNodeDataFrom:(const chip::Dnssd::DiscoveredNodeData * _Nonnull)cppDiscoveredNodedata +{ + DiscoveredNodeData * objCDiscoveredNodeData = [DiscoveredNodeData new]; + + // from CommissionNodeData + objCDiscoveredNodeData.deviceType = cppDiscoveredNodedata->commissionData.deviceType; + objCDiscoveredNodeData.vendorId = cppDiscoveredNodedata->commissionData.vendorId; + objCDiscoveredNodeData.productId = cppDiscoveredNodedata->commissionData.productId; + objCDiscoveredNodeData.longDiscriminator = cppDiscoveredNodedata->commissionData.longDiscriminator; + objCDiscoveredNodeData.commissioningMode = cppDiscoveredNodedata->commissionData.commissioningMode; + objCDiscoveredNodeData.pairingHint = cppDiscoveredNodedata->commissionData.pairingHint; + objCDiscoveredNodeData.deviceName = [NSString stringWithCString:cppDiscoveredNodedata->commissionData.deviceName + encoding:NSASCIIStringEncoding]; + objCDiscoveredNodeData.rotatingIdLen = cppDiscoveredNodedata->commissionData.rotatingIdLen; + objCDiscoveredNodeData.rotatingId = cppDiscoveredNodedata->commissionData.rotatingId; + objCDiscoveredNodeData.instanceName = [NSString stringWithCString:cppDiscoveredNodedata->commissionData.instanceName + encoding:NSASCIIStringEncoding]; + + // from CommonResolutionData + objCDiscoveredNodeData.port = cppDiscoveredNodedata->resolutionData.port; + objCDiscoveredNodeData.hostName = [NSString stringWithCString:cppDiscoveredNodedata->resolutionData.hostName + encoding:NSASCIIStringEncoding]; + objCDiscoveredNodeData.platformInterface = cppDiscoveredNodedata->resolutionData.interfaceId.GetPlatformInterface(); + objCDiscoveredNodeData.numIPs = cppDiscoveredNodedata->resolutionData.numIPs; + if (cppDiscoveredNodedata->resolutionData.numIPs > 0) { + objCDiscoveredNodeData.ipAddresses = [NSMutableArray new]; + } + for (size_t i = 0; i < cppDiscoveredNodedata->resolutionData.numIPs; i++) { + char addrCString[chip::Inet::IPAddress::kMaxStringLength]; + cppDiscoveredNodedata->resolutionData.ipAddress->ToString(addrCString, chip::Inet::IPAddress::kMaxStringLength); + objCDiscoveredNodeData.ipAddresses[i] = [NSString stringWithCString:addrCString encoding:NSASCIIStringEncoding]; + } + return objCDiscoveredNodeData; +} + ++ (VideoPlayer *)convertToObjCVideoPlayerFrom:(TargetVideoPlayerInfo * _Nonnull)cppTargetVideoPlayerInfo +{ + VideoPlayer * objCVideoPlayer = [VideoPlayer new]; + if (cppTargetVideoPlayerInfo->IsInitialized()) { + objCVideoPlayer.nodeId = cppTargetVideoPlayerInfo->GetNodeId(); + objCVideoPlayer.fabricIndex = cppTargetVideoPlayerInfo->GetFabricIndex(); + objCVideoPlayer.vendorId = cppTargetVideoPlayerInfo->GetVendorId(); + objCVideoPlayer.productId = cppTargetVideoPlayerInfo->GetProductId(); + objCVideoPlayer.deviceType = cppTargetVideoPlayerInfo->GetDeviceType(); + objCVideoPlayer.isConnected = (cppTargetVideoPlayerInfo->GetOperationalDeviceProxy() != nil); + objCVideoPlayer.deviceName = [NSString stringWithCString:cppTargetVideoPlayerInfo->GetDeviceName() + encoding:NSASCIIStringEncoding]; + objCVideoPlayer.contentApps = [NSMutableArray new]; + TargetEndpointInfo * cppTargetEndpointInfos = cppTargetVideoPlayerInfo->GetEndpoints(); + for (size_t i = 0; i < kMaxNumberOfEndpoints && cppTargetEndpointInfos[i].IsInitialized(); i++) { + objCVideoPlayer.contentApps[i] = [ConversionUtils convertToObjCContentAppFrom:&cppTargetEndpointInfos[i]]; + } + objCVideoPlayer.isInitialized = true; + } + return objCVideoPlayer; +} + +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.mm deleted file mode 100644 index 2c96ca48cb95ab..00000000000000 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/DiscoveredNodeDataConverter.mm +++ /dev/null @@ -1,58 +0,0 @@ -/** - * - * Copyright (c) 2020-2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#import - -#import "DiscoveredNodeDataConverter.hpp" - -@implementation DiscoveredNodeDataConverter - -+ (DiscoveredNodeData *)convertToObjC:(const chip::Dnssd::DiscoveredNodeData *)chipDiscoveredNodeData -{ - DiscoveredNodeData * objCDiscoveredNodeData = [DiscoveredNodeData new]; - - // from CommissionNodeData - objCDiscoveredNodeData.deviceType = chipDiscoveredNodeData->commissionData.deviceType; - objCDiscoveredNodeData.vendorId = chipDiscoveredNodeData->commissionData.vendorId; - objCDiscoveredNodeData.productId = chipDiscoveredNodeData->commissionData.productId; - objCDiscoveredNodeData.longDiscriminator = chipDiscoveredNodeData->commissionData.longDiscriminator; - objCDiscoveredNodeData.commissioningMode = chipDiscoveredNodeData->commissionData.commissioningMode; - objCDiscoveredNodeData.pairingHint = chipDiscoveredNodeData->commissionData.pairingHint; - objCDiscoveredNodeData.deviceName = [NSString stringWithCString:chipDiscoveredNodeData->commissionData.deviceName - encoding:NSASCIIStringEncoding]; - objCDiscoveredNodeData.rotatingIdLen = chipDiscoveredNodeData->commissionData.rotatingIdLen; - objCDiscoveredNodeData.rotatingId = chipDiscoveredNodeData->commissionData.rotatingId; - objCDiscoveredNodeData.instanceName = [NSString stringWithCString:chipDiscoveredNodeData->commissionData.instanceName - encoding:NSASCIIStringEncoding]; - - // from CommonResolutionData - objCDiscoveredNodeData.port = chipDiscoveredNodeData->resolutionData.port; - objCDiscoveredNodeData.hostName = [NSString stringWithCString:chipDiscoveredNodeData->resolutionData.hostName - encoding:NSASCIIStringEncoding]; - objCDiscoveredNodeData.platformInterface = chipDiscoveredNodeData->resolutionData.interfaceId.GetPlatformInterface(); - objCDiscoveredNodeData.numIPs = chipDiscoveredNodeData->resolutionData.numIPs; - if (chipDiscoveredNodeData->resolutionData.numIPs > 0) { - objCDiscoveredNodeData.ipAddresses = [NSMutableArray new]; - } - for (int i = 0; i < chipDiscoveredNodeData->resolutionData.numIPs; i++) { - char addrCString[chip::Inet::IPAddress::kMaxStringLength]; - chipDiscoveredNodeData->resolutionData.ipAddress->ToString(addrCString, chip::Inet::IPAddress::kMaxStringLength); - objCDiscoveredNodeData.ipAddresses[i] = [NSString stringWithCString:addrCString encoding:NSASCIIStringEncoding]; - } - return objCDiscoveredNodeData; -} - -@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.h new file mode 100644 index 00000000000000..64a320982a86f6 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.h @@ -0,0 +1,61 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VideoPlayer_h +#define VideoPlayer_h + +@interface VideoPlayer : NSObject + +@property uint64_t nodeId; + +@property uint8_t fabricIndex; + +/** + * @brief true if this VideoPlayer is connected, false otherwise + */ +@property bool isConnected; + +/** + * @brief contentApps will be nil the VideoPlayer is not connected + */ +@property NSMutableArray * contentApps; + +@property NSString * deviceName; + +@property uint16_t vendorId; + +@property uint16_t productId; + +@property uint16_t deviceType; + +/** + @brief true, if all the required fields are initialized, false otherwise + */ +@property BOOL isInitialized; + +- (instancetype)initWithNodeId:(uint64_t)nodeId + fabricIndex:(uint8_t)fabricIndex + isConnected:(bool)isConnected + contentApps:(NSMutableArray *)contentApps + deviceName:(NSString *)deviceName + vendorId:(uint16_t)vendorId + productId:(uint16_t)productId + deviceType:(uint16_t)deviceType; + +@end + +#endif /* VideoPlayer_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.m b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.m new file mode 100644 index 00000000000000..2640fbb2045de0 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/VideoPlayer.m @@ -0,0 +1,59 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "VideoPlayer.h" + +@implementation VideoPlayer + +- (instancetype)init +{ + if (self = [super init]) { + _isInitialized = false; + } + return self; +} + +- (instancetype)initWithNodeId:(uint64_t)nodeId + fabricIndex:(uint8_t)fabricIndex + isConnected:(bool)isConnected + contentApps:(NSMutableArray *)contentApps + deviceName:(NSString *)deviceName + vendorId:(uint16_t)vendorId + productId:(uint16_t)productId + deviceType:(uint16_t)deviceType; +{ + if (self = [super init]) { + _nodeId = nodeId; + _fabricIndex = fabricIndex; + _isConnected = isConnected; + _contentApps = contentApps; + _deviceName = deviceName; + _vendorId = vendorId; + _productId = productId; + _deviceType = deviceType; + _isInitialized = true; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ with Product ID: %d, Vendor ID: %d", _deviceName, _productId, _vendorId]; +} +@end diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj index ed740398a117f4..dfaf0a6813066d 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj @@ -7,9 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + 3C81C75328F8C79E001CB9D1 /* StartFromCacheView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75228F8C79E001CB9D1 /* StartFromCacheView.swift */; }; + 3C81C75528F8C7B6001CB9D1 /* StartFromCacheViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75428F8C7B6001CB9D1 /* StartFromCacheViewModel.swift */; }; + 3C81C75728F8E418001CB9D1 /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75628F8E418001CB9D1 /* ConnectionView.swift */; }; + 3C81C75928F8E42D001CB9D1 /* ConnectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75828F8E42D001CB9D1 /* ConnectionViewModel.swift */; }; 3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */; }; - 3CA1CA7C28E282150023ED44 /* MediaPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */; }; - 3CA1CA7E28E284950023ED44 /* MediaPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */; }; + 3CA1CA7C28E282150023ED44 /* MediaPlaybackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7B28E282150023ED44 /* MediaPlaybackView.swift */; }; + 3CA1CA7E28E284950023ED44 /* MediaPlaybackViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7D28E284950023ED44 /* MediaPlaybackViewModel.swift */; }; 3CC0E8FA2841DD3400EC6A18 /* TvCastingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */; }; 3CC0E8FC2841DD3400EC6A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */; }; 3CC0E8FE2841DD3500EC6A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3CC0E8FD2841DD3500EC6A18 /* Assets.xcassets */; }; @@ -44,11 +48,15 @@ 3C7507AE28529A5F00D7DB3A /* CommissioningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissioningView.swift; sourceTree = ""; }; 3C7507B62853A3AD00D7DB3A /* CommissionerDiscoveryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissionerDiscoveryViewModel.swift; sourceTree = ""; }; 3C7507B82853EFF000D7DB3A /* CommissioningViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissioningViewModel.swift; sourceTree = ""; }; + 3C81C75228F8C79E001CB9D1 /* StartFromCacheView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartFromCacheView.swift; sourceTree = ""; }; + 3C81C75428F8C7B6001CB9D1 /* StartFromCacheViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartFromCacheViewModel.swift; sourceTree = ""; }; + 3C81C75628F8E418001CB9D1 /* ConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionView.swift; sourceTree = ""; }; + 3C81C75828F8E42D001CB9D1 /* ConnectionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionViewModel.swift; sourceTree = ""; }; 3CA19434285BA780004768D5 /* ContentLauncherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLauncherView.swift; sourceTree = ""; }; 3CA19436285BA877004768D5 /* ContentLauncherViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLauncherViewModel.swift; sourceTree = ""; }; 3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterSelectorView.swift; sourceTree = ""; }; - 3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerView.swift; sourceTree = ""; }; - 3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerViewModel.swift; sourceTree = ""; }; + 3CA1CA7B28E282150023ED44 /* MediaPlaybackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlaybackView.swift; sourceTree = ""; }; + 3CA1CA7D28E284950023ED44 /* MediaPlaybackViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlaybackViewModel.swift; sourceTree = ""; }; 3CC0E8F62841DD3400EC6A18 /* TvCasting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TvCasting.app; sourceTree = BUILT_PRODUCTS_DIR; }; 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TvCastingApp.swift; sourceTree = ""; }; 3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -103,6 +111,10 @@ 3C75075E284C1DF800D7DB3A /* TvCasting.entitlements */, 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */, 3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */, + 3C81C75228F8C79E001CB9D1 /* StartFromCacheView.swift */, + 3C81C75428F8C7B6001CB9D1 /* StartFromCacheViewModel.swift */, + 3C81C75628F8E418001CB9D1 /* ConnectionView.swift */, + 3C81C75828F8E42D001CB9D1 /* ConnectionViewModel.swift */, 3C7507AC285299DF00D7DB3A /* CommissionerDiscoveryView.swift */, 3C7507B62853A3AD00D7DB3A /* CommissionerDiscoveryViewModel.swift */, 3C7507AE28529A5F00D7DB3A /* CommissioningView.swift */, @@ -110,8 +122,8 @@ 3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */, 3CA19434285BA780004768D5 /* ContentLauncherView.swift */, 3CA19436285BA877004768D5 /* ContentLauncherViewModel.swift */, - 3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */, - 3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */, + 3CA1CA7B28E282150023ED44 /* MediaPlaybackView.swift */, + 3CA1CA7D28E284950023ED44 /* MediaPlaybackViewModel.swift */, 3CC0E8FF2841DD3500EC6A18 /* Preview Content */, ); path = TvCasting; @@ -208,16 +220,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3C81C75328F8C79E001CB9D1 /* StartFromCacheView.swift in Sources */, + 3C81C75528F8C7B6001CB9D1 /* StartFromCacheViewModel.swift in Sources */, 3CCB8745286A5D0F00771BAD /* CommissionerDiscoveryView.swift in Sources */, 3CCB8746286A5D0F00771BAD /* CommissionerDiscoveryViewModel.swift in Sources */, + 3C81C75928F8E42D001CB9D1 /* ConnectionViewModel.swift in Sources */, 3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */, 3CCB8747286A5D0F00771BAD /* CommissioningView.swift in Sources */, 3CCB8748286A5D0F00771BAD /* CommissioningViewModel.swift in Sources */, - 3CA1CA7E28E284950023ED44 /* MediaPlayerViewModel.swift in Sources */, + 3CA1CA7E28E284950023ED44 /* MediaPlaybackViewModel.swift in Sources */, 3CCB8749286A5D0F00771BAD /* ContentLauncherView.swift in Sources */, 3CCB874A286A5D0F00771BAD /* ContentLauncherViewModel.swift in Sources */, + 3C81C75728F8E418001CB9D1 /* ConnectionView.swift in Sources */, 3CC0E8FC2841DD3400EC6A18 /* ContentView.swift in Sources */, - 3CA1CA7C28E282150023ED44 /* MediaPlayerView.swift in Sources */, + 3CA1CA7C28E282150023ED44 /* MediaPlaybackView.swift in Sources */, 3CC0E8FA2841DD3400EC6A18 /* TvCastingApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -355,7 +371,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"TvCasting/Preview Content\""; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = R7NUZ7N74U; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -404,7 +420,7 @@ CoreData, "-Wl,-unexported_symbol,\"__Z*\"", ); - PRODUCT_BUNDLE_IDENTIFIER = com.matter.TvCasting; + PRODUCT_BUNDLE_IDENTIFIER = "com.matter.TvCasting-sharadb"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -425,7 +441,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"TvCasting/Preview Content\""; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = R7NUZ7N74U; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -451,7 +467,7 @@ "-Wformat-nonliteral", "-Wformat-security", ); - PRODUCT_BUNDLE_IDENTIFIER = com.matter.TvCasting; + PRODUCT_BUNDLE_IDENTIFIER = "com.matter.TvCasting-sharadb"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissionerDiscoveryView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissionerDiscoveryView.swift index b49e774164ad94..3ee2ac30d4b724 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissionerDiscoveryView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissionerDiscoveryView.swift @@ -52,7 +52,7 @@ struct CommissionerDiscoveryView: View { } else if(!viewModel.commissioners.isEmpty) { - Text("Select a commissioner TV...") + Text("Select a commissioner video player...") ForEach(viewModel.commissioners) { commissioner in NavigationLink( destination: CommissioningView(_selectedCommissioner: commissioner), @@ -68,7 +68,7 @@ struct CommissionerDiscoveryView: View { } } } - .navigationTitle("TV Discovery") + .navigationTitle("Video Player Discovery") .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) } } diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift index 23cee1eb7d341b..f5cb7ddcfaeb74 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift @@ -65,17 +65,29 @@ struct CommissioningView: View { if(viewModel.commisisoningComplete == true) { Text("Commissioning finished!").padding() - NavigationLink( - destination: ClusterSelectorView(), - label: { - Text("Next") - .frame(width: 100, height: 30, alignment: .center) - .border(Color.black, width: 1) + + if let connectionSuccess = viewModel.connectionSuccess + { + if let connectionStatus = viewModel.connectionStatus + { + Text(connectionStatus).padding() } - ).background(Color.blue) - .foregroundColor(Color.white) - .frame(maxHeight: .infinity, alignment: .bottom) - .padding() + + if(connectionSuccess) + { + NavigationLink( + destination: ClusterSelectorView(), + label: { + Text("Next") + .frame(width: 100, height: 30, alignment: .center) + .border(Color.black, width: 1) + } + ).background(Color.blue) + .foregroundColor(Color.white) + .frame(maxHeight: .infinity, alignment: .bottom) + .padding() + } + } } else if(viewModel.commisisoningComplete == false) { diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift index 5af7d263133557..1c2feaa3aac024 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift @@ -29,20 +29,43 @@ class CommissioningViewModel: ObservableObject { @Published var commisisoningComplete: Bool?; + @Published var connectionSuccess: Bool?; + + @Published var connectionStatus: String?; + func prepareForCommissioning(selectedCommissioner: DiscoveredNodeData?) { if let castingServerBridge = CastingServerBridge.getSharedInstance() { - castingServerBridge.openBasicCommissioningWindow( - { (result: Bool) -> () in - // commissioning complete handler code + castingServerBridge.openBasicCommissioningWindow(DispatchQueue.main, + commissioningWindowRequestedHandler: { (result: Bool) -> () in + DispatchQueue.main.async { + self.commisisoningWindowOpened = result + } + }, + commissioningCompleteCallback: { (result: Bool) -> () in self.Log.info("Commissioning status: \(result)") DispatchQueue.main.async { self.commisisoningComplete = result } }, - clientQueue: DispatchQueue.main, - commissioningWindowRequestedHandler: { (result: Bool) -> () in - self.commisisoningWindowOpened = result + onConnectionSuccessCallback: { (videoPlayer: VideoPlayer) -> () in + DispatchQueue.main.async { + self.connectionSuccess = true + self.connectionStatus = "Connected to \(String(describing: videoPlayer))" + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.onConnectionSuccessCallback called with \(videoPlayer.nodeId)") + } + }, + onConnectionFailureCallback: { (error: MatterError) -> () in + DispatchQueue.main.async { + self.connectionSuccess = false + self.connectionStatus = "Failed to connect to video player!" + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.onConnectionFailureCallback called with \(error)") + } + }, + onNewOrUpdatedEndpointCallback: { (contentApp: ContentApp) -> () in + DispatchQueue.main.async { + self.Log.info("CommissioningViewModel.openBasicCommissioningWindow.onNewOrUpdatedEndpointCallback called with \(contentApp.endpointId)") + } }) } @@ -53,14 +76,10 @@ class CommissioningViewModel: ObservableObject { } } - private func sendUserDirectedCommissioningRequest(selectedCommissioner: DiscoveredNodeData?) { - let ipAddress: String = selectedCommissioner!.ipAddresses[0] as! String - let port: UInt16 = selectedCommissioner!.port - let platformInterface: UInt32 = selectedCommissioner!.platformInterface - + private func sendUserDirectedCommissioningRequest(selectedCommissioner: DiscoveredNodeData?) { if let castingServerBridge = CastingServerBridge.getSharedInstance() { - castingServerBridge.sendUserDirectedCommissioningRequest(ipAddress, commissionerPort: port, platformInterface: platformInterface, clientQueue: DispatchQueue.main, udcRequestSentHandler: { (result: Bool) -> () in + castingServerBridge.sendUserDirectedCommissioningRequest(selectedCommissioner!, clientQueue: DispatchQueue.main, udcRequestSentHandler: { (result: Bool) -> () in self.udcRequestSent = result }) } diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionView.swift new file mode 100644 index 00000000000000..c7bfacc6cca49e --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionView.swift @@ -0,0 +1,78 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import SwiftUI + +struct ConnectionView: View { + var selectedVideoPlayer: VideoPlayer? + + @StateObject var viewModel = ConnectionViewModel(); + + init(_selectedVideoPlayer: VideoPlayer?) { + self.selectedVideoPlayer = _selectedVideoPlayer + } + + var body: some View { + VStack(alignment: .leading) { + if let requestSent = viewModel.requestSent { + if(requestSent) + { + Text("Sent request to verify or connect to video player").padding() + } + else + { + Text("Failed in sending request to verify or connect to video player!").foregroundColor(Color.red).padding() + } + + if let connectionSuccess = viewModel.connectionSuccess + { + if let connectionStatus = viewModel.connectionStatus + { + Text(connectionStatus).padding() + } + + if(connectionSuccess) + { + NavigationLink( + destination: ClusterSelectorView(), + label: { + Text("Next") + .frame(width: 100, height: 30, alignment: .center) + .border(Color.black, width: 1) + } + ).background(Color.blue) + .foregroundColor(Color.white) + .frame(maxHeight: .infinity, alignment: .bottom) + .padding() + } + } + } + } + .navigationTitle("Connecting...") + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) + .onAppear(perform: { + viewModel.verifyOrEstablishConnection(selectedVideoPlayer: self.selectedVideoPlayer) + }) + } +} + +struct ConnectionView_Previews: PreviewProvider { + static var previews: some View { + ConnectionView(_selectedVideoPlayer: nil) + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionViewModel.swift new file mode 100644 index 00000000000000..2d97a47ab3966c --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ConnectionViewModel.swift @@ -0,0 +1,63 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import Foundation +import os.log + +class ConnectionViewModel: ObservableObject { + let Log = Logger(subsystem: "com.matter.casting", + category: "ConnectionViewModel") + + @Published var requestSent: Bool?; + + @Published var connectionSuccess: Bool?; + + @Published var connectionStatus: String?; + + func verifyOrEstablishConnection(selectedVideoPlayer: VideoPlayer?) { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + castingServerBridge.verifyOrEstablishConnection(selectedVideoPlayer!, clientQueue: DispatchQueue.main, + requestSentHandler: { (error: MatterError) -> () in + DispatchQueue.main.async { + self.requestSent = (error.code == 0) + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.requestSentHandler called with \(error)") + } + }, + onConnectionSuccessCallback: { (videoPlayer: VideoPlayer) -> () in + DispatchQueue.main.async { + self.connectionSuccess = true + self.connectionStatus = "Connected to \(String(describing: videoPlayer))" + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.onConnectionSuccessCallback called with \(videoPlayer.nodeId)") + } + }, + onConnectionFailureCallback: { (error: MatterError) -> () in + DispatchQueue.main.async { + self.connectionSuccess = false + self.connectionStatus = "Failed to connect to video player!" + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.onConnectionFailureCallback called with \(error)") + } + }, + onNewOrUpdatedEndpointCallback: { (contentApp: ContentApp) -> () in + DispatchQueue.main.async { + self.Log.info("ConnectionViewModel.verifyOrEstablishConnection.onNewOrUpdatedEndpointCallback called with \(contentApp.endpointId)") + } + }) + } + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherView.swift index 120b6ee1a903d6..dc15dc66876fa6 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherView.swift @@ -17,51 +17,86 @@ import SwiftUI +extension ContentApp : Identifiable { + public var id: UInt16 { + endpointId + } +} + struct ContentLauncherView: View { @StateObject var viewModel = ContentLauncherViewModel() @State private var contentUrl: String = "" @State private var contentDisplayStr: String = "" + @State private var targetContentAppId: String = "" var body: some View { VStack(alignment: .leading) { - HStack() { - Text("Content URL") - - TextField( - "https://www.test.com/videoid", - text: $contentUrl - ) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .border(.secondary) + if(viewModel.contentAppIds.isEmpty) + { + Text("No Content Launcher cluster supporting content apps found on this video player!") } + else + { + HStack() { + Text("Content App Endpoint Id") + + VStack() + { + Picker("Select", selection: $targetContentAppId) { + Text("Select").tag(nil as String?) + ForEach(viewModel.contentAppIds, id: \.self) { contentAppId in + Text(String(contentAppId)) + } + } + .pickerStyle(.menu) + .padding(2) + } + .border(.secondary) + } - HStack() { - Text("Display string") + HStack() { + Text("Content URL") - TextField( - "Test video", - text: $contentDisplayStr - ) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .border(.secondary) - } + TextField( + "https://www.test.com/videoid", + text: $contentUrl + ) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .border(.secondary) + } - Button("Launch URL!") { - viewModel.launchUrl(contentUrl: contentUrl, contentDisplayStr: contentDisplayStr) - } - .background(Color.blue) - .foregroundColor(Color.white) - .cornerRadius(4) - .border(Color.black, width: 1) - .padding() + HStack() { + Text("Display string") + + TextField( + "Test video", + text: $contentDisplayStr + ) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .border(.secondary) + } + + Button("Launch URL!") { + viewModel.launchUrl(targetContentAppId: targetContentAppId, contentUrl: contentUrl, contentDisplayStr: contentDisplayStr) + } + .background(Color.blue) + .foregroundColor(Color.white) + .cornerRadius(4) + .border(Color.black, width: 1) + .padding() - Text(viewModel.status ?? "") + Text(viewModel.status ?? "") + } + } .navigationTitle("Content Launcher") .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) + .onAppear(perform: { + viewModel.populateContentApps() + }) } } diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherViewModel.swift index ee741f8bcae8f0..7003525e8d3360 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentLauncherViewModel.swift @@ -25,14 +25,27 @@ class ContentLauncherViewModel: ObservableObject { @Published var status: String?; - func launchUrl(contentUrl: String?, contentDisplayStr: String?) + @Published var contentAppIds: [String] = []; + + var targetVideoPlayer: VideoPlayer?; + + func launchUrl(targetContentAppId: String?, contentUrl: String?, contentDisplayStr: String?) { - if ((contentUrl != nil && !contentUrl!.isEmpty) && (contentDisplayStr != nil && !contentDisplayStr!.isEmpty)) + if ((targetContentAppId != nil && !targetContentAppId!.isEmpty) && (contentUrl != nil && !contentUrl!.isEmpty) && (contentDisplayStr != nil && !contentDisplayStr!.isEmpty)) { + var targetContentApp: ContentApp? + for contentApp in (targetVideoPlayer!.contentApps as! [ContentApp]) { + if(UInt16(targetContentAppId!) == contentApp.endpointId) + { + targetContentApp = contentApp + break + } + } + if let castingServerBridge = CastingServerBridge.getSharedInstance() { castingServerBridge - .contentLauncher_launchUrl(contentUrl!, + .contentLauncher_launchUrl(targetContentApp!, contentUrl: contentUrl!, contentDisplayStr: contentDisplayStr!, responseCallback: { (result: Bool) -> () in @@ -41,9 +54,8 @@ class ContentLauncherViewModel: ObservableObject { self.status = result ? "Launched URL successfully" : "Launch URL failure!" } }, - clientQueue: DispatchQueue.main, - requestSentHandler: - { (result: Bool) -> () in + clientQueue: DispatchQueue.main, + requestSentHandler: { (result: Bool) -> () in self.Log.info("ContentLauncherViewModel.launchUrl.launcUrlRequestSentHandler result \(result)") self.status = result ? "Sent Launch URL request" : "Failed to send Launch URL request!" }) @@ -55,4 +67,26 @@ class ContentLauncherViewModel: ObservableObject { self.status = "Missing input parameter(s)!" } } + + func populateContentApps() + { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + castingServerBridge.getActiveTargetVideoPlayers(DispatchQueue.main, + activeTargetVideoPlayersHandler: { (targetVideoPlayers: NSMutableArray?) -> () in + let targetVideoPlayer: VideoPlayer = targetVideoPlayers![0] as! VideoPlayer + if(targetVideoPlayer.isInitialized && targetVideoPlayer.isConnected) + { + self.targetVideoPlayer = targetVideoPlayer + for contentApp in (targetVideoPlayer.contentApps as! [ContentApp]) + { + if(contentApp.supportsContentLauncher()) + { + self.contentAppIds.append(String(contentApp.endpointId)) + } + } + } + }) + } + } } diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentView.swift index 69b67095c60751..e7ca12c9b720cd 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ContentView.swift @@ -20,7 +20,8 @@ import SwiftUI struct ContentView: View { var body: some View { NavigationView { - CommissionerDiscoveryView() + //CommissionerDiscoveryView() + StartFromCacheView() } } } diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackView.swift new file mode 100644 index 00000000000000..b41835adb0c139 --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackView.swift @@ -0,0 +1,105 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SwiftUI + +struct MediaPlayerView: View { + @StateObject var viewModel = MediaPlaybackViewModel() + + @State private var minIntervalStr: String = "" + @State private var maxIntervalStr: String = "" + @State private var targetContentAppId: String = "" + + var body: some View { + VStack(alignment: .leading) + { + if(viewModel.contentAppIds.isEmpty) + { + Text("No Media Playback cluster supporting content apps found on this video player!") + } + else + { + Text("Subscribe to Current State") + + HStack() { + Text("Content App Endpoint Id") + + VStack() + { + Picker("Select", selection: $targetContentAppId) { + Text("Select").tag(nil as String?) + ForEach(viewModel.contentAppIds, id: \.self) { contentAppId in + Text(String(contentAppId)) + } + } + .pickerStyle(.menu) + .padding(2) + } + .border(.secondary) + } + + HStack() { + Text("Min Interval") + + TextField( + "0", + text: $minIntervalStr + ) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .border(.secondary) + } + + HStack() { + Text("Max Interval") + + TextField( + "1", + text: $maxIntervalStr + ) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .border(.secondary) + } + + Button("Subscribe!") { + viewModel.subscribeCurrentState(targetContentAppId: targetContentAppId, minInterval: minIntervalStr, maxInterval: maxIntervalStr) + } + .background(Color.blue) + .foregroundColor(Color.white) + .cornerRadius(4) + .border(Color.black, width: 1) + .padding() + + Text(viewModel.requestStatus ?? "") + Text(viewModel.subscriptionStatus ?? "") + Text(viewModel.readResponse ?? "") + } + } + .navigationTitle("Media Playback") + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) + .onAppear(perform: { + viewModel.populateContentApps() + }) + } +} + +struct MediaPlayerView_Previews: PreviewProvider { + static var previews: some View { + MediaPlayerView() + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackViewModel.swift new file mode 100644 index 00000000000000..5a93a2ffe7c3cf --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlaybackViewModel.swift @@ -0,0 +1,120 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import Foundation +import os.log + +class MediaPlaybackViewModel: ObservableObject { + let Log = Logger(subsystem: "com.matter.casting", + category: "MediaPlaybackViewModel") + + @Published var requestStatus: String?; + @Published var subscriptionStatus: String?; + @Published var readResponse: String?; + + @Published var contentAppIds: [String] = []; + + var targetVideoPlayer: VideoPlayer?; + + func subscribeCurrentState(targetContentAppId: String?, minInterval: String, maxInterval: String) + { + if((targetContentAppId != nil && !targetContentAppId!.isEmpty)) + { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + var targetContentApp: ContentApp? + for contentApp in (targetVideoPlayer!.contentApps as! [ContentApp]) { + if(UInt16(targetContentAppId!) == contentApp.endpointId) + { + targetContentApp = contentApp + break + } + } + + castingServerBridge.mediaPlayback_subscribeCurrentState(targetContentApp!, minInterval: UInt16(minInterval) ?? 0, maxInterval: UInt16(maxInterval) ?? 1, clientQueue: DispatchQueue.main, + requestSentHandler: { (result: MatterError) -> () in + self.Log.info("MediaPlaybackViewModel.subscribeToCurrentState.requestSentHandler result \(result)") + self.requestStatus = result.code == 0 ? "Subscribe request sent!" : "Failed to send Subscribe request!" + }, + successCallback: { (result: MediaPlayback_PlaybackState) -> () in + DispatchQueue.main.async { + self.Log.info("MediaPlaybackViewModel.subscribeToCurrentState.successCallback called") + switch(result) + { + case .Playing: + self.readResponse = "Current state: Playing" + break + case .Paused: + self.readResponse = "Current state: Paused" + break + case .NotPlaying: + self.readResponse = "Current state: NotPlaying" + break + case .Buffering: + self.readResponse = "Current state: Buffering" + break + default: + self.readResponse = "Current state: Unknown!" + break + } + } + }, + failureCallback: { (result: MatterError) -> () in + DispatchQueue.main.async { + self.Log.info("MediaPlaybackViewModel.subscribeToCurrentState.failureCallback called with \(result)") + self.readResponse = "Attribute read failure!" + } + }, + subscriptionEstablishedCallback: { () -> () in + DispatchQueue.main.async { + self.Log.info("MediaPlaybackViewModel.subscribeToCurrentState.subscriptionEstablishedCallback called") + self.subscriptionStatus = "Subscription established!" + } + } + ) + } + } + else + { + Log.debug("MediaPlaybackViewModel.subscribeToCurrentState No endpoint selected!") + self.requestStatus = "No endpoint selected!" + } + } + + func populateContentApps() + { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + castingServerBridge.getActiveTargetVideoPlayers(DispatchQueue.main, + activeTargetVideoPlayersHandler: { (targetVideoPlayers: NSMutableArray?) -> () in + let targetVideoPlayer: VideoPlayer = targetVideoPlayers![0] as! VideoPlayer + if(targetVideoPlayer.isInitialized && targetVideoPlayer.isConnected) + { + self.targetVideoPlayer = targetVideoPlayer + for contentApp in (targetVideoPlayer.contentApps as! [ContentApp]) + { + if(contentApp.supportsMediaPlayback()) + { + self.contentAppIds.append(String(contentApp.endpointId)) + } + } + } + }) + } + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift deleted file mode 100644 index 296b0a78607f9a..00000000000000 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift +++ /dev/null @@ -1,76 +0,0 @@ -/** - * - * Copyright (c) 2020-2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import SwiftUI - -struct MediaPlayerView: View { - @StateObject var viewModel = MediaPlayerViewModel() - - @State private var minIntervalStr: String = "" - @State private var maxIntervalStr: String = "" - - var body: some View { - VStack(alignment: .leading) { - Text("Subscribe to Current State") - - HStack() { - Text("Min Interval") - - TextField( - "0", - text: $minIntervalStr - ) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .border(.secondary) - } - - HStack() { - Text("Max Interval") - - TextField( - "10", - text: $maxIntervalStr - ) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .border(.secondary) - } - - Button("Subscribe!") { - viewModel.subscribeCurrentState(minInterval: minIntervalStr, maxInterval: maxIntervalStr) - } - .background(Color.blue) - .foregroundColor(Color.white) - .cornerRadius(4) - .border(Color.black, width: 1) - .padding() - - Text(viewModel.requestStatus ?? "") - Text(viewModel.subscriptionStatus ?? "") - Text(viewModel.readResponse ?? "") - } - .navigationTitle("Media Playback") - .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) - } -} - -struct MediaPlayerView_Previews: PreviewProvider { - static var previews: some View { - MediaPlayerView() - } -} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift deleted file mode 100644 index d401d3f5247d5b..00000000000000 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift +++ /dev/null @@ -1,77 +0,0 @@ -/** - * - * Copyright (c) 2020-2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import Foundation -import os.log - -class MediaPlayerViewModel: ObservableObject { - let Log = Logger(subsystem: "com.matter.casting", - category: "MediaPlayerViewModel") - - @Published var requestStatus: String?; - @Published var subscriptionStatus: String?; - @Published var readResponse: String?; - - func subscribeCurrentState(minInterval: String, maxInterval: String) - { - if let castingServerBridge = CastingServerBridge.getSharedInstance() - { - castingServerBridge.mediaPlayback_subscribeCurrentState(UInt16(minInterval) ?? 0, maxInterval: UInt16(maxInterval) ?? 10, clientQueue: DispatchQueue.main, - requestSentHandler: { (result: MatterError) -> () in - self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.requestSentHandler result \(result)") - self.requestStatus = result.code == 0 ? "Subscribe request sent!" : "Failed to send Subscribe request!" - }, - successCallback: { (result: MediaPlayback_PlaybackState) -> () in - DispatchQueue.main.async { - self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.successCallback called") - switch(result) - { - case .Playing: - self.readResponse = "Current state: Playing" - break - case .Paused: - self.readResponse = "Current state: Paused" - break - case .NotPlaying: - self.readResponse = "Current state: NotPlaying" - break - case .Buffering: - self.readResponse = "Current state: Buffering" - break - default: - self.readResponse = "Current state: Unknown!" - break - } - } - }, - failureCallback: { (result: MatterError) -> () in - DispatchQueue.main.async { - self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.failureCallback called with \(result)") - self.readResponse = "Attribute read failure!" - } - }, - subscriptionEstablishedCallback: { () -> () in - DispatchQueue.main.async { - self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.subscriptionEstablishedCallback called") - self.subscriptionStatus = "Subscription established!" - } - } - ) - } - } -} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheView.swift new file mode 100644 index 00000000000000..9d4c0c8a659151 --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheView.swift @@ -0,0 +1,74 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SwiftUI + +extension VideoPlayer : Identifiable { + public var id: String { + deviceName + } +} + +struct StartFromCacheView: View { + @StateObject var viewModel = StartFromCacheViewModel() + + var body: some View { + VStack(alignment: .leading) { + NavigationLink( + destination: CommissionerDiscoveryView(), + label: { + Text("Skip to commissioner discovery >>") + .frame(width: 300, height: 30, alignment: .center) + .border(Color.black, width: 1) + } + ).background(Color.blue) + .foregroundColor(Color.white) + .padding() + + if(viewModel.videoPlayers.isEmpty) + { + Text("No cached video players.") + } + else + { + Text("Pick a Video player") + ForEach(viewModel.videoPlayers) { videoPlayer in + NavigationLink( + destination: ConnectionView(_selectedVideoPlayer: videoPlayer), + label: { + Text(videoPlayer.description) + } + ) + .frame(width: 350, height: 50, alignment: .center) + .border(Color.black, width: 1) + .background(Color.blue) + .foregroundColor(Color.white) + .padding(1) + } + } + } + .navigationTitle("Starting from Cache") + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) + .onAppear(perform: {viewModel.readFromCache()}) + } +} + +struct StartFromCacheView_Previews: PreviewProvider { + static var previews: some View { + StartFromCacheView() + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheViewModel.swift new file mode 100644 index 00000000000000..202d92c5ccfff3 --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/StartFromCacheViewModel.swift @@ -0,0 +1,38 @@ +/** + * + * Copyright (c) 2020-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Foundation +import os.log + +class StartFromCacheViewModel: ObservableObject { + let Log = Logger(subsystem: "com.matter.casting", + category: "StartFromCacheViewModel") + + @Published var videoPlayers: [VideoPlayer] = [] + + func readFromCache() { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + castingServerBridge.readCachedVideoPlayers(DispatchQueue.main, readCachedVideoPlayersHandler: { (cachedVideoPlayers: NSMutableArray?) -> () in + if(cachedVideoPlayers != nil) + { + self.videoPlayers = cachedVideoPlayers! as! [VideoPlayer] + } + }) + } + } +} diff --git a/examples/tv-casting-app/linux/CastingUtils.cpp b/examples/tv-casting-app/linux/CastingUtils.cpp index 3531ddd85b32fb..5c199351165dc7 100644 --- a/examples/tv-casting-app/linux/CastingUtils.cpp +++ b/examples/tv-casting-app/linux/CastingUtils.cpp @@ -210,7 +210,7 @@ void doCastingDemoActions(TargetEndpointInfo * endpoint) void OnConnectionSuccess(TargetVideoPlayerInfo * videoPlayer) { ChipLogProgress(AppServer, - "OnConnectionSuccess with Video Player(nodeId: %llu, fabricIndex: %d, deviceName: %s, vendorId: %d, productId: " + "OnConnectionSuccess with Video Player(nodeId: %lu, fabricIndex: %d, deviceName: %s, vendorId: %d, productId: " "%d, deviceType: %d)", videoPlayer->GetNodeId(), videoPlayer->GetFabricIndex(), videoPlayer->GetDeviceName(), videoPlayer->GetVendorId(), videoPlayer->GetProductId(), videoPlayer->GetDeviceType()); @@ -245,14 +245,14 @@ CHIP_ERROR ConnectToCachedVideoPlayer() { if (cachedVideoPlayers[i].IsInitialized()) { - ChipLogProgress(AppServer, "Found a Cached video player with nodeId: %llu, fabricIndex: %d", + ChipLogProgress(AppServer, "Found a Cached video player with nodeId: %lu, fabricIndex: %d", cachedVideoPlayers[i].GetNodeId(), cachedVideoPlayers[i].GetFabricIndex()); if (CastingServer::GetInstance()->VerifyOrEstablishConnection( cachedVideoPlayers[i], OnConnectionSuccess, OnConnectionFailure, OnNewOrUpdatedEndpoint) == CHIP_NO_ERROR) { ChipLogProgress( AppServer, - "FindOrEstablish CASESession attempted for cached video player with nodeId: %llu, fabricIndex: %d", + "FindOrEstablish CASESession attempted for cached video player with nodeId: %lu, fabricIndex: %d", cachedVideoPlayers[i].GetNodeId(), cachedVideoPlayers[i].GetFabricIndex()); return CHIP_NO_ERROR; } diff --git a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h index f7a7f74e53f2f3..1ad23687416853 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h +++ b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h @@ -65,7 +65,12 @@ class CastingServer CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Dnssd::DiscoveredNodeData * selectedCommissioner); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT - TargetVideoPlayerInfo * GetActiveTargetVideoPlayer() { return &mActiveTargetVideoPlayerInfo; } + TargetVideoPlayerInfo * GetActiveTargetVideoPlayer() + { + return mActiveTargetVideoPlayerInfo.IsInitialized() && mActiveTargetVideoPlayerInfo.GetOperationalDeviceProxy() != nullptr + ? &mActiveTargetVideoPlayerInfo + : nullptr; + } CHIP_ERROR TargetVideoPlayerInfoInit(chip::NodeId nodeId, chip::FabricIndex fabricIndex, std::function onConnectionSuccess, std::function onConnectionFailure, diff --git a/examples/tv-casting-app/tv-casting-common/include/MediaBase.h b/examples/tv-casting-app/tv-casting-common/include/MediaBase.h index e442e809ca33dc..8db6de11902873 100644 --- a/examples/tv-casting-app/tv-casting-common/include/MediaBase.h +++ b/examples/tv-casting-app/tv-casting-common/include/MediaBase.h @@ -31,7 +31,7 @@ class MediaBase auto deviceProxy = targetVideoPlayerInfo.GetOperationalDeviceProxy(); if (deviceProxy == nullptr) { - ChipLogError(AppServer, "Failed in getting an instance of OperationalDeviceProxy for nodeId: %llu, fabricIndex: %d", + ChipLogError(AppServer, "Failed in getting an instance of OperationalDeviceProxy for nodeId: %lu, fabricIndex: %d", targetVideoPlayerInfo.GetNodeId(), targetVideoPlayerInfo.GetFabricIndex()); return CHIP_ERROR_PEER_NODE_NOT_FOUND; } 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 2b1f22edee47f0..886f72ed4b7d11 100644 --- a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h +++ b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h @@ -73,7 +73,7 @@ class TargetVideoPlayerInfo _this->mDeviceProxy = chip::OperationalDeviceProxy(&exchangeMgr, sessionHandle); _this->mInitialized = true; ChipLogProgress(AppServer, - "HandleDeviceConnected created an instance of OperationalDeviceProxy for nodeId: %llu, fabricIndex: %d", + "HandleDeviceConnected created an instance of OperationalDeviceProxy for nodeId: %lu, fabricIndex: %d", _this->GetNodeId(), _this->GetFabricIndex()); if (_this->mOnConnectionSuccessClientCallback) @@ -87,7 +87,7 @@ class TargetVideoPlayerInfo { ChipLogError( AppServer, - "HandleDeviceConnectionFailure called for peerId.nodeId: %llu, peer.fabricIndex: %d with error: %" CHIP_ERROR_FORMAT, + "HandleDeviceConnectionFailure called for peerId.nodeId: %lu, peer.fabricIndex: %d with error: %" CHIP_ERROR_FORMAT, peerId.GetNodeId(), peerId.GetFabricIndex(), error.AsString()); TargetVideoPlayerInfo * _this = static_cast(context); _this->mDeviceProxy = chip::OperationalDeviceProxy();