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..8e870116 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); @@ -26,33 +25,90 @@ 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; } - 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, + parseStreamEncryptionMode(ctx, stream_encryption_mode) + ); + auto streamApiLow_ptr = new stream::StreamApiLow(); + *streamApiLow_ptr = streamApiLow; + + return ctx.long2jLong((jlong) streamApiLow_ptr); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; } extern "C" @@ -91,10 +147,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; } @@ -152,10 +208,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( @@ -210,7 +266,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; } @@ -236,11 +292,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; @@ -264,11 +320,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, - privmx::wrapper::streamRoom2Java( - ctx, - streamRoom_c - ) + addToArrayMID, + streamRoom2Java( + ctx, + streamRoom_c + ) ); } return ctx->NewObject( @@ -395,11 +451,10 @@ 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") || - ctx.nullCheck(web_rtc, "webRtc")) { + ctx.nullCheck(web_rtc, "webRtc")) { return; } @@ -688,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; } @@ -729,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; } @@ -760,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; } @@ -792,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]() { @@ -879,4 +934,240 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_acceptOfferO parseSdpWithTypeModel(ctx, sdp) ); }); +} + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_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(private_meta, "Private 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_modules_stream_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_modules_stream_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_modules_stream_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_modules_stream_StreamApiLow_getStreamRoomRecordingKeys( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + 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) + ); + + 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 1b8d5395..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 @@ -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) ); } @@ -2267,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 28972a1a..28856e5a 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", - "J" + "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; @@ -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( 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; 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 new file mode 100644 index 00000000..258c3f84 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/RecordingEncKey.java @@ -0,0 +1,11 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +public class RecordingEncKey { + public byte[] id; + public byte[] key; + + public RecordingEncKey(byte[] id, byte[] key) { + this.id = id; + this.key = key; + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..790ca3f1 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamEncryptionMode.java @@ -0,0 +1,6 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +public enum StreamEncryptionMode { + SINGLE_KEY, + MULTIPLE_KEY +} 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 36546587..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,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; } } 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) { 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..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,8 +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.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; 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 +48,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 { @@ -223,6 +238,77 @@ 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); + } + + public native List getStreamRoomRecordingKeys(String streamRoomId); + private native void deinit() throws IllegalStateException; @Override