From e3ba9259292dc2ee00f35ee05d4462a446fb31bf Mon Sep 17 00:00:00 2001 From: Sharad Binjola Date: Tue, 27 Sep 2022 14:00:04 -0700 Subject: [PATCH] Extending Media attribute subscriptions to iOS tv-casting-app/framework --- .../jni/com/chip/casting/TvCastingApp.java | 4 +- .../jni/cpp/MatterCallbackHandler-JNI.cpp | 3 +- .../app/src/main/jni/cpp/TvCastingApp-JNI.cpp | 17 +- .../project.pbxproj | 24 + .../CastingServerBridge.h | 496 ++++++++- .../CastingServerBridge.mm | 947 +++++++++++++++++- .../ContentLauncherTypes.h | 68 ++ .../ContentLauncherTypes.mm | 83 ++ .../MatterTvCastingBridge/MatterError.h | 33 + .../MatterTvCastingBridge/MatterError.mm | 39 + .../MediaPlaybackTypes.h | 39 + .../MediaPlaybackTypes.mm | 44 + .../TargetNavigatorTypes.h | 33 + .../TargetNavigatorTypes.mm | 43 + .../TvCasting.xcodeproj/project.pbxproj | 12 + .../TvCasting/ClusterSelectorView.swift | 54 + .../TvCasting/CommissioningView.swift | 2 +- .../TvCasting/CommissioningViewModel.swift | 4 +- .../TvCasting/TvCasting/MediaPlayerView.swift | 76 ++ .../TvCasting/MediaPlayerViewModel.swift | 77 ++ 20 files changed, 2035 insertions(+), 63 deletions(-) create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java index eb3a184b1ab3f8..27408a4934f637 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java @@ -17,6 +17,8 @@ */ package com.chip.casting; +import java.util.ArrayList; + public class TvCastingApp { private static final String TAG = TvCastingApp.class.getSimpleName(); @@ -178,7 +180,7 @@ public native boolean targetNavigator_subscribeToCurrentTarget( SubscriptionEstablishedCallback subscriptionEstablishedHandler); public native boolean targetNavigator_subscribeToTargetList( - SuccessCallback readSuccessHandler, + SuccessCallback> readSuccessHandler, FailureCallback readFailureHandler, int minInterval, int maxInterval, diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp index ef682b67da3d78..f9bbe7a649f531 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp @@ -307,7 +307,8 @@ jobject TargetListSuccessHandlerJNI::ConvertToJObject( } jmethodID constructor = env->GetMethodID(responseTypeClass, "", "(Ljava/lang/Integer;java/lang/String;)V"); - jobject jTargetInfo = env->NewObject(responseTypeClass, constructor, targetInfo.identifier, targetInfo.name); + chip::UtfString targetInfoName(env, targetInfo.name); + jobject jTargetInfo = env->NewObject(responseTypeClass, constructor, targetInfo.identifier, targetInfoName.jniValue()); chip::JniReferences::GetInstance().AddToList(jArrayList, jTargetInfo); } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp index 4edb41683f1962..cec6ec3c2962bc 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -173,7 +174,7 @@ CHIP_ERROR CreateParameter(JNIEnv * env, jobject jParameter, } CHIP_ERROR CreateContentSearch(JNIEnv * env, jobject jSearch, - chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type & search) + chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type & search, ListFreer & listFreer) { jclass jContentSearchClass; ReturnErrorOnFailure( @@ -192,18 +193,21 @@ CHIP_ERROR CreateContentSearch(JNIEnv * env, jobject jSearch, jmethodID jNextMid = env->GetMethodID(env->GetObjectClass(jIterator), "next", "()Ljava/lang/Object;"); jmethodID jHasNextMid = env->GetMethodID(env->GetObjectClass(jIterator), "hasNext", "()Z"); - chip::app::Clusters::ContentLauncher::Structs::Parameter::Type * parameterList = - new chip::app::Clusters::ContentLauncher::Structs::Parameter::Type[parameterListSize]; + auto * parameterListHolder = new ListHolder(parameterListSize); + listFreer.add(parameterListHolder); int parameterIndex = 0; while (env->CallBooleanMethod(jIterator, jHasNextMid)) { jobject jParameter = env->CallObjectMethod(jIterator, jNextMid); chip::app::Clusters::ContentLauncher::Structs::Parameter::Type parameter; ReturnErrorOnFailure(CreateParameter(env, jParameter, parameter)); - parameterList[parameterIndex++] = parameter; + parameterListHolder->mList[parameterIndex].type = parameter.type; + parameterListHolder->mList[parameterIndex].value = parameter.value; + parameterListHolder->mList[parameterIndex].externalIDList = parameter.externalIDList; + parameterIndex++; } search.parameterList = chip::app::DataModel::List( - parameterList, parameterListSize); + parameterListHolder->mList, parameterListSize); return CHIP_NO_ERROR; } @@ -221,8 +225,9 @@ JNI_METHOD(jboolean, contentLauncher_1launchContent) const char * nativeData = env->GetStringUTFChars(jData, 0); chip::Optional data = MakeOptional(CharSpan::fromCharString(nativeData)); + ListFreer listFreer; chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type search; - CHIP_ERROR err = CreateContentSearch(env, jSearch, search); + CHIP_ERROR err = CreateContentSearch(env, jSearch, search, listFreer); VerifyOrExit(CHIP_NO_ERROR == err, ChipLogError(AppServer, "contentLauncher_1launchContent::Could not create ContentSearch object %" CHIP_ERROR_FORMAT, 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 890346e0616d88..0a4ab42cb3c900 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj @@ -8,6 +8,9 @@ /* Begin PBXBuildFile section */ 3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */; }; + 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 */; }; 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, ); }; }; @@ -17,11 +20,18 @@ 3CCB8742286A593700771BAD /* DiscoveredNodeDataConverter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */; }; 3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873D286A593700771BAD /* CastingServerBridge.mm */; }; 3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */; }; + 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF8532628E37F1000F07B9F /* MatterError.mm */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OnboardingPayload.h; sourceTree = ""; }; 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardingPayload.m; sourceTree = ""; }; + 3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPlaybackTypes.mm; sourceTree = ""; }; + 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TargetNavigatorTypes.mm; sourceTree = ""; }; + 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 = ""; }; + 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 = ""; }; 3CCB8735286A555500771BAD /* libTvCastingCommon.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libTvCastingCommon.a; path = lib/libTvCastingCommon.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -32,6 +42,8 @@ 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiscoveredNodeDataConverter.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 = ""; }; + 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 */ /* Begin PBXFrameworksBuildPhase section */ @@ -77,6 +89,14 @@ 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */, 3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */, 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */, + 3CF8532528E37ED800F07B9F /* MatterError.h */, + 3CF8532628E37F1000F07B9F /* MatterError.mm */, + 3C4E53B428E5593700F293E8 /* ContentLauncherTypes.h */, + 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */, + 3CA1CA7728E243750023ED44 /* MediaPlaybackTypes.h */, + 3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */, + 3C4E53B328E5185F00F293E8 /* TargetNavigatorTypes.h */, + 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */, ); path = MatterTvCastingBridge; sourceTree = ""; @@ -185,7 +205,11 @@ buildActionMask = 2147483647; files = ( 3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */, + 3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */, + 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */, + 3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */, 3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */, + 3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */, 3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */, 3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */, ); diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h index 0bde8e593b2dfb..6d43a0d280c659 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h @@ -15,8 +15,12 @@ * limitations under the License. */ +#import "ContentLauncherTypes.h" #import "DiscoveredNodeData.h" +#import "MatterError.h" +#import "MediaPlaybackTypes.h" #import "OnboardingPayload.h" +#import "TargetNavigatorTypes.h" #import #ifndef CastingServerBridge_h @@ -24,26 +28,6 @@ @interface CastingServerBridge : NSObject -@property void (^_Nonnull commissioningCompleteCallback)(bool); - -@property void (^_Nonnull contentLauncher_launchUrlResponseCallback)(bool); -@property void (^_Nonnull levelControl_stepResponseCallback)(bool); -@property void (^_Nonnull levelControl_moveToLevelResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_playResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_pauseResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_stopPlaybackResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_nextResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_seekResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_skipForwardResponseCallback)(bool); -@property void (^_Nonnull mediaPlayback_skipBackwardResponseCallback)(bool); -@property void (^_Nonnull applicationLauncher_launchAppResponseCallback)(bool); -@property void (^_Nonnull applicationLauncher_stopAppResponseCallback)(bool); -@property void (^_Nonnull applicationLauncher_hideAppResponseCallback)(bool); -@property void (^_Nonnull targetNavigator_navigateTargetResponseCallback)(bool); -@property void (^_Nonnull keypadInput_sendKeyResponseCallback)(bool); - -@property OnboardingPayload * _Nonnull onboardingPayload; - + (CastingServerBridge * _Nullable)getSharedInstance; /*! @@ -110,7 +94,7 @@ commissioningWindowRequestedHandler:(void (^_Nonnull)(bool))commissioningWindowRequestedHandler; /*! - @brief Send a Content Launcher:LaunchURL request to a TV + @brief Send a ContentLauncher:LaunchURL request to a TV @param contentUrl URL of the content to launch on the TV @@ -128,6 +112,53 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; +/*! + @brief Send a ContentLauncher:LaunchContent request to a TV + + @param contentSearch Indicates the content to launch + + @param autoPlay Play Best match automatically if true, otherwise display matches + + @param data App specific data to be passed to the TV + + @param responseCallback Callback for when the response has been received + + @param clientQueue Queue to dispatch the call to the requestSentHandler on + + @param requestSentHandler Handler to call on sending the request + */ +- (void)contentLauncher_launchContent:(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; + +/*! + @brief Subscribe to ContentLauncher:SupportedStreamingProtocols + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint32_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + /*! @brief Send a LevelControl:Step request to a TV @@ -181,6 +212,81 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; +/*! + @brief Subscribe to LevelControl:CurrentLevel + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to LevelControl:MinLevel + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to LevelControl:MaxLevel + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + /*! @brief Send a MediaPlayback:Play request to a TV @@ -281,6 +387,180 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; +/*! + @brief Subscribe to MediaPlayback:CurrentState + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackState))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:StartTime + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:Duration + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:SampledPosition + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackPosition * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:PlaybackSpeed + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(float))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:SeekRangeEnd + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to MediaPlayback:SeekRangeStart + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; /*! @brief Send a ApplicationLauncher:LaunchApp request to a TV @@ -361,6 +641,56 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; +/*! + @brief Subscribe to TargetNavigator:TargetList + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSMutableArray * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to TargetNavigator:CurrentTarget + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + /*! @brief Send a KeypadInput:SendKey request to a TV @@ -379,6 +709,130 @@ clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler; +/*! + @brief Subscribe to ApplicationBasic:VendorName + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to ApplicationBasic:VendorID + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to ApplicationBasic:ApplicationName + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to ApplicationBasic:ProductID + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint16_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; + +/*! + @brief Subscribe to ApplicationBasic:ApplicationVersion + + @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 requestSentHandler Handler to call on sending the request + + @param successCallback Callback for when a read report is successfully received + + @param failureCallback Callback for when there is a failure in receiving a read report + + @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully + */ +- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback; @end #endif /* CastingServerBridge_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm index 2eccbf8242a0a9..c690e49af7ef7c 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm @@ -19,12 +19,14 @@ #import "CastingServer.h" #import "DiscoveredNodeDataConverter.hpp" +#import "MatterCallbacks.h" #import "OnboardingPayload.h" #include #include #include #include +#include #include #include #include @@ -34,6 +36,18 @@ @interface CastingServerBridge () // queue used to serialize all work performed by the CastingServerBridge @property (atomic, readonly) dispatch_queue_t chipWorkQueue; +@property OnboardingPayload * _Nonnull onboardingPayload; + +@property void (^_Nonnull commissioningCompleteCallback)(bool); + +@property NSMutableDictionary * commandResponseCallbacks; + +@property NSMutableDictionary * subscriptionEstablishedCallbacks; + +@property NSMutableDictionary * subscriptionReadSuccessCallbacks; + +@property NSMutableDictionary * subscriptionReadFailureCallbacks; + @end @implementation CastingServerBridge @@ -96,6 +110,11 @@ - (instancetype)init _chipWorkQueue = chip::DeviceLayer::PlatformMgrImpl().GetWorkQueue(); + _commandResponseCallbacks = [NSMutableDictionary dictionary]; + _subscriptionEstablishedCallbacks = [NSMutableDictionary dictionary]; + _subscriptionReadSuccessCallbacks = [NSMutableDictionary dictionary]; + _subscriptionReadFailureCallbacks = [NSMutableDictionary dictionary]; + chip::DeviceLayer::PlatformMgrImpl().StartEventLoopTask(); CastingServer::GetInstance()->Init(); @@ -209,11 +228,14 @@ - (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl { ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchUrl() called"); - _contentLauncher_launchUrlResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchUrl"]; + dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncherLaunchURL( [contentUrl UTF8String], [contentDisplayStr UTF8String], [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].contentLauncher_launchUrlResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"contentLauncher_launchUrl"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -221,6 +243,120 @@ - (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl }); } +- (void)contentLauncher_launchContent:(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"); + + [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchContent"]; + + // Make a copy of params before we go async. + contentSearch = [contentSearch copy]; + data = [data copy]; + + dispatch_async(_chipWorkQueue, ^{ + ListFreer listFreer; + chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type cppSearch; + if (contentSearch.parameterList.count > 0) { + auto * parameterListHolder + = new ListHolder(contentSearch.parameterList.count); + listFreer.add(parameterListHolder); + + int parameterIndex = 0; + for (ContentLauncher_Parameter * parameter in contentSearch.parameterList) { + int externalIdListIndex = 0; + if (parameter.externalIDList != nil) { + auto * externalIdListHolder + = new ListHolder( + parameter.externalIDList.count); + listFreer.add(externalIdListHolder); + + for (ContentLauncher_AdditionalInfo * additionalInfo in parameter.externalIDList) { + externalIdListHolder->mList[externalIdListIndex].value = chip::CharSpan([additionalInfo.value UTF8String], + [additionalInfo.value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + externalIdListHolder->mList[externalIdListIndex].name = chip::CharSpan([additionalInfo.name UTF8String], + [additionalInfo.name lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + externalIdListIndex++; + } + parameterListHolder->mList[parameterIndex].externalIDList = MakeOptional( + chip::app::DataModel::List( + externalIdListHolder->mList, parameter.externalIDList.count)); + } else { + parameterListHolder->mList[parameterIndex].externalIDList = chip::Optional>::Missing(); + } + + parameterListHolder->mList[parameterIndex].type + = static_cast(parameter.type); + parameterListHolder->mList[parameterIndex].value = chip::CharSpan( + [parameter.value UTF8String], [parameter.value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + parameterIndex++; + cppSearch.parameterList + = chip::app::DataModel::List( + parameterListHolder->mList, contentSearch.parameterList.count); + } + } + + CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_LaunchContent(cppSearch, autoPlay, + MakeOptional(chip::CharSpan([data UTF8String], [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding])), + [](CHIP_ERROR err) { + void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks + objectForKey:@"contentLauncher_launchContent"]; + responseCallback(CHIP_NO_ERROR == err); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler(CHIP_NO_ERROR == err); + }); + }); +} + +- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint32_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_subscribeSupportedStreamingProtocols() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback + forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_SubscribeToSupportedStreamingProtocols( + nullptr, + [](void * context, + chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo::DecodableArgType + supportedStreamingProtocols) { + void (^callback)(uint32_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + callback(supportedStreamingProtocols); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + - (void)levelControl_step:(uint8_t)stepMode stepSize:(uint8_t)stepSize transitionTime:(uint16_t)transitionTime @@ -232,12 +368,14 @@ - (void)levelControl_step:(uint8_t)stepMode { ChipLogProgress(AppServer, "CastingServerBridge().levelControl_step() called"); - _levelControl_stepResponseCallback = responseCallback; + [_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) { - [CastingServerBridge getSharedInstance].levelControl_stepResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_step"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -255,11 +393,13 @@ - (void)levelControl_moveToLevel:(uint8_t)level { ChipLogProgress(AppServer, "CastingServerBridge().levelControl_moveToLevel() called"); - _levelControl_moveToLevelResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"levelControl_moveToLevel"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_MoveToLevel( level, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].levelControl_moveToLevelResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_moveToLevel"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -267,16 +407,139 @@ - (void)levelControl_moveToLevel:(uint8_t)level }); } +- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeCurrentLevel() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeCurrentLevel"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeCurrentLevel"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeCurrentLevel"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToCurrentLevel( + nullptr, + [](void * context, + chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType currentLevel) { + void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"levelControl_subscribeCurrentLevel"]; + callback(@(currentLevel.Value())); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"levelControl_subscribeCurrentLevel"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"levelControl_subscribeCurrentLevel"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMinLevel() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMinLevel"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMinLevel"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMinLevel"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMinLevel( + nullptr, + [](void * context, chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType minLevel) { + void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"levelControl_subscribeMinLevel"]; + callback(minLevel); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"levelControl_subscribeMinLevel"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"levelControl_subscribeMinLevel"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMaxLevel() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMaxLevel"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMaxLevel"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMaxLevel"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMaxLevel( + nullptr, + [](void * context, chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType maxLevel) { + void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"levelControl_subscribeMaxLevel"]; + callback(maxLevel); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"levelControl_subscribeMaxLevel"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"levelControl_subscribeMaxLevel"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + - (void)mediaPlayback_play:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_play() called"); - _mediaPlayback_playResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_play"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Play([](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_playResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_play"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -290,10 +553,12 @@ - (void)mediaPlayback_pause:(void (^_Nonnull)(bool))responseCallback { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_pause() called"); - _mediaPlayback_pauseResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_pause"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Pause([](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_pauseResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_pause"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -307,10 +572,12 @@ - (void)mediaPlayback_stopPlayback:(void (^_Nonnull)(bool))responseCallback { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_stopPlayback() called"); - _mediaPlayback_pauseResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_stopPlayback"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_StopPlayback([](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_stopPlaybackResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_stopPlayback"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -324,10 +591,12 @@ - (void)mediaPlayback_next:(void (^_Nonnull)(bool))responseCallback { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_next() called"); - _mediaPlayback_nextResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_next"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Next([](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_nextResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_next"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -342,10 +611,12 @@ - (void)mediaPlayback_seek:(uint8_t)position { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_seek() called"); - _mediaPlayback_seekResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_seek"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Seek(position, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_seekResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_seek"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -360,10 +631,12 @@ - (void)mediaPlayback_skipForward:(uint64_t)deltaPositionMilliseconds { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipForward() called"); - _mediaPlayback_skipForwardResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipForward"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipForward(deltaPositionMilliseconds, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_skipForwardResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipForward"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -378,10 +651,12 @@ - (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds { ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipBackward() called"); - _mediaPlayback_skipBackwardResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipBackward"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipBackward(deltaPositionMilliseconds, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].mediaPlayback_skipBackwardResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipBackward"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -389,6 +664,305 @@ - (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds }); } +- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackState))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeCurrentState() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeCurrentState"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeCurrentState"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeCurrentState"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState( + nullptr, + [](void * context, + chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType currentState) { + void (^callback)(MediaPlayback_PlaybackState) = + [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeCurrentState"]; + callback(MediaPlayback_PlaybackState(currentState)); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeCurrentState"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeCurrentState"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeStartTime() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeStartTime"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeStartTime"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeStartTime"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToStartTime( + nullptr, + [](void * context, chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType startTime) { + void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeStartTime"]; + callback(@(startTime.Value())); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeStartTime"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeStartTime"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeDuration() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeDuration"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeDuration"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeDuration"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( + nullptr, + [](void * context, chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType startTime) { + void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeDuration"]; + callback(@(startTime.Value())); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeDuration"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeDuration"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackPosition * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSampledPosition() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSampledPosition"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToSampledPosition( + nullptr, + [](void * context, + chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType playbackPosition) { + void (^callback)(MediaPlayback_PlaybackPosition * _Nullable) = + [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeSampledPosition"]; + MediaPlayback_PlaybackPosition * objCPlaybackPosition = nil; + if (!playbackPosition.IsNull()) { + if (playbackPosition.Value().position.IsNull()) { + objCPlaybackPosition = + [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:@(playbackPosition.Value().updatedAt) + position:nil]; + } else { + objCPlaybackPosition = + [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:@(playbackPosition.Value().updatedAt) + position:@(playbackPosition.Value().position.Value())]; + } + callback(objCPlaybackPosition); + } + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeSampledPosition"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeSampledPosition"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(float))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribePlaybackSpeed() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToPlaybackSpeed( + nullptr, + [](void * context, + chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType playbackSpeed) { + void (^callback)(float) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribePlaybackSpeed"]; + callback(playbackSpeed); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribePlaybackSpeed"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribePlaybackSpeed"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeEnd() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( + nullptr, + [](void * context, + chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeEnd) { + void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + callback(@(seekRangeEnd.Value())); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeStart() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration( + nullptr, + [](void * context, + chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeStart) { + void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeStart"]; + callback(@(seekRangeStart.Value())); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeStart"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"mediaPlayback_subscribeSeekRangeStart"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId applicationId:(NSString * _Nonnull)applicationId data:(NSData * _Nullable)data @@ -398,7 +972,7 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId { ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_launchApp() called"); - _applicationLauncher_launchAppResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_launchApp"]; chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application; application.catalogVendorId = catalogVendorId; @@ -407,7 +981,9 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_LaunchApp(application, chip::MakeOptional(chip::ByteSpan(static_cast(data.bytes), data.length)), [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].applicationLauncher_launchAppResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks + objectForKey:@"applicationLauncher_launchApp"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -423,7 +999,7 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId { ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_stopApp() called"); - _applicationLauncher_stopAppResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_stopApp"]; chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application; application.catalogVendorId = catalogVendorId; @@ -431,7 +1007,9 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_StopApp(application, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].applicationLauncher_stopAppResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_stopApp"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -447,7 +1025,7 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId { ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_hideApp() called"); - _applicationLauncher_hideAppResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_hideApp"]; chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application; application.catalogVendorId = catalogVendorId; @@ -455,7 +1033,9 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_HideApp(application, [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].applicationLauncher_hideAppResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_hideApp"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -471,12 +1051,14 @@ - (void)targetNavigator_navigateTarget:(uint8_t)target { ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_navigateTarget() called"); - _targetNavigator_navigateTargetResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"targetNavigator_navigateTarget"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_NavigateTarget( target, chip::MakeOptional(chip::CharSpan::fromCharString([data UTF8String])), [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].targetNavigator_navigateTargetResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks + objectForKey:@"targetNavigator_navigateTarget"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -484,6 +1066,103 @@ - (void)targetNavigator_navigateTarget:(uint8_t)target }); } +- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSMutableArray *))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeTargetList() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeTargetList"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeTargetList"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeTargetList"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToTargetList( + nullptr, + [](void * context, + chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType targetList) { + void (^callback)(NSMutableArray *) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"targetNavigator_subscribeTargetList"]; + NSMutableArray * objCTargetList = nil; + size_t targetInfoCount; + targetList.ComputeSize(&targetInfoCount); + if (targetInfoCount > 0) { + objCTargetList = [NSMutableArray arrayWithCapacity:targetInfoCount]; + auto iter = targetList.begin(); + while (iter.Next()) { + const chip::app::Clusters::TargetNavigator::Structs::TargetInfo::DecodableType & targetInfo + = iter.GetValue(); + TargetNavigator_TargetInfo * objCTargetInfo = [[TargetNavigator_TargetInfo alloc] + initWithIdentifier:@(targetInfo.identifier) + name:[NSString stringWithUTF8String:targetInfo.name.data()]]; + [objCTargetList addObject:objCTargetInfo]; + } + } + callback(objCTargetList); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"targetNavigator_subscribeTargetList"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"targetNavigator_subscribeTargetList"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint8_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeCurrentTarget() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeCurrentTarget"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToCurrentTarget( + nullptr, + [](void * context, + chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType currentTarget) { + void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"targetNavigator_subscribeCurrentTarget"]; + callback(currentTarget); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"targetNavigator_subscribeCurrentTarget"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"targetNavigator_subscribeCurrentTarget"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + - (void)keypadInput_sendKey:(uint8_t)keyCode responseCallback:(void (^_Nonnull)(bool))responseCallback clientQueue:(dispatch_queue_t _Nonnull)clientQueue @@ -491,12 +1170,14 @@ - (void)keypadInput_sendKey:(uint8_t)keyCode { ChipLogProgress(AppServer, "CastingServerBridge().keypadInput_sendKey() called"); - _keypadInput_sendKeyResponseCallback = responseCallback; + [_commandResponseCallbacks setObject:responseCallback forKey:@"keypadInput_sendKey"]; dispatch_async(_chipWorkQueue, ^{ CHIP_ERROR err = CastingServer::GetInstance()->KeypadInput_SendKey( static_cast(keyCode), [](CHIP_ERROR err) { - [CastingServerBridge getSharedInstance].keypadInput_sendKeyResponseCallback(CHIP_NO_ERROR == err); + void (^responseCallback)(bool) = + [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"keypadInput_sendKey"]; + responseCallback(CHIP_NO_ERROR == err); }); dispatch_async(clientQueue, ^{ requestSentHandler(CHIP_NO_ERROR == err); @@ -504,4 +1185,210 @@ - (void)keypadInput_sendKey:(uint8_t)keyCode }); } +- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorName() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorName"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorName"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorName"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorName( + nullptr, + [](void * context, + chip::app::Clusters::ApplicationBasic::Attributes::VendorName::TypeInfo::DecodableArgType vendorName) { + void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"applicationBasic_subscribeVendorName"]; + callback([NSString stringWithUTF8String:vendorName.data()]); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"applicationBasic_subscribeVendorName"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"applicationBasic_subscribeVendorName"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSNumber * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorID() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorID"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorID"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorID"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorID( + nullptr, + [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::VendorID::TypeInfo::DecodableArgType vendorID) { + void (^callback)(NSNumber * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"applicationBasic_subscribeVendorID"]; + callback(@(vendorID)); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"applicationBasic_subscribeVendorID"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"applicationBasic_subscribeVendorID"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationName() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationName"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationName"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback + forKey:@"applicationBasic_subscribeApplicationName"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationName( + nullptr, + [](void * context, + chip::app::Clusters::ApplicationBasic::Attributes::ApplicationName::TypeInfo::DecodableArgType applicationName) { + void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"applicationBasic_subscribeApplicationName"]; + callback([NSString stringWithUTF8String:applicationName.data()]); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"applicationBasic_subscribeApplicationName"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"applicationBasic_subscribeApplicationName"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(uint16_t))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeProductID() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeProductID"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeProductID"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeProductID"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToProductID( + nullptr, + [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::ProductID::TypeInfo::DecodableArgType productID) { + void (^callback)(uint16_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"applicationBasic_subscribeProductID"]; + callback(productID); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"applicationBasic_subscribeProductID"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"applicationBasic_subscribeProductID"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + +- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval + maxInterval:(uint16_t)maxInterval + clientQueue:(dispatch_queue_t _Nonnull)clientQueue + requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler + successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback + failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback + subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback +{ + ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationVersion() called"); + + [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationVersion"]; + [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationVersion"]; + [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback + forKey:@"applicationBasic_subscribeApplicationVersion"]; + + dispatch_async(_chipWorkQueue, ^{ + CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationVersion( + nullptr, + [](void * context, + chip::app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::TypeInfo::DecodableArgType + applicationVersion) { + void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks + objectForKey:@"applicationBasic_subscribeApplicationVersion"]; + callback([NSString stringWithUTF8String:applicationVersion.data()]); + }, + [](void * context, CHIP_ERROR err) { + void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks + objectForKey:@"applicationBasic_subscribeApplicationVersion"]; + callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]); + }, + minInterval, maxInterval, + [](void * context) { + void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks + objectForKey:@"applicationBasic_subscribeApplicationVersion"]; + callback(); + }); + dispatch_async(clientQueue, ^{ + requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger() + message:[NSString stringWithUTF8String:err.AsString()]]); + }); + }); +} + @end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h new file mode 100644 index 00000000000000..49f44df70a4b11 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h @@ -0,0 +1,68 @@ +/** + * + * 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 + +#ifndef ContentLauncherTypes_h +#define ContentLauncherTypes_h + +typedef NS_ENUM(uint8_t, ContentLauncher_ParameterEnum) { + Actor = 0x00, + Channel = 0x01, + Character = 0x02, + Director = 0x03, + Event = 0x04, + Franchise = 0x05, + Genre = 0x06, + League = 0x07, + Popularity = 0x08, + Provider = 0x09, + Sport = 0x10, + SportsTeam = 0x11, + Type = 0x12, + Video = 0x13, +}; + +@interface ContentLauncher_AdditionalInfo : NSObject + +@property (nonatomic, copy) NSString * _Nonnull name; +@property (nonatomic, copy) NSString * _Nonnull value; + +- (ContentLauncher_AdditionalInfo * _Nonnull)initWithName:(NSString * _Nonnull)name value:(NSString * _Nonnull)value; +- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone; +@end + +@interface ContentLauncher_Parameter : NSObject + +@property (nonatomic) ContentLauncher_ParameterEnum type; +@property (nonatomic, copy) NSString * _Nonnull value; +@property (nonatomic, copy) NSArray * _Nullable externalIDList; + +- (ContentLauncher_Parameter * _Nonnull)initWithType:(ContentLauncher_ParameterEnum)type + value:(NSString * _Nonnull)value + externalIDList:(NSArray * _Nullable)externalIDList; +- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone; +@end + +@interface ContentLauncher_ContentSearch : NSObject + +@property (nonatomic, copy) NSArray * _Nonnull parameterList; + +- (ContentLauncher_ContentSearch * _Nonnull)initWithParameterList:(NSArray * _Nonnull)parameterList; +- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone; +@end +#endif /* ContentLauncherTypes_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm new file mode 100644 index 00000000000000..958de58b054476 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm @@ -0,0 +1,83 @@ +/** + * + * 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 "ContentLauncherTypes.h" + +@implementation ContentLauncher_AdditionalInfo +- (ContentLauncher_AdditionalInfo * _Nonnull)initWithName:(NSString * _Nonnull)name value:(NSString * _Nonnull)value +{ + self = [super init]; + if (self) { + _name = name; + _value = value; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"ContentLauncher_AdditionalInfo: name=%@ value=%@", _name, _value]; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + return [[ContentLauncher_AdditionalInfo alloc] initWithName:_name value:_value]; +} +@end + +@implementation ContentLauncher_Parameter +- (ContentLauncher_Parameter * _Nonnull)initWithType:(ContentLauncher_ParameterEnum)type + value:(NSString * _Nonnull)value + externalIDList:(NSArray * _Nullable)externalIDList +{ + self = [super init]; + if (self) { + _type = type; + _value = value; + _externalIDList = externalIDList; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"ContentLauncher_Parameter: type=%hhu value=%@", _type, _value]; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + return [[ContentLauncher_Parameter alloc] initWithType:_type value:_value externalIDList:_externalIDList]; +} +@end + +@implementation ContentLauncher_ContentSearch +- (ContentLauncher_ContentSearch * _Nonnull)initWithParameterList:(NSArray * _Nonnull)parameterList +{ + self = [super init]; + if (self) { + _parameterList = parameterList; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + return [[ContentLauncher_ContentSearch alloc] initWithParameterList:_parameterList]; +} +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h new file mode 100644 index 00000000000000..ec018725294162 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h @@ -0,0 +1,33 @@ +/** + * + * 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 + +#ifndef MatterError_h +#define MatterError_h + +@interface MatterError : NSObject + +@property uint32_t code; + +@property NSString * _Nullable message; + +- (MatterError * _Nonnull)initWithCode:(uint32_t)code message:(NSString * _Nullable)message; + +@end + +#endif /* MatterError_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm new file mode 100644 index 00000000000000..ce700e5a80338a --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm @@ -0,0 +1,39 @@ +/** + * + * 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 "MatterError.h" + +@implementation MatterError + +- (MatterError *)initWithCode:(uint32_t)code message:(NSString * _Nullable)message +{ + self = [super init]; + if (self) { + _code = code; + _message = message; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"MatterError: code=%d message=%@", _code, _message]; +} + +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h new file mode 100644 index 00000000000000..f316d75cc43c6b --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h @@ -0,0 +1,39 @@ +/** + * + * 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 + +#ifndef MediaPlaybackTypes_h +#define MediaPlaybackTypes_h + +typedef NS_ENUM(uint8_t, MediaPlayback_PlaybackState) { + Playing = 0x00, + Paused = 0x01, + NotPlaying = 0x02, + Buffering = 0x03, +}; + +@interface MediaPlayback_PlaybackPosition : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull updatedAt; +@property (nonatomic, copy) NSNumber * _Nullable position; + +- (MediaPlayback_PlaybackPosition * _Nonnull)initWithUpdatedAt:(NSNumber * _Nonnull)updatedAt + position:(NSNumber * _Nullable)position; +- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone; +@end + +#endif /* MediaPlaybackTypes_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm new file mode 100644 index 00000000000000..6c0eb428c63b9e --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm @@ -0,0 +1,44 @@ +/** + * + * 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 "MediaPlaybackTypes.h" + +@implementation MediaPlayback_PlaybackPosition + +- (MediaPlayback_PlaybackPosition * _Nonnull)initWithUpdatedAt:(NSNumber * _Nonnull)updatedAt + position:(NSNumber * _Nullable)position +{ + self = [super init]; + if (self) { + _updatedAt = updatedAt; + _position = position; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"MediaPlayback_PlaybackPosition: updatedAt=%@ position=%@", _updatedAt, _position]; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + return [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:_updatedAt position:_position]; +} +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h new file mode 100644 index 00000000000000..c00eba2edcfdb8 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h @@ -0,0 +1,33 @@ +/** + * + * 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 + +#ifndef TargetNavigatorTypes_h +#define TargetNavigatorTypes_h + +@interface TargetNavigator_TargetInfo : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull identifier; +@property (nonatomic, copy) NSString * _Nonnull name; + +- (TargetNavigator_TargetInfo * _Nonnull)initWithIdentifier:(NSNumber * _Nonnull)identifier name:(NSString * _Nonnull)name; + +- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone; +@end + +#endif /* TargetNavigatorTypes_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm new file mode 100644 index 00000000000000..5f3447d7165674 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm @@ -0,0 +1,43 @@ +/** + * + * 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 "TargetNavigatorTypes.h" + +@implementation TargetNavigator_TargetInfo + +- (TargetNavigator_TargetInfo * _Nonnull)initWithIdentifier:(NSNumber * _Nonnull)identifier name:(NSString * _Nonnull)name +{ + self = [super init]; + if (self) { + _identifier = identifier; + _name = name; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"TargetNavigator_TargetInfo: identifier=%@ name=%@", _identifier, _name]; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + return [[TargetNavigator_TargetInfo alloc] initWithIdentifier:_identifier name:_name]; +} +@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 05feeae4cb6e5c..ed740398a117f4 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 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 */; }; 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 */; }; @@ -43,6 +46,9 @@ 3C7507B82853EFF000D7DB3A /* CommissioningViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissioningViewModel.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 = ""; }; 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 = ""; }; @@ -101,8 +107,11 @@ 3C7507B62853A3AD00D7DB3A /* CommissionerDiscoveryViewModel.swift */, 3C7507AE28529A5F00D7DB3A /* CommissioningView.swift */, 3C7507B82853EFF000D7DB3A /* CommissioningViewModel.swift */, + 3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */, 3CA19434285BA780004768D5 /* ContentLauncherView.swift */, 3CA19436285BA877004768D5 /* ContentLauncherViewModel.swift */, + 3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */, + 3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */, 3CC0E8FF2841DD3500EC6A18 /* Preview Content */, ); path = TvCasting; @@ -201,11 +210,14 @@ files = ( 3CCB8745286A5D0F00771BAD /* CommissionerDiscoveryView.swift in Sources */, 3CCB8746286A5D0F00771BAD /* CommissionerDiscoveryViewModel.swift in Sources */, + 3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */, 3CCB8747286A5D0F00771BAD /* CommissioningView.swift in Sources */, 3CCB8748286A5D0F00771BAD /* CommissioningViewModel.swift in Sources */, + 3CA1CA7E28E284950023ED44 /* MediaPlayerViewModel.swift in Sources */, 3CCB8749286A5D0F00771BAD /* ContentLauncherView.swift in Sources */, 3CCB874A286A5D0F00771BAD /* ContentLauncherViewModel.swift in Sources */, 3CC0E8FC2841DD3400EC6A18 /* ContentView.swift in Sources */, + 3CA1CA7C28E282150023ED44 /* MediaPlayerView.swift in Sources */, 3CC0E8FA2841DD3400EC6A18 /* TvCastingApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift new file mode 100644 index 00000000000000..d7285e82ec1a2b --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift @@ -0,0 +1,54 @@ +/** + * + * 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 ClusterSelectorView: View { + var body: some View { + VStack(alignment: .leading) { + NavigationLink( + destination: ContentLauncherView(), + label: { + Text("Content Launcher") + .frame(width: 300, height: 30, alignment: .center) + .border(Color.black, width: 1) + } + ).background(Color.blue) + .foregroundColor(Color.white) + .padding() + + NavigationLink( + destination: MediaPlayerView(), + label: { + Text("Media Playback") + .frame(width: 300, height: 30, alignment: .center) + .border(Color.black, width: 1) + } + ).background(Color.blue) + .foregroundColor(Color.white) + .padding() + } + .navigationTitle("Cluster selection") + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top) + } +} + +struct ClusterSelectorView_Previews: PreviewProvider { + static var previews: some View { + ClusterSelectorView() + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift index b246a3bda45e50..23cee1eb7d341b 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift @@ -66,7 +66,7 @@ struct CommissioningView: View { { Text("Commissioning finished!").padding() NavigationLink( - destination: ContentLauncherView(), + destination: ClusterSelectorView(), label: { Text("Next") .frame(width: 100, height: 30, alignment: .center) diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift index 3f2d4404d3aa81..5af7d263133557 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift @@ -45,9 +45,7 @@ class CommissioningViewModel: ObservableObject { self.commisisoningWindowOpened = result }) } - - // TBD: Get Onboarding payload - + // Send User directed commissioning request if a commissioner with a known IP addr was selected if(selectedCommissioner != nil && selectedCommissioner!.numIPs > 0) { diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift new file mode 100644 index 00000000000000..296b0a78607f9a --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift @@ -0,0 +1,76 @@ +/** + * + * 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 new file mode 100644 index 00000000000000..d401d3f5247d5b --- /dev/null +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift @@ -0,0 +1,77 @@ +/** + * + * 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!" + } + } + ) + } + } +}