From bd70f6ea5210332bbd1cb21ab043d493ecdccb03 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:19:03 +0100 Subject: [PATCH 01/24] feat: add new class - StreamEncryptionMode --- .../endpoint/wrapper/streams/parsers/parser.h | 3 +++ .../src/cpp/streams/parsers/parser.cpp | 20 +++++++++++++++++++ .../streams/model/StreamEncryptionMode.java | 6 ++++++ 3 files changed, 29 insertions(+) create mode 100644 privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamEncryptionMode.java diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/parser.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/parser.h index f9421230..c916db46 100644 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/parser.h +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/parser.h @@ -17,6 +17,7 @@ #include "privmx/endpoint/wrapper/streams/modules/StreamSettingsJNI.h" #include #include "model_native_initializers.h" +#include "privmx/endpoint/stream/Types.hpp" // streams privmx::endpoint::stream::DeviceType parseDeviceType(JniContextUtils &ctx, jobject type); @@ -31,4 +32,6 @@ privmx::endpoint::stream::StreamSettings parseStreamSettings(JNIEnv *env, jobjec privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextUtils &ctx, jobject streamSubscription); +privmx::endpoint::stream::StreamEncryptionMode parseStreamEncryptionMode(JniContextUtils &ctx, jobject streamEncryptionMode); + //#endif //PRIVMX_POCKET_LIB_PARSER_H diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp index 5edbfa33..8d49ceb0 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp @@ -103,4 +103,24 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU if(streamTrackId != nullptr) result.streamTrackId = jobject2string(ctx, streamTrackId); return result; +} + +privmx::endpoint::stream::StreamEncryptionMode parseStreamEncryptionMode( + JniContextUtils &ctx, + jobject streamEncryptionMode +) { + jclass cls = ctx->GetObjectClass(streamEncryptionMode); + jmethodID nameFID = ctx->GetMethodID( + cls, + "name", + "()Ljava/lang/String;" + ); + + auto name_j = (jstring) ctx->CallObjectMethod(streamEncryptionMode, nameFID); + std::string name_c = ctx.jString2string(name_j); + + if (name_c == "SINGLE_KEY") return privmx::endpoint::stream::StreamEncryptionMode::SINGLE_KEY; + if (name_c == "MULTIPLE_KEY") return privmx::endpoint::stream::StreamEncryptionMode::MULTIPLE_KEY; + + return {}; } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamEncryptionMode.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamEncryptionMode.java new file mode 100644 index 00000000..c8c9fc50 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamEncryptionMode.java @@ -0,0 +1,6 @@ +package com.simplito.java.privmx_endpoint.streams.model; + +public enum StreamEncryptionMode { + SINGLE_KEY, + MULTIPLE_KEY +} From cf4164bea5fa9b76f6aea2dd83a9f8d9c57b2434 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:30:30 +0100 Subject: [PATCH 02/24] feat: add new parameter to streamApiLow create method --- .../src/cpp/streams/modules/StreamApiLow.cpp | 3 +- .../privmx_endpoint/streams/StreamApiLow.java | 44 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index 0c13221f..f980b8e0 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -68,7 +68,8 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_create( JNIEnv *env, jclass clazz, jobject connection, - jobject eventApi + jobject eventApi, + jobject stream_encryption_mode ) { JniContextUtils ctx(env); if (ctx.nullCheck(connection, "Connection")) { diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index d4e398f6..17718af6 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -14,12 +14,10 @@ import com.simplito.java.privmx_endpoint.model.ContainerPolicy; import com.simplito.java.privmx_endpoint.model.PagingList; import com.simplito.java.privmx_endpoint.model.UserWithPubKey; -import com.simplito.java.privmx_endpoint.streams.model.events.eventSelectorTypes.StreamEventSelectorType; -import com.simplito.java.privmx_endpoint.streams.model.events.eventTypes.StreamEventType; import com.simplito.java.privmx_endpoint.modules.core.Connection; import com.simplito.java.privmx_endpoint.modules.event.EventApi; -import com.simplito.java.privmx_endpoint.streams.model.SdpWithTypeModel; import com.simplito.java.privmx_endpoint.streams.model.Settings; +import com.simplito.java.privmx_endpoint.streams.model.StreamEncryptionMode; import com.simplito.java.privmx_endpoint.streams.model.StreamHandle; import com.simplito.java.privmx_endpoint.streams.model.StreamInfo; import com.simplito.java.privmx_endpoint.streams.model.StreamPublishResult; @@ -50,33 +48,41 @@ private StreamApiLow(Long api) { private static native StreamApiLow create( Connection connection, - EventApi eventApi + EventApi eventApi, + StreamEncryptionMode streamEncryptionMode ); - public StreamApiLow( - Connection connection - ) throws IllegalStateException { - this(connection, null); - } - public StreamApiLow( Connection connection, - EventApi eventApi + EventApi eventApi, + StreamEncryptionMode streamEncryptionMode ) throws IllegalStateException { Objects.requireNonNull(connection); EventApi tmpEventApi = eventApi == null ? new EventApi(connection) : null; - StreamApiLow streamApiLow = create( + create( connection, - Optional.ofNullable(eventApi).orElse(tmpEventApi) + Optional.ofNullable(eventApi).orElse(tmpEventApi), + streamEncryptionMode ); -// api = streamApiLow.api; - try { if (eventApi != null) tmpEventApi.close(); } catch (Exception ignore) { } } + public StreamApiLow( + Connection connection, + EventApi eventApi + ) throws IllegalStateException { + this(connection, eventApi, StreamEncryptionMode.SINGLE_KEY); + } + + public StreamApiLow( + Connection connection + ) throws IllegalStateException { + this(connection, null, StreamEncryptionMode.SINGLE_KEY); + } + public native List getTurnCredentials(); public String createStreamRoom( @@ -141,7 +147,7 @@ public PagingList listStreamRooms( String sortOrder, String lastId, String sortBy - ){ + ) { return listStreamRooms(contextId, skip, limit, sortOrder, lastId, sortBy, null); } @@ -151,7 +157,7 @@ public PagingList listStreamRooms( long limit, String sortOrder, String lastId - ){ + ) { return listStreamRooms(contextId, skip, limit, sortOrder, lastId, null, null); } @@ -160,7 +166,7 @@ public PagingList listStreamRooms( long skip, long limit, String sortOrder - ){ + ) { return listStreamRooms(contextId, skip, limit, sortOrder, null, null, null); } @@ -168,7 +174,7 @@ public PagingList listStreamRooms( String contextId, long skip, long limit - ){ + ) { return listStreamRooms(contextId, skip, limit, "desc", null, null, null); } From 4cc36e2b295a68c833e9920537b2da48c37420ab Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:36:19 +0100 Subject: [PATCH 03/24] feat: add new method to streamApiLow - createStreamRoomEx --- .../src/cpp/streams/modules/StreamApiLow.cpp | 61 +++++++++++++++++++ .../privmx_endpoint/streams/StreamApiLow.java | 23 ++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index f980b8e0..da333995 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -838,4 +838,65 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_subscribeToRemoteSt parseSettings(ctx, options) ); }); +} +extern "C" +JNIEXPORT jstring JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( + JNIEnv *env, + jobject thiz, + jstring context_id, + jobject users, + jobject managers, + jbyteArray public_meta, + jbyteArray private_meta, + jstring type, + jobject policies +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(context_id, "Context ID") || + ctx.nullCheck(users, "Users list") || + ctx.nullCheck(managers, "Managers list") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + + jstring result; + ctx.callResultEndpointApi( + &result, + [ + &ctx, + &thiz, + context_id, + &users, + &managers, + &public_meta, + &private_meta, + &type, + &policies + ]() { + std::vector users_c = usersToVector( + ctx, + ctx.jObject2jArray(users)); + std::vector managers_c = usersToVector( + ctx, + ctx.jObject2jArray(managers)); + auto container_policies_c = std::optional( + parseContainerPolicy(ctx, policies)); + return ctx->NewStringUTF( + getStreamApi(ctx, thiz)->createStreamRoomEx( + ctx.jString2string(context_id), + users_c, + managers_c, + core::Buffer::from(ctx.jByteArray2String(public_meta)), + core::Buffer::from(ctx.jByteArray2String(private_meta)), + ctx.jString2string(type), + container_policies_c + ).c_str()); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index 17718af6..f99a9735 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -74,7 +74,7 @@ public StreamApiLow( Connection connection, EventApi eventApi ) throws IllegalStateException { - this(connection, eventApi, StreamEncryptionMode.SINGLE_KEY); + this(connection, eventApi, StreamEncryptionMode.SINGLE_KEY); } public StreamApiLow( @@ -104,6 +104,27 @@ public native String createStreamRoom( ContainerPolicy policies ); + public native String createStreamRoomEx( + String contextId, + List users, + List managers, + byte[] publicMeta, + byte[] privateMeta, + String type, + ContainerPolicy policies + ); + + public String createStreamRoomEx( + String contextId, + List users, + List managers, + byte[] publicMeta, + byte[] privateMeta, + String type + ) { + return this.createStreamRoomEx(contextId, users, managers, publicMeta, privateMeta, type, null); + } + //TODO: write methods with default values for force and forceGenerateNewKey parameters public void updateStreamRoom( String streamRoomId, From e826c12b8a72086441d33d3b6e775cd63a889044 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:39:44 +0100 Subject: [PATCH 04/24] feat: add new method to streamApiLow - getStreamRoomEx --- .../src/cpp/streams/modules/StreamApiLow.cpp | 29 +++++++++++++++++++ .../privmx_endpoint/streams/StreamApiLow.java | 2 ++ 2 files changed, 31 insertions(+) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index da333995..03556eb6 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -899,4 +899,33 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( return nullptr; } return result; +} +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jstring type +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + jobject result; + ctx.callResultEndpointApi(&result, [&ctx, &thiz, &stream_room_id, &type] { + + return privmx::wrapper::streams::streamRoom2Java( + ctx, + getStreamApi(ctx, thiz)->getStreamRoomEx( + ctx.jString2string(stream_room_id), + ctx.jString2string(type) + ) + ); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index f99a9735..33e0ac53 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -201,6 +201,8 @@ public PagingList listStreamRooms( public native StreamRoom getStreamRoom(String streamRoomId); + public native StreamRoom getStreamRoomEx(String streamRoomId, String type); + public native void deleteStreamRoom(String streamRoomId); // Stream From f5854f850af3a36dfa05ff4d235eb970c78c04cd Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:46:19 +0100 Subject: [PATCH 05/24] feat: add new method to streamApiLow - listStreamRoomsEx --- .../src/cpp/streams/modules/StreamApiLow.cpp | 95 +++++++++++++++++++ .../privmx_endpoint/streams/StreamApiLow.java | 44 +++++++++ 2 files changed, 139 insertions(+) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index 03556eb6..5ee46824 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -928,4 +928,99 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( return nullptr; } return result; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( + JNIEnv *env, + jobject thiz, + jstring context_id, + jlong skip, + jlong limit, + jstring sort_order, + jstring type, + jstring last_id, + jstring sort_by, + jstring query_as_json +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(context_id, "Context ID") || + ctx.nullCheck(sort_order, "Sort order") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + + jobject result; + ctx.callResultEndpointApi( + &result, + [ + &ctx, + &env, + &thiz, + &context_id, + &skip, + &limit, + &sort_order, + &last_id, + &sort_by, + &query_as_json, + &type + ]() { + jclass pagingListCls = env->FindClass( + "com/simplito/java/privmx_endpoint/model/PagingList"); + jmethodID pagingListInitMID = env->GetMethodID( + pagingListCls, "", + "(Ljava/lang/Long;Ljava/util/List;)V"); + jclass arrayCls = env->FindClass("java/util/ArrayList"); + jmethodID initArrayMID = env->GetMethodID(arrayCls, + "", + "()V"); + jmethodID addToArrayMID = env->GetMethodID(arrayCls, + "add", + "(Ljava/lang/Object;)Z"); + auto query = core::PagingQuery(); + query.skip = skip; + query.limit = limit; + query.sortOrder = ctx.jString2string(sort_order); + + if (last_id != nullptr) { + query.lastId = ctx.jString2string(last_id); + } + if (sort_by != nullptr) { + query.sortBy = ctx.jString2string(sort_by); + } + if (query_as_json != nullptr) { + query.queryAsJson = ctx.jString2string(query_as_json); + } + + auto streamRooms_c( + getStreamApi(ctx, thiz)->listStreamRoomsEx( + ctx.jString2string(context_id), + query, + ctx.jString2string(type) + ) + ); + jobject array = env->NewObject(arrayCls, initArrayMID); + for (auto &streamRoom_c: streamRooms_c.readItems) { + env->CallBooleanMethod(array, + addToArrayMID, + privmx::wrapper::streams::streamRoom2Java( + ctx, + streamRoom_c + ) + ); + } + return ctx->NewObject( + pagingListCls, + pagingListInitMID, + ctx.long2jLong(streamRooms_c.totalAvailable), + array + ); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index 33e0ac53..29743dd3 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -199,6 +199,50 @@ public PagingList listStreamRooms( return listStreamRooms(contextId, skip, limit, "desc", null, null, null); } + public native PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId, + String sortBy, + String queryAsJson + ); + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId, + String sortBy + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, lastId, sortBy, null); + } + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, lastId, null, null); + } + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, null, null, null); + } + public native StreamRoom getStreamRoom(String streamRoomId); public native StreamRoom getStreamRoomEx(String streamRoomId, String type); From 5f8665b0c8a5156b36a5d83ce077e2ed6b2ff8a0 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 11 Feb 2026 13:49:46 +0100 Subject: [PATCH 06/24] feat: add new method to streamApiLow - enableStreamRoomRecording --- .../src/cpp/streams/modules/StreamApiLow.cpp | 21 ++++++++++++++++++- .../privmx_endpoint/streams/StreamApiLow.java | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index 5ee46824..6a77519d 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -316,7 +316,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRooms( privmx::wrapper::streams::streamRoom2Java( ctx, streamRoom_c - ) + ) ); } return ctx->NewObject( @@ -1023,4 +1023,23 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( return nullptr; } return result; +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_enableStreamRoomRecording( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id]() { + getStreamApi(ctx, thiz)->enableStreamRoomRecording( + ctx.jString2string(stream_room_id) + ); + }); } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index 29743dd3..bca2c31c 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -306,6 +306,8 @@ public native StreamHandle createStream( public native void keyManagement(String streamRoomId, boolean disable); + public native void enableStreamRoomRecording(String streamRoomId); + private native void deinit() throws IllegalStateException; @Override From 433d76a3cd5af7a946ca13771fcd8d62188b2195 Mon Sep 17 00:00:00 2001 From: Doominika Date: Thu, 12 Feb 2026 11:23:44 +0100 Subject: [PATCH 07/24] feat: add new class - RecordingEncKey --- .../parsers/model_native_initializers.h | 3 ++ .../parsers/model_native_initializers.cpp | 31 +++++++++++++++++++ .../streams/model/RecordingEncKey.java | 13 ++++++++ 3 files changed, 47 insertions(+) create mode 100644 privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey.java diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h index 772c19dc..1ea1f6f4 100644 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h @@ -63,6 +63,9 @@ namespace privmx { jobject sdpWithTypeModel2Java(JniContextUtils &ctx, privmx::endpoint::stream::SdpWithTypeModel sdpWithTypeModel_c); + + jobject + recordingEncKey2Java(JniContextUtils &ctx, privmx::endpoint::stream::RecordingEncKey recordingEncKey_c); } // streams } // wrapper } // privmx diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp index aafeddad..472e56cf 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp @@ -455,6 +455,37 @@ namespace privmx { ); } + jobject recordingEncKey2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::RecordingEncKey recordingEncKey_c + ){ + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "[B" // id + "[B" // key + ")V" + ); + + jbyteArray id = ctx->NewByteArray(recordingEncKey_c.id.size()); + jbyteArray key = ctx->NewByteArray(recordingEncKey_c.key.size()); + + ctx->SetByteArrayRegion(id, 0, recordingEncKey_c.id.size(), + (jbyte *) recordingEncKey_c.id.data()); + ctx->SetByteArrayRegion(key, 0, recordingEncKey_c.key.size(), + (jbyte *) recordingEncKey_c.key.data()); + + return ctx->NewObject( + itemCls, + initItemMID, + id, + key + ); + } jobject remoteStreamId2Java( JniContextUtils &ctx, diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey.java new file mode 100644 index 00000000..8b229c60 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.streams.model; + +import jdk.internal.util.ByteArray; + +public class RecordingEncKey { + public ByteArray id; + public ByteArray key; + + public RecordingEncKey(ByteArray id, ByteArray key) { + this.id = id; + this.key = key; + } +} \ No newline at end of file From 2afeb9356c772520ff06f9d81411cbe9627346e9 Mon Sep 17 00:00:00 2001 From: Doominika Date: Thu, 12 Feb 2026 11:24:00 +0100 Subject: [PATCH 08/24] feat: add new method to streamApiLow - getStreamRoomRecordingKeys --- .../src/cpp/streams/modules/StreamApiLow.cpp | 27 +++++++++++++++++++ .../privmx_endpoint/streams/StreamApiLow.java | 3 +++ 2 files changed, 30 insertions(+) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp index 6a77519d..bd25de68 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -1042,4 +1042,31 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_enableStreamRoomRec ctx.jString2string(stream_room_id) ); }); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomRecordingKeys( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + jobject result; + + ctx.callResultEndpointApi(&result, [&ctx, &env, &thiz, &stream_room_id] { + auto keys = getStreamApi(ctx, thiz)->getStreamRoomRecordingKeys( + ctx.jString2string(stream_room_id) + ); + + return vectorTojArray( + ctx, + keys, + privmx::wrapper::streams::recordingEncKey2Java + ); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java index bca2c31c..e06a9ad0 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/StreamApiLow.java @@ -16,6 +16,7 @@ import com.simplito.java.privmx_endpoint.model.UserWithPubKey; import com.simplito.java.privmx_endpoint.modules.core.Connection; import com.simplito.java.privmx_endpoint.modules.event.EventApi; +import com.simplito.java.privmx_endpoint.streams.model.RecordingEncKey; import com.simplito.java.privmx_endpoint.streams.model.Settings; import com.simplito.java.privmx_endpoint.streams.model.StreamEncryptionMode; import com.simplito.java.privmx_endpoint.streams.model.StreamHandle; @@ -308,6 +309,8 @@ public native StreamHandle createStream( public native void enableStreamRoomRecording(String streamRoomId); + public native List getStreamRoomRecordingKeys(String streamRoomId); + private native void deinit() throws IllegalStateException; @Override From 3d1b327baf573a7e2b54ad3e45aa1bc9bcb3bd53 Mon Sep 17 00:00:00 2001 From: Doominika Date: Thu, 12 Feb 2026 11:42:40 +0100 Subject: [PATCH 09/24] feat: add new parameter to StreamRoom class --- .../src/cpp/streams/parsers/model_native_initializers.cpp | 4 +++- .../java/privmx_endpoint/streams/model/StreamRoom.java | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp index 472e56cf..c155016f 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/model_native_initializers.cpp @@ -160,6 +160,7 @@ namespace privmx { "Lcom/simplito/java/privmx_endpoint/model/ContainerPolicy;" // policy "Ljava/lang/Long;" // statusCode "Ljava/lang/Long;" // schemaVersion + "Z" // closed ")V" ); @@ -190,7 +191,8 @@ namespace privmx { privateMeta, privmx::wrapper::containerPolicy2Java(ctx, streamRoom_c.policy), ctx.long2jLong(streamRoom_c.statusCode), - ctx.long2jLong(streamRoom_c.schemaVersion) + ctx.long2jLong(streamRoom_c.schemaVersion), + (jboolean) streamRoom_c.closed ); } diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamRoom.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamRoom.java index 6fd6f0f9..f0109f1a 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamRoom.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/streams/model/StreamRoom.java @@ -30,6 +30,7 @@ public class StreamRoom { public ContainerPolicy policy; public Long statusCode; public Long schemaVersion; + public boolean closed; public StreamRoom( String contextId, @@ -45,7 +46,8 @@ public StreamRoom( byte[] privateMeta, ContainerPolicy policy, Long statusCode, - Long schemaVersion + Long schemaVersion, + boolean closed ) { this.contextId = contextId; this.streamRoomId = streamRoomId; @@ -61,5 +63,6 @@ public StreamRoom( this.policy = policy; this.statusCode = statusCode; this.schemaVersion = schemaVersion; + this.closed = closed; } } From 65bd0e269daf42f8a813dcb90c902a9cfc1c01ef Mon Sep 17 00:00:00 2001 From: Doominika Date: Thu, 12 Feb 2026 11:43:05 +0100 Subject: [PATCH 10/24] chore: remove unnecessary headers --- .../wrapper/streams/parsers/model_native_initializers.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h index 1ea1f6f4..f9c9908e 100644 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h @@ -52,12 +52,6 @@ namespace privmx { jobject key2Java(JniContextUtils &ctx, privmx::endpoint::stream::Key key_c); - jobject - streamRoom2Java(JniContextUtils &ctx, privmx::endpoint::stream::StreamRoom streamRoom_c); - - jobject - stream2Java(JniContextUtils &ctx, privmx::endpoint::stream::Stream stream_c); - jobject turnCredentials2Java(JniContextUtils &ctx, privmx::endpoint::stream::TurnCredentials turnCredentials_c); From 2922021ee4881bf14bf6974b33e609a6799bb14e Mon Sep 17 00:00:00 2001 From: Doominika Date: Fri, 20 Feb 2026 16:06:00 +0100 Subject: [PATCH 11/24] feat: correct package name --- .../java/privmx_endpoint/model/stream/RecordingEncKey.java | 2 +- .../java/privmx_endpoint/model/stream/StreamEncryptionMode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java index 8b229c60..d4272cc2 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java @@ -1,4 +1,4 @@ -package com.simplito.java.privmx_endpoint.streams.model; +package com.simplito.java.privmx_endpoint.model.stream; import jdk.internal.util.ByteArray; diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamEncryptionMode.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamEncryptionMode.java index c8c9fc50..790ca3f1 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamEncryptionMode.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamEncryptionMode.java @@ -1,4 +1,4 @@ -package com.simplito.java.privmx_endpoint.streams.model; +package com.simplito.java.privmx_endpoint.model.stream; public enum StreamEncryptionMode { SINGLE_KEY, From ca9358802f4490fc22ae74bbc485100ddda5f7a6 Mon Sep 17 00:00:00 2001 From: Doominika Date: Fri, 20 Feb 2026 16:07:11 +0100 Subject: [PATCH 12/24] feat: change to java byte array --- .../java/privmx_endpoint/model/stream/RecordingEncKey.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java index d4272cc2..875a21e6 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java @@ -3,10 +3,10 @@ import jdk.internal.util.ByteArray; public class RecordingEncKey { - public ByteArray id; - public ByteArray key; + public byte[] id; + public byte[] key; - public RecordingEncKey(ByteArray id, ByteArray key) { + public RecordingEncKey(byte[] id, byte[] key) { this.id = id; this.key = key; } From dc8e4ba09d65bdf3895adaab3e067ff1c82078fc Mon Sep 17 00:00:00 2001 From: Doominika Date: Fri, 20 Feb 2026 16:07:59 +0100 Subject: [PATCH 13/24] feat: remove redundant import --- .../java/privmx_endpoint/model/stream/RecordingEncKey.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java index 875a21e6..258c3f84 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java @@ -1,7 +1,5 @@ package com.simplito.java.privmx_endpoint.model.stream; -import jdk.internal.util.ByteArray; - public class RecordingEncKey { public byte[] id; public byte[] key; From d6243b4ad42576cc6b6d634856efa4b02d2b6461 Mon Sep 17 00:00:00 2001 From: Doominika Date: Sat, 21 Feb 2026 12:34:32 +0100 Subject: [PATCH 14/24] fix: change types to nullable ones in models --- .../src/cpp/parsers/model_native_initializers.cpp | 4 +++- jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp | 2 +- .../java/privmx_endpoint/model/stream/StreamRoom.java | 2 +- .../java/privmx_endpoint/model/stream/StreamSubscription.java | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp index 1b8d5395..49b1b10c 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp @@ -1617,6 +1617,7 @@ namespace privmx { "Lcom/simplito/java/privmx_endpoint/model/ContainerPolicy;" // policy "Ljava/lang/Long;" // statusCode "Ljava/lang/Long;" // schemaVersion + "Ljava/lang/Boolean;" // closed ")V" ); @@ -1647,7 +1648,8 @@ namespace privmx { privateMeta, privmx::wrapper::containerPolicy2Java(ctx, streamRoom_c.policy), ctx.long2jLong(streamRoom_c.statusCode), - ctx.long2jLong(streamRoom_c.schemaVersion) + ctx.long2jLong(streamRoom_c.schemaVersion), + ctx.bool2jBoolean(streamRoom_c.closed) ); } diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp index 28972a1a..3f86cffd 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp @@ -905,7 +905,7 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU jfieldID streamIdFID = ctx->GetFieldID( ctx->GetObjectClass(streamSubscription), "streamId", - "J" + "Ljava/lang/Long;" ); jfieldID trackIdFID = ctx->GetFieldID( diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java index ac7baab1..05371361 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java @@ -30,7 +30,7 @@ public class StreamRoom { public ContainerPolicy policy; public Long statusCode; public Long schemaVersion; - public boolean closed; + public Boolean closed; public StreamRoom( String contextId, diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java index f9462643..54a471b1 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java @@ -1,7 +1,7 @@ package com.simplito.java.privmx_endpoint.model.stream; public class StreamSubscription { - public long streamId; + public Long streamId; public String streamTrackId; public StreamSubscription(long streamId, String streamTrackId) { From 96bbb697c85aa91fda402107e8adc0ded7cf2713 Mon Sep 17 00:00:00 2001 From: Doominika Date: Sat, 21 Feb 2026 12:45:26 +0100 Subject: [PATCH 15/24] fix: correct parseStreamSubscription function --- jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp index 3f86cffd..992b8eb0 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp @@ -903,21 +903,21 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU privmx::endpoint::stream::StreamSubscription result; jclass cls = ctx->GetObjectClass(streamSubscription); jfieldID streamIdFID = ctx->GetFieldID( - ctx->GetObjectClass(streamSubscription), + cls, "streamId", "Ljava/lang/Long;" ); jfieldID trackIdFID = ctx->GetFieldID( - ctx->GetObjectClass(streamSubscription), + cls, "streamTrackId", "Ljava/lang/String;" ); - jlong streamId = ctx->GetLongField(streamSubscription, streamIdFID); + jobject streamId = ctx->GetObjectField(streamSubscription, streamIdFID); jobject streamTrackId = ctx->GetObjectField(streamSubscription, trackIdFID); - result.streamId = streamId; + result.streamId = jobject2long(ctx, streamId); if (streamTrackId != nullptr) result.streamTrackId = jobject2string(ctx, streamTrackId); return result; From 3a54398b0e3adddac0b19e8a871dbc5a8769e50d Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 11:31:34 +0100 Subject: [PATCH 16/24] chore: bring back the lost classes --- jni-wrappers/privmx-endpoint/CMakeLists.txt | 1 - .../parsers/model_native_initializers.h | 5 + .../privmx/endpoint/wrapper/parsers/parser.h | 1 + .../src/cpp/modules/StreamApiLow.cpp | 237 +++++++++++++++++- .../cpp/parsers/model_native_initializers.cpp | 31 +++ .../src/cpp/parsers/parser.cpp | 20 ++ 6 files changed, 291 insertions(+), 4 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/CMakeLists.txt b/jni-wrappers/privmx-endpoint/CMakeLists.txt index ee4cfeb9..630b54f1 100644 --- a/jni-wrappers/privmx-endpoint/CMakeLists.txt +++ b/jni-wrappers/privmx-endpoint/CMakeLists.txt @@ -30,7 +30,6 @@ add_library(${CMAKE_PROJECT_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/Utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/KvdbApi.cpp src/cpp/modules/WebRTCInterfaceJNI.cpp - src/cpp/modules/StreamSettingsJNI.cpp src/cpp/modules/StreamApiLow.cpp ) target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/includes) diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/model_native_initializers.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/model_native_initializers.h index 441e079e..f6726740 100644 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/model_native_initializers.h +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/model_native_initializers.h @@ -315,6 +315,11 @@ namespace privmx { privmx::endpoint::stream::StreamsUpdatedData data ); + jobject recordingEncKey2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::RecordingEncKey recordingEncKey_c + ); + } // wrapper } // privmx diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/parser.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/parser.h index f4fe23bc..53c7c9cd 100644 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/parser.h +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/parsers/parser.h @@ -52,6 +52,7 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU privmx::endpoint::stream::SdpWithTypeModel parseSdpWithTypeModel(JniContextUtils &ctx, jobject sdpWithTypeModel); +privmx::endpoint::stream::StreamEncryptionMode parseStreamEncryptionMode(JniContextUtils &ctx, jobject streamEncryptionMode); jobject parseEvent(JniContextUtils &ctx, std::shared_ptr event); diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index dfdf24c4..78b7309c 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -12,9 +12,8 @@ #include "privmx/endpoint/wrapper/modules/WebRTCInterfaceJNI.h" #include "privmx/endpoint/stream/StreamApiLow.hpp" -using namespace privmx::endpoint::stream; using namespace privmx::endpoint; -//using namespace privmx::wrapper; +using namespace privmx::wrapper; StreamApiLow *getStreamApi(JniContextUtils &ctx, jobject streamApiInstance) { jclass cls = ctx->GetObjectClass(streamApiInstance); @@ -265,7 +264,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_listStreamRo for (auto &streamRoom_c: streamRooms_c.readItems) { env->CallBooleanMethod(array, addToArrayMID, - privmx::wrapper::streamRoom2Java( + streamRoom2Java( ctx, streamRoom_c ) @@ -879,4 +878,236 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_acceptOfferO parseSdpWithTypeModel(ctx, sdp) ); }); +} + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( + JNIEnv *env, + jobject thiz, + jstring context_id, + jobject users, + jobject managers, + jbyteArray public_meta, + jbyteArray private_meta, + jstring type, + jobject policies +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(context_id, "Context ID") || + ctx.nullCheck(users, "Users list") || + ctx.nullCheck(managers, "Managers list") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + + jstring result; + ctx.callResultEndpointApi( + &result, + [ + &ctx, + &thiz, + context_id, + &users, + &managers, + &public_meta, + &private_meta, + &type, + &policies + ]() { + std::vector users_c = usersToVector( + ctx, + ctx.jObject2jArray(users)); + std::vector managers_c = usersToVector( + ctx, + ctx.jObject2jArray(managers)); + auto container_policies_c = std::optional( + parseContainerPolicy(ctx, policies)); + return ctx->NewStringUTF( + getStreamApi(ctx, thiz)->createStreamRoomEx( + ctx.jString2string(context_id), + users_c, + managers_c, + core::Buffer::from(ctx.jByteArray2String(public_meta)), + core::Buffer::from(ctx.jByteArray2String(private_meta)), + ctx.jString2string(type), + container_policies_c + ).c_str()); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jstring type +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + jobject result; + ctx.callResultEndpointApi(&result, [&ctx, &thiz, &stream_room_id, &type] { + + return streamRoom2Java( + ctx, + getStreamApi(ctx, thiz)->getStreamRoomEx( + ctx.jString2string(stream_room_id), + ctx.jString2string(type) + ) + ); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( + JNIEnv *env, + jobject thiz, + jstring context_id, + jlong skip, + jlong limit, + jstring sort_order, + jstring type, + jstring last_id, + jstring sort_by, + jstring query_as_json +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(context_id, "Context ID") || + ctx.nullCheck(sort_order, "Sort order") || + ctx.nullCheck(type, "Type")) { + return nullptr; + } + + jobject result; + ctx.callResultEndpointApi( + &result, + [ + &ctx, + &env, + &thiz, + &context_id, + &skip, + &limit, + &sort_order, + &last_id, + &sort_by, + &query_as_json, + &type + ]() { + jclass pagingListCls = env->FindClass( + "com/simplito/java/privmx_endpoint/model/PagingList"); + jmethodID pagingListInitMID = env->GetMethodID( + pagingListCls, "", + "(Ljava/lang/Long;Ljava/util/List;)V"); + jclass arrayCls = env->FindClass("java/util/ArrayList"); + jmethodID initArrayMID = env->GetMethodID(arrayCls, + "", + "()V"); + jmethodID addToArrayMID = env->GetMethodID(arrayCls, + "add", + "(Ljava/lang/Object;)Z"); + auto query = core::PagingQuery(); + query.skip = skip; + query.limit = limit; + query.sortOrder = ctx.jString2string(sort_order); + + if (last_id != nullptr) { + query.lastId = ctx.jString2string(last_id); + } + if (sort_by != nullptr) { + query.sortBy = ctx.jString2string(sort_by); + } + if (query_as_json != nullptr) { + query.queryAsJson = ctx.jString2string(query_as_json); + } + + auto streamRooms_c( + getStreamApi(ctx, thiz)->listStreamRoomsEx( + ctx.jString2string(context_id), + query, + ctx.jString2string(type) + ) + ); + jobject array = env->NewObject(arrayCls, initArrayMID); + for (auto &streamRoom_c: streamRooms_c.readItems) { + env->CallBooleanMethod(array, + addToArrayMID, + streamRoom2Java( + ctx, + streamRoom_c + ) + ); + } + return ctx->NewObject( + pagingListCls, + pagingListInitMID, + ctx.long2jLong(streamRooms_c.totalAvailable), + array + ); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_enableStreamRoomRecording( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id]() { + getStreamApi(ctx, thiz)->enableStreamRoomRecording( + ctx.jString2string(stream_room_id) + ); + }); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomRecordingKeys( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + jobject result; + + ctx.callResultEndpointApi(&result, [&ctx, &env, &thiz, &stream_room_id] { + auto keys = getStreamApi(ctx, thiz)->getStreamRoomRecordingKeys( + ctx.jString2string(stream_room_id) + ); + + return vectorTojArray( + ctx, + keys, + recordingEncKey2Java + ); + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } \ No newline at end of file diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp index 49b1b10c..140f0984 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/model_native_initializers.cpp @@ -2269,5 +2269,36 @@ namespace privmx { ); } + jobject recordingEncKey2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::RecordingEncKey recordingEncKey_c + ){ + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/streams/model/RecordingEncKey"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "[B" // id + "[B" // key + ")V" + ); + + jbyteArray id = ctx->NewByteArray(recordingEncKey_c.id.size()); + jbyteArray key = ctx->NewByteArray(recordingEncKey_c.key.size()); + + ctx->SetByteArrayRegion(id, 0, recordingEncKey_c.id.size(), + (jbyte *) recordingEncKey_c.id.data()); + ctx->SetByteArrayRegion(key, 0, recordingEncKey_c.key.size(), + (jbyte *) recordingEncKey_c.key.data()); + + return ctx->NewObject( + itemCls, + initItemMID, + id, + key + ); + } } // wrapper } // privmx \ No newline at end of file diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp index 992b8eb0..28856e5a 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp @@ -941,6 +941,26 @@ privmx::endpoint::stream::SdpWithTypeModel parseSdpWithTypeModel(JniContextUtils } +privmx::endpoint::stream::StreamEncryptionMode parseStreamEncryptionMode( + JniContextUtils &ctx, + jobject streamEncryptionMode +) { + jclass cls = ctx->GetObjectClass(streamEncryptionMode); + jmethodID nameFID = ctx->GetMethodID( + cls, + "name", + "()Ljava/lang/String;" + ); + + auto name_j = (jstring) ctx->CallObjectMethod(streamEncryptionMode, nameFID); + std::string name_c = ctx.jString2string(name_j); + + if (name_c == "SINGLE_KEY") return privmx::endpoint::stream::StreamEncryptionMode::SINGLE_KEY; + if (name_c == "MULTIPLE_KEY") return privmx::endpoint::stream::StreamEncryptionMode::MULTIPLE_KEY; + + return {}; +} + // java -> c++ template std::vector jArrayToVector( From 7bdb3136e78b114f24b6e7f0e57bd0e7dc2cb1f4 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 11:56:40 +0100 Subject: [PATCH 17/24] chore: bring back the param in init streamApiLow and add nullcheck --- .../src/cpp/modules/StreamApiLow.cpp | 52 ++++++++++++++++++- .../modules/stream/StreamApiLow.java | 20 +++++-- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index 78b7309c..cdfa9c1c 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -25,19 +25,67 @@ StreamApiLow *getStreamApi(JniContextUtils &ctx, jobject streamApiInstance) { return (stream::StreamApiLow *) ctx.getObject(apiLong).getLongValue(); } + +/* + * +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_create( + JNIEnv *env, + jclass clazz, + jobject connection, + jobject eventApi, + jobject stream_encryption_mode +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(connection, "Connection")) { + return nullptr; + } + +// jobject result; +// ctx.callResultEndpointApi(&result, [&ctx, &env, &clazz, &connection, &eventApi] { + jmethodID initMID = ctx->GetMethodID(clazz, "", + "(Ljava/lang/Long;)V"); + auto connection_c = getConnection(env, connection); + auto eventApi_c = getEventApi(env, eventApi); + auto streamApiLow = StreamApiLow::create( + *connection_c, + *eventApi_c + ); + auto *api = new StreamApiLow(); + *api = streamApiLow; + + jobject result = ctx->NewObject( + clazz, + initMID, + ctx.long2jLong((jlong) api) + ); + return result; + +// }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + */ + + extern "C" JNIEXPORT jobject JNICALL Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_init( JNIEnv *env, jobject thiz, jobject connection, - jobject eventApi + jobject eventApi, + jobject stream_encryption_mode ) { JniContextUtils ctx(env); jobject result; if (ctx.nullCheck(connection, "Connection") || - ctx.nullCheck(eventApi, "EventApi")) { + ctx.nullCheck(eventApi, "EventApi") || + ctx.nullCheck(stream_encryption_mode, "Stream Encryption Mode")) { return nullptr; } diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index ff809f7e..89009e00 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -16,6 +16,7 @@ import com.simplito.java.privmx_endpoint.model.UserWithPubKey; import com.simplito.java.privmx_endpoint.model.stream.SdpWithTypeModel; import com.simplito.java.privmx_endpoint.model.stream.Settings; +import com.simplito.java.privmx_endpoint.model.stream.StreamEncryptionMode; import com.simplito.java.privmx_endpoint.model.stream.StreamHandle; import com.simplito.java.privmx_endpoint.model.stream.StreamInfo; import com.simplito.java.privmx_endpoint.model.stream.StreamPublishResult; @@ -46,23 +47,36 @@ private StreamApiLow(Long api) { this.api = api; } - private native Long init(Connection connection, EventApi eventApi) throws IllegalStateException; + private native Long init( + Connection connection, + EventApi eventApi, + StreamEncryptionMode streamEncryptionMode + ) throws IllegalStateException; public StreamApiLow( Connection connection ) throws IllegalStateException { - this.api = init(connection, null); + this.api = init(connection, null, StreamEncryptionMode.SINGLE_KEY); } public StreamApiLow( Connection connection, EventApi eventApi + ) throws IllegalStateException { + this.api = init(connection, eventApi, StreamEncryptionMode.SINGLE_KEY); + } + + public StreamApiLow( + Connection connection, + EventApi eventApi, + StreamEncryptionMode streamEncryptionMode ) throws IllegalStateException { Objects.requireNonNull(connection); EventApi tmpEventApi = eventApi == null ? new EventApi(connection) : null; this.api = init( connection, - Optional.ofNullable(eventApi).orElse(tmpEventApi) + Optional.ofNullable(eventApi).orElse(tmpEventApi), + Optional.ofNullable(streamEncryptionMode).orElse(StreamEncryptionMode.SINGLE_KEY) ); try { From f0f57988f4291aa0b68dd2f13bd96ed3f8a36f56 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 12:00:41 +0100 Subject: [PATCH 18/24] chore: bring back callResultEndpointApi in init function --- .../src/cpp/modules/StreamApiLow.cpp | 120 ++++++++++-------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index cdfa9c1c..b4c12a68 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -84,22 +84,30 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_init( jobject result; if (ctx.nullCheck(connection, "Connection") || - ctx.nullCheck(eventApi, "EventApi") || - ctx.nullCheck(stream_encryption_mode, "Stream Encryption Mode")) { + ctx.nullCheck(eventApi, "EventApi") || + ctx.nullCheck(stream_encryption_mode, "Stream Encryption Mode")) { return nullptr; } - ctx.callResultEndpointApi(&result, [&ctx, &env, &connection, &eventApi] { - auto connection_c = getConnection(env, connection); - auto eventApi_c = getEventApi(env, eventApi); - auto streamApiLow = stream::StreamApiLow::create( - *connection_c, - *eventApi_c - ); - auto streamApiLow_ptr = new stream::StreamApiLow(); - *streamApiLow_ptr = streamApiLow; - return ctx.long2jLong((jlong) streamApiLow_ptr); - }); + ctx.callResultEndpointApi( + &result, + [&ctx, &env, &connection, &eventApi, stream_encryption_mode] { + auto connection_c = getConnection(env, connection); + auto eventApi_c = getEventApi(env, eventApi); + auto streamApiLow = stream::StreamApiLow::create( + *connection_c, + *eventApi_c + ); + auto streamApiLow_ptr = new stream::StreamApiLow(); + *streamApiLow_ptr = streamApiLow; + + return ctx.long2jLong((jlong) streamApiLow_ptr); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } extern "C" @@ -138,10 +146,10 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_createStream ) { JniContextUtils ctx(env); if (ctx.nullCheck(context_id, "Context ID") || - ctx.nullCheck(users, "Users list") || - ctx.nullCheck(managers, "Managers list") || - ctx.nullCheck(public_meta, "Public meta") || - ctx.nullCheck(private_meta, "Private meta")) { + ctx.nullCheck(users, "Users list") || + ctx.nullCheck(managers, "Managers list") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(private_meta, "Private meta")) { return nullptr; } @@ -199,10 +207,10 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_updateStream ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream room ID") || - ctx.nullCheck(users, "Users list") || - ctx.nullCheck(managers, "Managers list") || - ctx.nullCheck(public_meta, "Public meta") || - ctx.nullCheck(private_meta, "Private meta")) { + ctx.nullCheck(users, "Users list") || + ctx.nullCheck(managers, "Managers list") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(private_meta, "Private meta")) { return; } ctx.callVoidEndpointApi( @@ -257,7 +265,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_listStreamRo ) { JniContextUtils ctx(env); if (ctx.nullCheck(context_id, "Context ID") || - ctx.nullCheck(sort_order, "Sort order")) { + ctx.nullCheck(sort_order, "Sort order")) { return nullptr; } @@ -283,11 +291,11 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_listStreamRo "(Ljava/lang/Long;Ljava/util/List;)V"); jclass arrayCls = env->FindClass("java/util/ArrayList"); jmethodID initArrayMID = env->GetMethodID(arrayCls, - "", - "()V"); + "", + "()V"); jmethodID addToArrayMID = env->GetMethodID(arrayCls, - "add", - "(Ljava/lang/Object;)Z"); + "add", + "(Ljava/lang/Object;)Z"); auto query = core::PagingQuery(); query.skip = skip; query.limit = limit; @@ -311,11 +319,11 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_listStreamRo jobject array = env->NewObject(arrayCls, initArrayMID); for (auto &streamRoom_c: streamRooms_c.readItems) { env->CallBooleanMethod(array, - addToArrayMID, - streamRoom2Java( - ctx, - streamRoom_c - ) + addToArrayMID, + streamRoom2Java( + ctx, + streamRoom_c + ) ); } return ctx->NewObject( @@ -446,7 +454,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_joinStreamRo ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream room ID") || - ctx.nullCheck(web_rtc, "webRtc")) { + ctx.nullCheck(web_rtc, "webRtc")) { return; } @@ -735,7 +743,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_unsubscribeF ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream Room ID") || - ctx.nullCheck(subscriptions_to_remove, "Subscriptions to remove")) { + ctx.nullCheck(subscriptions_to_remove, "Subscriptions to remove")) { return; } @@ -776,9 +784,9 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_modifyRemote ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream Room ID") || - ctx.nullCheck(subscriptions_to_add, "Subscriptions to add") || - ctx.nullCheck(subscriptions_to_add, "Subscriptions to remove") || - ctx.nullCheck(options, "Options")) { + ctx.nullCheck(subscriptions_to_add, "Subscriptions to add") || + ctx.nullCheck(subscriptions_to_add, "Subscriptions to remove") || + ctx.nullCheck(options, "Options")) { return; } @@ -807,7 +815,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_modifyRemote } for (int i = 0; i < subscriptions_to_remove_length; i++) { jobject arrayElement = ctx->GetObjectArrayElement(subscriptions_to_remove_arr, - i); + i); if (ctx.nullCheck(arrayElement, "Subscriptions to remove array elements")) { return; } @@ -839,8 +847,8 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_subscribeToR ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream Room ID") || - ctx.nullCheck(subscriptions, "Subscriptions") || - ctx.nullCheck(options, "Options")) { + ctx.nullCheck(subscriptions, "Subscriptions") || + ctx.nullCheck(options, "Options")) { return; } ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id, &subscriptions, &options]() { @@ -943,11 +951,11 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( ) { JniContextUtils ctx(env); if (ctx.nullCheck(context_id, "Context ID") || - ctx.nullCheck(users, "Users list") || - ctx.nullCheck(managers, "Managers list") || - ctx.nullCheck(public_meta, "Public meta") || - ctx.nullCheck(public_meta, "Public meta") || - ctx.nullCheck(type, "Type")) { + ctx.nullCheck(users, "Users list") || + ctx.nullCheck(managers, "Managers list") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(type, "Type")) { return nullptr; } @@ -999,7 +1007,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream Room ID") || - ctx.nullCheck(type, "Type")) { + ctx.nullCheck(type, "Type")) { return nullptr; } jobject result; @@ -1035,8 +1043,8 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( ) { JniContextUtils ctx(env); if (ctx.nullCheck(context_id, "Context ID") || - ctx.nullCheck(sort_order, "Sort order") || - ctx.nullCheck(type, "Type")) { + ctx.nullCheck(sort_order, "Sort order") || + ctx.nullCheck(type, "Type")) { return nullptr; } @@ -1063,11 +1071,11 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( "(Ljava/lang/Long;Ljava/util/List;)V"); jclass arrayCls = env->FindClass("java/util/ArrayList"); jmethodID initArrayMID = env->GetMethodID(arrayCls, - "", - "()V"); + "", + "()V"); jmethodID addToArrayMID = env->GetMethodID(arrayCls, - "add", - "(Ljava/lang/Object;)Z"); + "add", + "(Ljava/lang/Object;)Z"); auto query = core::PagingQuery(); query.skip = skip; query.limit = limit; @@ -1093,11 +1101,11 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( jobject array = env->NewObject(arrayCls, initArrayMID); for (auto &streamRoom_c: streamRooms_c.readItems) { env->CallBooleanMethod(array, - addToArrayMID, - streamRoom2Java( - ctx, - streamRoom_c - ) + addToArrayMID, + streamRoom2Java( + ctx, + streamRoom_c + ) ); } return ctx->NewObject( From 735f125f9fbd46894be0dd1d3b69eeddf51ee926 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 13:16:57 +0100 Subject: [PATCH 19/24] chore: bring back new parameter in create function --- .../privmx-endpoint/src/cpp/modules/StreamApiLow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index b4c12a68..1437f77c 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -91,12 +91,13 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_init( ctx.callResultEndpointApi( &result, - [&ctx, &env, &connection, &eventApi, stream_encryption_mode] { + [&ctx, &env, &connection, &eventApi, &stream_encryption_mode] { auto connection_c = getConnection(env, connection); auto eventApi_c = getEventApi(env, eventApi); auto streamApiLow = stream::StreamApiLow::create( *connection_c, - *eventApi_c + *eventApi_c, + parseStreamEncryptionMode(ctx, stream_encryption_mode) ); auto streamApiLow_ptr = new stream::StreamApiLow(); *streamApiLow_ptr = streamApiLow; From 21e1f169733b000b30548afdd165c7cbbda0597b Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 13:17:52 +0100 Subject: [PATCH 20/24] chore: fix param in nullcheck --- jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index 1437f77c..06d6faee 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -955,7 +955,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( ctx.nullCheck(users, "Users list") || ctx.nullCheck(managers, "Managers list") || ctx.nullCheck(public_meta, "Public meta") || - ctx.nullCheck(public_meta, "Public meta") || + ctx.nullCheck(private_meta, "Private meta") || ctx.nullCheck(type, "Type")) { return nullptr; } From ed44093b5d9f187985d6be11c4f2fdc0b03b631f Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 13:21:20 +0100 Subject: [PATCH 21/24] chore: bring back api methods --- .../src/cpp/modules/StreamApiLow.cpp | 10 +-- .../modules/stream/StreamApiLow.java | 69 +++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index 06d6faee..dd1b1357 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -939,7 +939,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_acceptOfferO extern "C" JNIEXPORT jstring JNICALL -Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_createStreamRoomEx( JNIEnv *env, jobject thiz, jstring context_id, @@ -1000,7 +1000,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_createStreamRoomEx( } extern "C" JNIEXPORT jobject JNICALL -Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_getStreamRoomEx( JNIEnv *env, jobject thiz, jstring stream_room_id, @@ -1030,7 +1030,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomEx( extern "C" JNIEXPORT jobject JNICALL -Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_listStreamRoomsEx( JNIEnv *env, jobject thiz, jstring context_id, @@ -1125,7 +1125,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_listStreamRoomsEx( extern "C" JNIEXPORT void JNICALL -Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_enableStreamRoomRecording( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_enableStreamRoomRecording( JNIEnv *env, jobject thiz, jstring stream_room_id @@ -1144,7 +1144,7 @@ Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_enableStreamRoomRec extern "C" JNIEXPORT jobject JNICALL -Java_com_simplito_java_privmx_1endpoint_streams_StreamApiLow_getStreamRoomRecordingKeys( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_getStreamRoomRecordingKeys( JNIEnv *env, jobject thiz, jstring stream_room_id diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index 89009e00..6d795279 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -237,6 +237,75 @@ public String buildSubscriptionQuery( public native void keyManagement(String streamRoomId, boolean disable); + public native void enableStreamRoomRecording(String streamRoomId); + + public native PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId, + String sortBy, + String queryAsJson + ); + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId, + String sortBy + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, lastId, sortBy, null); + } + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type, + String lastId + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, lastId, null, null); + } + + public PagingList listStreamRoomsEx( + String contextId, + long skip, + long limit, + String sortOrder, + String type + ) { + return listStreamRoomsEx(contextId, skip, limit, sortOrder, type, null, null, null); + } + + public native StreamRoom getStreamRoomEx(String streamRoomId, String type); + + public native String createStreamRoomEx( + String contextId, + List users, + List managers, + byte[] publicMeta, + byte[] privateMeta, + String type, + ContainerPolicy policies + ); + + public String createStreamRoomEx( + String contextId, + List users, + List managers, + byte[] publicMeta, + byte[] privateMeta, + String type + ) { + return this.createStreamRoomEx(contextId, users, managers, publicMeta, privateMeta, type, null); + } + private native void deinit() throws IllegalStateException; @Override From 2a3df80b137f40ae293084136e4b0852ed1e8ed5 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 13:22:16 +0100 Subject: [PATCH 22/24] chore: bring back method --- .../java/privmx_endpoint/modules/stream/StreamApiLow.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index 6d795279..93beb6bc 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -14,6 +14,7 @@ import com.simplito.java.privmx_endpoint.model.ContainerPolicy; import com.simplito.java.privmx_endpoint.model.PagingList; import com.simplito.java.privmx_endpoint.model.UserWithPubKey; +import com.simplito.java.privmx_endpoint.model.stream.RecordingEncKey; import com.simplito.java.privmx_endpoint.model.stream.SdpWithTypeModel; import com.simplito.java.privmx_endpoint.model.stream.Settings; import com.simplito.java.privmx_endpoint.model.stream.StreamEncryptionMode; @@ -306,6 +307,8 @@ public String createStreamRoomEx( return this.createStreamRoomEx(contextId, users, managers, publicMeta, privateMeta, type, null); } + public native List getStreamRoomRecordingKeys(String streamRoomId); + private native void deinit() throws IllegalStateException; @Override From a21589853e936523f785f772b7be2c642bf44712 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 13:24:06 +0100 Subject: [PATCH 23/24] feat: add nullcheck for stream_room_id --- .../privmx-endpoint/src/cpp/modules/StreamApiLow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index dd1b1357..8e870116 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -451,7 +451,6 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_joinStreamRo jobject thiz, jstring stream_room_id, jobject web_rtc - // todo - made changes in arguments ) { JniContextUtils ctx(env); if (ctx.nullCheck(stream_room_id, "Stream room ID") || @@ -1152,6 +1151,10 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_getStreamRoo JniContextUtils ctx(env); jobject result; + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return nullptr; + } + ctx.callResultEndpointApi(&result, [&ctx, &env, &thiz, &stream_room_id] { auto keys = getStreamApi(ctx, thiz)->getStreamRoomRecordingKeys( ctx.jString2string(stream_room_id) From 99fa304b8a6e8367c9dfc8cee33d4d2759b3150a Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 23 Feb 2026 15:47:17 +0100 Subject: [PATCH 24/24] fix: change imports after moving streamApiLow --- .../privmx_endpoint/modules/stream/RoomJanusSession.java | 8 ++------ .../privmx_endpoint/modules/stream/WebRTCInterface.java | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/RoomJanusSession.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/RoomJanusSession.java index 60d3ef08..f94e3d70 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/RoomJanusSession.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/RoomJanusSession.java @@ -3,18 +3,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.simplito.java.privmx_endpoint.model.ConnectionType; -import com.simplito.java.privmx_endpoint.model.Key; -import com.simplito.java.privmx_endpoint.model.KeyType; +import com.simplito.java.privmx_endpoint.model.stream.Key; +import com.simplito.java.privmx_endpoint.model.stream.KeyType; -import org.webrtc.MediaStreamTrack; -import org.webrtc.PeerConnection; import org.webrtc.PeerConnectionFactory; import org.webrtc.PmxFrameCryptor; import org.webrtc.PmxFrameCryptorFactory; import org.webrtc.PmxKeyStore; -import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java index f470718b..a7bbb8c7 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java @@ -11,7 +11,7 @@ package com.simplito.java.privmx_endpoint.modules.stream; -import com.simplito.java.privmx_endpoint.model.Key; +import com.simplito.java.privmx_endpoint.model.stream.Key; import java.util.List;