23
23
#include < lib/support/CHIPJNIError.h>
24
24
#include < lib/support/JniReferences.h>
25
25
#include < lib/support/JniTypeWrappers.h>
26
+ #include < app/app-platform/ContentApp.h>
26
27
27
28
using namespace chip ;
28
29
using namespace chip ::app;
@@ -34,6 +35,9 @@ using namespace chip::Credentials;
34
35
* com.matter.tv.server.tvapp.AppPlatform class.
35
36
*/
36
37
38
+ // Forward declaration
39
+ std::vector<ContentApp::SupportedCluster> convert_to_cpp (JNIEnv* env, jobject supportedClusters);
40
+
37
41
#define JNI_METHOD (RETURN, METHOD_NAME ) \
38
42
extern " C" JNIEXPORT RETURN JNICALL Java_com_matter_tv_server_tvapp_AppPlatform_##METHOD_NAME
39
43
@@ -44,7 +48,8 @@ JNI_METHOD(void, nativeInit)(JNIEnv *, jobject app, jobject contentAppEndpointMa
44
48
}
45
49
46
50
JNI_METHOD (jint, addContentApp)
47
- (JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jobject manager)
51
+ (JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jobject supportedClusters,
52
+ jobject manager)
48
53
{
49
54
chip::DeviceLayer::StackLock lock;
50
55
JNIEnv * env = JniReferences::GetInstance ().GetEnvForCurrentThread ();
@@ -53,12 +58,12 @@ JNI_METHOD(jint, addContentApp)
53
58
JniUtfString aName (env, appName);
54
59
JniUtfString aVersion (env, appVersion);
55
60
EndpointId epId = AddContentApp (vName.c_str (), static_cast <uint16_t >(vendorId), aName.c_str (), static_cast <uint16_t >(productId),
56
- aVersion.c_str (), manager);
61
+ aVersion.c_str (), convert_to_cpp (env, supportedClusters), manager);
57
62
return static_cast <uint16_t >(epId);
58
63
}
59
64
60
65
JNI_METHOD (jint, addContentAppAtEndpoint)
61
- (JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jint endpointId,
66
+ (JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jobject supportedClusters, jint endpointId,
62
67
jobject manager)
63
68
{
64
69
chip::DeviceLayer::StackLock lock;
@@ -68,7 +73,7 @@ JNI_METHOD(jint, addContentAppAtEndpoint)
68
73
JniUtfString aName (env, appName);
69
74
JniUtfString aVersion (env, appVersion);
70
75
EndpointId epId = AddContentApp (vName.c_str (), static_cast <uint16_t >(vendorId), aName.c_str (), static_cast <uint16_t >(productId),
71
- aVersion.c_str (), static_cast <EndpointId>(endpointId), manager);
76
+ aVersion.c_str (), convert_to_cpp (env, supportedClusters), static_cast <EndpointId>(endpointId), manager);
72
77
return static_cast <uint16_t >(epId);
73
78
}
74
79
@@ -93,3 +98,77 @@ JNI_METHOD(void, addSelfVendorAsAdmin)
93
98
{
94
99
AddSelfVendorAsAdmin ();
95
100
}
101
+
102
+ std::vector<uint32_t > consume_and_convert_to_cpp (JNIEnv* env, jobject intArrayObject) {
103
+ std::vector<uint32_t > uintVector;
104
+ if (intArrayObject != nullptr ) {
105
+ jsize length = env->GetArrayLength (static_cast <jintArray>(intArrayObject));
106
+ jint* elements = env->GetIntArrayElements (static_cast <jintArray>(intArrayObject), nullptr );
107
+ if (elements != nullptr ) {
108
+ // OBS: Implicit type ambiguation from int32_t to uint32_t
109
+ uintVector.assign (elements, elements + length);
110
+ env->ReleaseIntArrayElements (static_cast <jintArray>(intArrayObject), elements, JNI_ABORT);
111
+ }
112
+ env->DeleteLocalRef (intArrayObject);
113
+ }
114
+ return uintVector;
115
+ }
116
+
117
+ std::vector<ContentApp::SupportedCluster> convert_to_cpp (JNIEnv* env, jobject supportedClustersObject) {
118
+ if (supportedClustersObject == nullptr || env == nullptr ) {
119
+ return {};
120
+ }
121
+
122
+ // Find Java classes. WARNING: Reflection
123
+ jclass collectionClass = env->FindClass (" java/util/Collection" );
124
+ jclass iteratorClass = env->FindClass (" java/util/Iterator" );
125
+ jclass clusterClass = env->FindClass (" com/matter/tv/server/tvapp/SupportedCluster" );
126
+ if (collectionClass == nullptr || iteratorClass == nullptr || clusterClass == nullptr ) {
127
+ return {};
128
+ }
129
+
130
+ // Find Java methods. WARNING: Reflection
131
+ jmethodID iteratorMethod = env->GetMethodID (collectionClass, " iterator" , " ()Ljava/util/Iterator;" );
132
+ jmethodID hasNextMethod = env->GetMethodID (iteratorClass, " hasNext" , " ()Z" );
133
+ jmethodID nextMethod = env->GetMethodID (iteratorClass, " next" , " ()Ljava/lang/Object;" );
134
+ if (iteratorMethod == nullptr || hasNextMethod == nullptr || nextMethod == nullptr ) {
135
+ return {};
136
+ }
137
+
138
+ // Find Java SupportedCluster fields. WARNING: Reflection
139
+ jfieldID clusterIdentifierField = env->GetFieldID (clusterClass, " clusterIdentifier" , " I" );
140
+ jfieldID featuresField = env->GetFieldID (clusterClass, " features" , " I" );
141
+ jfieldID optionalCommandIdentifiersField = env->GetFieldID (clusterClass, " optionalCommandIdentifiers" , " [I" );
142
+ jfieldID optionalAttributesIdentifiersField = env->GetFieldID (clusterClass, " optionalAttributesIdentifiers" , " [I" );
143
+ if (clusterIdentifierField == nullptr || featuresField == nullptr || optionalCommandIdentifiersField == nullptr || optionalAttributesIdentifiersField == nullptr ) {
144
+ return {};
145
+ }
146
+
147
+ // Find Set Iterator Object
148
+ jobject iteratorObject = env->CallObjectMethod (supportedClustersObject, iteratorMethod);
149
+ if (iteratorObject == nullptr ) {
150
+ return {};
151
+ }
152
+
153
+ // Iterate over the Java Collection and convert each SupportedCluster
154
+ std::vector<SupportedCluster> supportedClusters;
155
+ while (env->CallBooleanMethod (iteratorObject, hasNextMethod)) {
156
+ jobject clusterObject = env->CallObjectMethod (iteratorObject, nextMethod);
157
+ if (clusterObject != nullptr ) {
158
+ jint clusterIdentifier = env->GetIntField (clusterObject, clusterIdentifierField);
159
+ jint features = env->GetIntField (clusterObject, featuresField);
160
+ jobject commandIdsObject = env->GetObjectField (clusterObject, optionalCommandIdentifiersField);
161
+ jobject attributeIdsObject = env->GetObjectField (clusterObject, optionalAttributesIdentifiersField);
162
+ // OBS: Type ambiguation from int32_t to uint32_t
163
+ supportedClusters.emplace_back (
164
+ static_cast <ClusterId>(clusterIdentifier),
165
+ static_cast <uint32_t >(features),
166
+ consume_and_convert_to_cpp (env, commandIdsObject),
167
+ consume_and_convert_to_cpp (env, attributeIdsObject));
168
+ env->DeleteLocalRef (clusterObject);
169
+ }
170
+ }
171
+ env->DeleteLocalRef (iteratorObject);
172
+
173
+ return supportedClusters;
174
+ }
0 commit comments