From d2b7b38710941744189408bb3a8d0ca65c0fff31 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 10:50:37 +0100 Subject: [PATCH 01/26] feat: add VideoTrackInfo class --- .../parsers/model_native_initializers.h | 3 ++ .../parsers/model_native_initializers.cpp | 33 +++++++++++++++++++ .../privmx_endpoint/model/VideoTrackInfo.java | 1 + 3 files changed, 37 insertions(+) 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..2b935860 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 + streamTrackModificationPair2Java(JniContextUtils & ctx, endpoint::stream::StreamTrackModificationPair + streamTrackModificationPair); } // 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 0e43daa9..b3decfc1 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 @@ -571,6 +571,39 @@ namespace privmx { initItemMID ); } + + jobject + streamTrackModificationPair2Java( + JniContextUtils &ctx, + endpoint::stream::StreamTrackModificationPair streamTrackModificationPair + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/StreamTrackModificationPair"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Lcom/privmx/stream/StreamTrackInfo;" + "Lcom/privmx/stream/StreamTrackInfo;" + ")V" + ); + + jobject before = streamTrackModificationPair.before + ? streamTrackInfo2Java(ctx, streamTrackModificationPair.before.value()) + : nullptr; + + jobject after = streamTrackModificationPair.after + ? streamTrackInfo2Java(ctx, streamTrackModificationPair.after.value()) + : nullptr; + + return ctx->NewObject( + cls, + ctor, + before, + after + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/jvm/src/main/java/com/simplito/java/privmx_endpoint/model/VideoTrackInfo.java b/privmx-endpoint-streams/jvm/src/main/java/com/simplito/java/privmx_endpoint/model/VideoTrackInfo.java index cc89f60b..44d397ad 100644 --- a/privmx-endpoint-streams/jvm/src/main/java/com/simplito/java/privmx_endpoint/model/VideoTrackInfo.java +++ b/privmx-endpoint-streams/jvm/src/main/java/com/simplito/java/privmx_endpoint/model/VideoTrackInfo.java @@ -1,5 +1,6 @@ package com.simplito.java.privmx_endpoint.model; +import org.webrtc.PmxFrameCryptor; import org.webrtc.RtpSender; import org.webrtc.VideoTrack; From 5237e900742f2a5cb81631a01afc674ca8340a0b Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 10:52:34 +0100 Subject: [PATCH 02/26] feat: add StreamTrackModification class --- .../parsers/model_native_initializers.h | 4 + .../parsers/model_native_initializers.cpp | 84 +++++++++++++++++++ .../model/StreamTrackModification.java | 4 +- 3 files changed, 90 insertions(+), 2 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 2b935860..a125194b 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 @@ -66,6 +66,10 @@ namespace privmx { jobject streamTrackModificationPair2Java(JniContextUtils & ctx, endpoint::stream::StreamTrackModificationPair streamTrackModificationPair); + + jobject + streamTrackModification2Java(JniContextUtils & ctx, endpoint::stream::StreamTrackModification + streamTrackModification); } // 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 b3decfc1..ca711102 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 @@ -604,6 +604,90 @@ namespace privmx { ); } + jobject + streamTrackModification2Java( + JniContextUtils &ctx, + endpoint::stream::StreamTrackModification streamTrackModification + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/StreamTrackModification"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/Long;" + "Ljava/util/List;" + ")V" + ); + + jobject tracksList = vectorTojArray( + ctx, + streamTrackModification.tracks, + streamTrackModificationPair2Java + ); + + return ctx->NewObject( + cls, + ctor, + ctx.long2jLong(streamTrackModification.streamId), + tracksList + ); + } + + jobject + updatedStreamData2Java( + JniContextUtils &ctx, + endpoint::stream::UpdatedStreamData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/UpdatedStreamData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/lang/Long;" + "Ljava/lang/String;" + "Ljava/lang/Boolean;" + "Ljava/lang/Boolean;" + "Ljava/lang/String;" + "Ljava/lang/Long;" + "Ljava/lang/String;" + "Ljava/lang/String;" + ")V" + ); + + jobject jCodec = data.codec + ? ctx->NewStringUTF(data.codec->c_str()) + : nullptr; + + jobject jStreamId = data.streamId + ? ctx.long2jLong(data.streamId.value()) + : nullptr; + + jobject jStreamMid = data.streamMid + ? ctx->NewStringUTF(data.streamMid->c_str()) + : nullptr; + + jobject jStreamDisplay = data.stream_display + ? ctx->NewStringUTF(data.stream_display->c_str()) + : nullptr; + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.type.c_str()), + ctx.long2jLong(data.mindex), + ctx->NewStringUTF(data.mid.c_str()), + ctx.bool2jBoolean(data.send), + ctx.bool2jBoolean(data.ready), + jCodec, + jStreamId, + jStreamMid, + jStreamDisplay + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamTrackModification.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamTrackModification.java index 39f13b73..b0cbbf1b 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamTrackModification.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamTrackModification.java @@ -3,10 +3,10 @@ import java.util.List; public class StreamTrackModification { - public long streamId; + public Long streamId; public List tracks; - public StreamTrackModification(long streamId, List tracks) { + public StreamTrackModification(Long streamId, List tracks) { this.streamId = streamId; this.tracks = tracks; } From b7107fdf2c306cd7d63e43ae78233cdbf345b038 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 10:54:34 +0100 Subject: [PATCH 03/26] feat: add StreamUpdatedEventData class --- .../parsers/model_native_initializers.h | 4 ++ .../parsers/model_native_initializers.cpp | 45 +++++++++++++++++++ .../model/events/StreamUpdatedEventData.java | 20 +++++++++ 3 files changed, 69 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUpdatedEventData.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 a125194b..b2b36ec7 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 @@ -70,6 +70,10 @@ namespace privmx { jobject streamTrackModification2Java(JniContextUtils & ctx, endpoint::stream::StreamTrackModification streamTrackModification); + + jobject + streamUpdatedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamUpdatedEventData + data); } // 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 ca711102..bc83af44 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 @@ -688,6 +688,51 @@ namespace privmx { ); } + jobject streamUpdatedEventData2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamUpdatedEventData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/StreamUpdatedEventData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/util/List;" + "Ljava/util/List;" + "Ljava/util/List;" + ")V" + ); + + jobject addedList = vectorTojArray( + ctx, + data.streamsAdded, + streamInfo2Java + ); + + jobject removedList = vectorTojArray( + ctx, + data.streamsRemoved, + streamInfo2Java + ); + + jobject modifiedList = vectorTojArray( + ctx, + data.streamsModified, + streamTrackModification2Java + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.streamRoomId.c_str()), + addedList, + removedList, + modifiedList + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUpdatedEventData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUpdatedEventData.java new file mode 100644 index 00000000..01f6e1b8 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUpdatedEventData.java @@ -0,0 +1,20 @@ +package com.simplito.java.privmx_endpoint.model.events; + +import com.simplito.java.privmx_endpoint.model.StreamInfo; +import com.simplito.java.privmx_endpoint.model.StreamTrackModification; + +import java.util.List; + +public class StreamUpdatedEventData { + public String streamRoomId; + public List streamsAdded; + public List streamsRemoved; + public List streamsModified; + + public StreamUpdatedEventData(String streamRoomId, List streamsAdded, List streamsRemoved, List streamsModified) { + this.streamRoomId = streamRoomId; + this.streamsAdded = streamsAdded; + this.streamsRemoved = streamsRemoved; + this.streamsModified = streamsModified; + } +} \ No newline at end of file From 0014c4be4f225c40640cd5627f548d4a560dc76c Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 10:57:25 +0100 Subject: [PATCH 04/26] feat: add UpdatedStreamData class --- .../parsers/model_native_initializers.h | 5 +++ .../model/events/UpdatedStreamData.java | 41 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/UpdatedStreamData.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 b2b36ec7..60a70be6 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 @@ -74,6 +74,11 @@ namespace privmx { jobject streamUpdatedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamUpdatedEventData data); + + jobject + updatedStreamData2Java(JniContextUtils & ctx, endpoint::stream::UpdatedStreamData + updatedStreamData); + } // streams } // wrapper } // privmx diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/UpdatedStreamData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/UpdatedStreamData.java new file mode 100644 index 00000000..870ae035 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/UpdatedStreamData.java @@ -0,0 +1,41 @@ +package com.simplito.java.privmx_endpoint.model.events; + +public class UpdatedStreamData { + public String type; + public String codec = null; // optional + public Long streamId = null; // optional + public String streamMid = null; // optional + public String streamDisplay = null; // optional + public Long mindex; + public String mid; + Boolean send; + Boolean ready; + + public UpdatedStreamData(String type, Long mindex, String mid, Boolean send, Boolean ready, String codec, Long streamId, String streamMid, String streamDisplay) { + this.type = type; + this.codec = codec; + this.streamId = streamId; + this.streamMid = streamMid; + this.streamDisplay = streamDisplay; + this.mindex = mindex; + this.mid = mid; + this.send = send; + this.ready = ready; + } + + public UpdatedStreamData(String type, Long mindex, String mid, Boolean send, Boolean ready, String codec, Long streamId, String streamMid) { + this(type, mindex, mid, send, ready, codec, streamId, streamMid, null); + } + + public UpdatedStreamData(String type, Long mindex, String mid, Boolean send, Boolean ready, String codec, Long streamId) { + this(type, mindex, mid, send, ready, codec, streamId, null, null); + } + + public UpdatedStreamData(String type, Long mindex, String mid, Boolean send, Boolean ready, String codec) { + this(type, mindex, mid, send, ready, codec, null, null, null); + } + + public UpdatedStreamData(String type, Long mindex, String mid, Boolean send, Boolean ready) { + this(type, mindex, mid, send, ready, null, null, null, null); + } +} \ No newline at end of file From 3c1588e76c161bad25b5aae3b498a7e6a2a3c8d6 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 10:58:58 +0100 Subject: [PATCH 05/26] feat: add StreamRoomDeletedEventData class --- .../parsers/model_native_initializers.h | 4 ++++ .../parsers/model_native_initializers.cpp | 22 +++++++++++++++++++ .../events/StreamRoomDeletedEventData.java | 9 ++++++++ 3 files changed, 35 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamRoomDeletedEventData.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 60a70be6..13c2b1e7 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 @@ -79,6 +79,10 @@ namespace privmx { updatedStreamData2Java(JniContextUtils & ctx, endpoint::stream::UpdatedStreamData updatedStreamData); + jobject + streamRoomDeleted2EventDataJava(JniContextUtils & ctx, privmx::endpoint::stream::StreamRoomDeletedEventData + data); + } // 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 bc83af44..f4313b31 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 @@ -688,6 +688,28 @@ namespace privmx { ); } + jobject + streamRoomDeletedEventData2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamRoomDeletedEventData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/StreamRoomDeletedEventData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + ")V" + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.streamRoomId.c_str()) + ); + } + jobject streamUpdatedEventData2Java( JniContextUtils &ctx, privmx::endpoint::stream::StreamUpdatedEventData data diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamRoomDeletedEventData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamRoomDeletedEventData.java new file mode 100644 index 00000000..ea6ba838 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamRoomDeletedEventData.java @@ -0,0 +1,9 @@ +package com.simplito.java.privmx_endpoint.model.events; + +public class StreamRoomDeletedEventData { + public String streamRoomId; + + public StreamRoomDeletedEventData(String streamRoomId) { + this.streamRoomId = streamRoomId; + } +} From 79a6692ee342f4f9945313bf261ccaa9543fb374 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:00:51 +0100 Subject: [PATCH 06/26] fix: add StreamRoomDeletedEventData class --- .../wrapper/streams/parsers/model_native_initializers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 13c2b1e7..c4745e08 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 @@ -80,7 +80,7 @@ namespace privmx { updatedStreamData); jobject - streamRoomDeleted2EventDataJava(JniContextUtils & ctx, privmx::endpoint::stream::StreamRoomDeletedEventData + streamRoomDeletedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamRoomDeletedEventData data); } // streams From d67ca31919c779931486dc810197d097ebaf02bc Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:02:44 +0100 Subject: [PATCH 07/26] feat: add StreamPublishedEventData class --- .../parsers/model_native_initializers.h | 5 ++++ .../parsers/model_native_initializers.cpp | 26 +++++++++++++++++++ .../model/events/PublishedStreamData.java | 26 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.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 c4745e08..d8ac9fd3 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 @@ -83,6 +83,11 @@ namespace privmx { streamRoomDeletedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamRoomDeletedEventData data); + jobject + streamPublishedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamPublishedEventData + data); + + } // 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 f4313b31..d6b546af 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 @@ -710,6 +710,32 @@ namespace privmx { ); } + jobject + streamPublishedEventData2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamPublishedEventData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/PublishedStreamData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Lcom/simplito/java/privmx_endpoint/model/StreamInfo;" + "Ljava/lang/String;" + ")V" + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.streamRoomId.c_str()), + streamInfo2Java(ctx, data.stream), + ctx->NewStringUTF(data.userId.c_str()) + ); + } + jobject streamUpdatedEventData2Java( JniContextUtils &ctx, privmx::endpoint::stream::StreamUpdatedEventData data diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java new file mode 100644 index 00000000..b356b4f6 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java @@ -0,0 +1,26 @@ +package com.simplito.java.privmx_endpoint.model.events; + +import com.simplito.java.privmx_endpoint.model.StreamInfo; + +// todo: which to choose +// same as StreamPublishedEventData +public class PublishedStreamData { + + /** + * StreamRoom ID + */ + public String streamRoomId; + + /** + * Stream ID's + */ + public StreamInfo stream; + + public String userId; + + public PublishedStreamData(String streamRoomId, StreamInfo stream, String userId) { + this.streamRoomId = streamRoomId; + this.stream = stream; + this.userId = userId; + } +} \ No newline at end of file From 366c681d11fa17350bdead303a53d74fbd54fb6c Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:03:30 +0100 Subject: [PATCH 08/26] feat: add StreamEventData class --- .../parsers/model_native_initializers.h | 4 +++ .../parsers/model_native_initializers.cpp | 32 +++++++++++++++++++ .../model/events/StreamEventData.java | 15 +++++++++ 3 files changed, 51 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamEventData.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 d8ac9fd3..7440696c 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 @@ -87,6 +87,10 @@ namespace privmx { streamPublishedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamPublishedEventData data); + jobject + streamEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamEventData + data); + } // streams } // wrapper 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 d6b546af..ee711804 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 @@ -781,6 +781,38 @@ namespace privmx { ); } + jobject + streamEventData2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamEventData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/StreamEventData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/util/List;" + "Ljava/lang/String;" + ")V" + ); + + jobject streamIds = vectorTojArray( + ctx, + data.streamIds, + long2jobject + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.streamRoomId.c_str()), + streamIds, + ctx->NewStringUTF(data.userId.c_str()) + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamEventData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamEventData.java new file mode 100644 index 00000000..dead3835 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamEventData.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.events; + +import java.util.List; + +public class StreamEventData { + public String streamRoomId; + public List streamIds; + public String userId; + + public StreamEventData(String streamRoomId, List streamIds, String userId) { + this.streamRoomId = streamRoomId; + this.streamIds = streamIds; + this.userId = userId; + } +} From e311fe09b960c7894b10c77769fe234d7e9ae700 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:05:28 +0100 Subject: [PATCH 09/26] feat: add StreamUnpublishedEventData class --- .../parsers/model_native_initializers.h | 4 ++ .../parsers/model_native_initializers.cpp | 69 ++++++++++--------- .../events/StreamUnpublishedEventData.java | 11 +++ 3 files changed, 52 insertions(+), 32 deletions(-) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUnpublishedEventData.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 7440696c..5738e9f6 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 @@ -91,6 +91,10 @@ namespace privmx { streamEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamEventData data); + jobject + streamUnpublishedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamUnpublishedEventData + data); + } // streams } // wrapper 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 ee711804..4275e572 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 @@ -258,30 +258,6 @@ namespace privmx { ctx.long2jLong(streamRoom_c.schemaVersion) ); } - //Stream -// jobject stream2Java( -// JniContextUtils &ctx, -// privmx::endpoint::stream::Stream stream_c -// ) { -// jclass itemCls = ctx->FindClass( -// "com/simplito/java/privmx_endpoint/model/Stream"); -// -// jmethodID initItemMID = ctx->GetMethodID( -// itemCls, -// "", -// "(" -// "Ljava/lang/Long;" // streamId -// "Ljava/lang/String;" // userId -// ")V" -// ); -// -// return ctx->NewObject( -// itemCls, -// initItemMID, -// ctx.long2jLong(stream_c.streamId), -// ctx->NewStringUTF(stream_c.userId.c_str()) -// ); -// } jobject deviceType2Java( JniContextUtils &ctx, @@ -486,6 +462,7 @@ namespace privmx { ); } + jobject publishedStreamData2Java(JniContextUtils &ctx, privmx::endpoint::stream::PublishedStreamData publishedStreamData_c) { jclass itemCls = ctx->FindClass( "com/simplito/java/privmx_endpoint/model/PublishedStreamData"); @@ -525,17 +502,21 @@ namespace privmx { jobject data = nullptr; if (streamPublishResult_c.data.has_value()) { data = publishedStreamData2Java(ctx, streamPublishResult_c.data.value()); + return ctx->NewObject( + itemCls, + initItemMID, + ctx.bool2jBoolean(streamPublishResult_c.published), + data + ); + } else { + return ctx->NewObject( + itemCls, + initItemMID, + ctx.bool2jBoolean(streamPublishResult_c.published) + ); } - - return ctx->NewObject( - itemCls, - initItemMID, - ctx.bool2jBoolean(streamPublishResult_c.published), - data - ); } - jobject remoteStreamId2Java(JniContextUtils &ctx, privmx::endpoint::stream::RemoteStreamId remoteStreamId_c) { jclass itemCls = ctx->FindClass( @@ -813,6 +794,30 @@ namespace privmx { ); } + jobject + streamUnpublishedEventData2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamUnpublishedEventData data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/StreamUnpublishedEventData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/lang/Long;" + ")V" + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.streamRoomId.c_str()), + ctx.long2jLong(data.streamId) + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUnpublishedEventData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUnpublishedEventData.java new file mode 100644 index 00000000..41f0eb6b --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamUnpublishedEventData.java @@ -0,0 +1,11 @@ +package com.simplito.java.privmx_endpoint.model.events; + +public class StreamUnpublishedEventData { + public String streamRoomId; + public Long streamId; + + public StreamUnpublishedEventData(String streamRoomId, Long streamId) { + this.streamRoomId = streamRoomId; + this.streamId = streamId; + } +} From 1eabb47c13972d0965f55a4fa69de64528ce108a Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:06:28 +0100 Subject: [PATCH 10/26] feat: add NewStreams class --- .../parsers/model_native_initializers.h | 4 +++ .../parsers/model_native_initializers.cpp | 30 +++++++++++++++++++ .../model/events/NewStreams.java | 15 ++++++++++ 3 files changed, 49 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/NewStreams.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 5738e9f6..60d375a4 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 @@ -95,6 +95,10 @@ namespace privmx { streamUnpublishedEventData2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamUnpublishedEventData data); + jobject + newStreams2Java(JniContextUtils & ctx, privmx::endpoint::stream::NewStreams + data); + } // streams } // wrapper 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 4275e572..6cd50a43 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 @@ -818,6 +818,36 @@ namespace privmx { ); } + jobject + newStreams2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::NewStreams data + ) { + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/events/NewStreams"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/util/List;" + ")V" + ); + + jobject streamsList = vectorTojArray( + ctx, + data.streams, + streamInfo2Java + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.room.c_str()), + streamsList + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/NewStreams.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/NewStreams.java new file mode 100644 index 00000000..2e18d386 --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/NewStreams.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.events; + +import com.simplito.java.privmx_endpoint.model.StreamInfo; + +import java.util.List; + +public class NewStreams { + public String room; + public List streams; + + public NewStreams(String room, List streams) { + this.room = room; + this.streams = streams; + } +} From fc2c394a01f763bd49db688c3f546c152ab53591 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:07:33 +0100 Subject: [PATCH 11/26] feat: add StreamsUpdatedData class --- .../parsers/model_native_initializers.h | 3 ++ .../parsers/model_native_initializers.cpp | 29 +++++++++++++++++++ .../model/events/StreamsUpdatedData.java | 13 +++++++++ 3 files changed, 45 insertions(+) create mode 100644 privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamsUpdatedData.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 60d375a4..502d6793 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 @@ -99,6 +99,9 @@ namespace privmx { newStreams2Java(JniContextUtils & ctx, privmx::endpoint::stream::NewStreams data); + jobject + streamsUpdated2Java(JniContextUtils & ctx, privmx::endpoint::stream::StreamsUpdatedData + data); } // streams } // wrapper 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 6cd50a43..2b904b13 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 @@ -848,6 +848,35 @@ namespace privmx { ); } + jobject + streamsUpdated2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamsUpdatedData data + ) { + jclass cls = ctx->FindClass("com/simplito/java/privmx_endpoint/model/events/StreamsUpdatedData"); + jmethodID ctor = ctx->GetMethodID( + cls, + "", + "(" + "Ljava/lang/String;" + "Ljava/util/List;" + ")V" + ); + + jobject streamsList = vectorTojArray( + ctx, + data.streams, + updatedStreamData2Java + ); + + return ctx->NewObject( + cls, + ctor, + ctx->NewStringUTF(data.room.c_str()), + streamsList + ); + } + } // streams } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamsUpdatedData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamsUpdatedData.java new file mode 100644 index 00000000..d98b824c --- /dev/null +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamsUpdatedData.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.model.events; + +import java.util.List; + +public class StreamsUpdatedData { + public String room; + public List streams; + + public StreamsUpdatedData(String room, List streams) { + this.room = room; + this.streams = streams; + } +} \ No newline at end of file From 85d1c070aa0096a40d7b9e5492deef646c75f6e6 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:16:58 +0100 Subject: [PATCH 12/26] feat: update StreamPublishResult class --- .../model/StreamPublishResult.java | 14 ++++++++------ .../privmx_endpoint/model/StreamPublishResult.java | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java index 42a89b42..e322f97e 100644 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java +++ b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java @@ -1,15 +1,17 @@ package com.simplito.java.privmx_endpoint_streams.model; -import com.simplito.java.privmx_endpoint.model.PublishedStreamData; - public class StreamPublishResult { -public Boolean published; -public PublishedStreamData data; + public Boolean published; + public PublishedStreamData data; - public StreamPublishResult(boolean published) { + public StreamPublishResult(Boolean published) { this(published, null); } - public StreamPublishResult(boolean published, PublishedStreamData data) { + + public StreamPublishResult( + Boolean published, + PublishedStreamData data + ) { this.published = published; this.data = data; } diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamPublishResult.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamPublishResult.java index 52df82c8..6fdc0e14 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamPublishResult.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/StreamPublishResult.java @@ -4,10 +4,10 @@ public class StreamPublishResult { public Boolean published; public PublishedStreamData data; - public StreamPublishResult(boolean published) { + public StreamPublishResult(Boolean published) { this(published, null); } - public StreamPublishResult(boolean published, PublishedStreamData data) { + public StreamPublishResult(Boolean published, PublishedStreamData data) { this.published = published; this.data = data; } From 556833bd5a07b86b4ad0868daa7a8ff721858d69 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:21:08 +0100 Subject: [PATCH 13/26] feat: add parse streams event function --- .../endpoint/wrapper/streams/parsers/parser.h | 2 + .../src/cpp/streams/parsers/parser.cpp | 143 ++++++++++++++++++ 2 files changed, 145 insertions(+) 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..5f17fdf9 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 @@ -32,3 +32,5 @@ privmx::endpoint::stream::StreamSettings parseStreamSettings(JNIEnv *env, jobjec privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextUtils &ctx, jobject streamSubscription); //#endif //PRIVMX_POCKET_LIB_PARSER_H + jobject parseStreamEvent(JniContextUtils &ctx, std::shared_ptr event); + 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..68e5c18e 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,147 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU if(streamTrackId != nullptr) result.streamTrackId = jobject2string(ctx, streamTrackId); return result; +} + +jobject +parseStreamEvent(JniContextUtils &ctx, std::shared_ptr event) { + try { + if (stream::Events::isStreamRoomCreatedEvent(event)) { + privmx::endpoint::stream::StreamRoomCreatedEvent event_cast = stream::Events::extractStreamRoomCreatedEvent( + event); + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamRoomUpdatedEvent(event)) { + privmx::endpoint::stream::StreamRoomUpdatedEvent event_cast = + stream::Events::extractStreamRoomUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamRoomDeletedEvent(event)) { + privmx::endpoint::stream::StreamRoomDeletedEvent event_cast = + stream::Events::extractStreamRoomDeletedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoomDeletedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamPublishedEvent(event)) { + privmx::endpoint::stream::StreamPublishedEvent event_cast = + stream::Events::extractStreamPublishedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamPublishedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamUpdatedEvent(event)) { + privmx::endpoint::stream::StreamUpdatedEvent event_cast = + stream::Events::extractStreamUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamUpdatedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamJoinedEvent(event)) { + privmx::endpoint::stream::StreamJoinedEvent event_cast = + stream::Events::extractStreamJoinedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamUnpublishedEvent(event)) { + privmx::endpoint::stream::StreamUnpublishedEvent event_cast = + stream::Events::extractStreamUnpublishedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamUnpublishedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamLeftEvent(event)) { + privmx::endpoint::stream::StreamLeftEvent event_cast = + stream::Events::extractStreamLeftEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamNewStreamsEvent(event)) { + privmx::endpoint::stream::StreamNewStreamsEvent event_cast = + stream::Events::extractStreamNewStreamsEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::newStreams2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamsUpdatedEvent(event)) { + privmx::endpoint::stream::StreamsUpdatedEvent event_cast = + stream::Events::extractStreamsUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamsUpdated2Java(ctx, event_cast.data) + ); + } + else { + return nullptr; + } + + } catch (const std::exception &e) { + throw e; + } + return nullptr; } \ No newline at end of file From 9d2de70464b3f8a1bb6a22c62d38341922ea59fa Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:22:08 +0100 Subject: [PATCH 14/26] feat: add initEvent function to header --- .../includes/privmx/endpoint/wrapper/parsers/parser.h | 5 +++++ 1 file changed, 5 insertions(+) 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 b5aaa262..a8df0ade 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 @@ -18,6 +18,8 @@ #include "privmx/endpoint/core/Types.hpp" #include "privmx/endpoint/core/Events.hpp" #include "privmx/endpoint/inbox/Types.hpp" +#include "privmx/endpoint/stream/Events.hpp" +#include "privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h" std::vector usersToVector(JniContextUtils &ctx, jobjectArray users); @@ -35,6 +37,9 @@ privmx::endpoint::core::ItemPolicy parseItemPolicy(JniContextUtils &ctx, jobject privmx::endpoint::inbox::FilesConfig parseFilesConfig(JniContextUtils &ctx, jobject filesConfig); +jobject initEvent(JniContextUtils &ctx, std::string type, std::string channel, int64_t connectionId, + std::vector &subscriptions, int64_t timestamp, jobject data_j) ; + jobject parseEvent(JniContextUtils &ctx, std::shared_ptr event); privmx::endpoint::core::PagingQuery parsePagingQuery(JniContextUtils &ctx, jobject pagingQuery); From 61a45d0a1df4633f02c07d945a600c96b0f9a8da Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:29:25 +0100 Subject: [PATCH 15/26] refactor: rename StreamPublishedEventData --- .../src/cpp/streams/parsers/model_native_initializers.cpp | 2 +- ...PublishedStreamData.java => StreamPublishedEventData.java} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/{PublishedStreamData.java => StreamPublishedEventData.java} (77%) 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 2b904b13..58563a1e 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 @@ -697,7 +697,7 @@ namespace privmx { privmx::endpoint::stream::StreamPublishedEventData data ) { jclass cls = ctx->FindClass( - "com/simplito/java/privmx_endpoint/model/events/PublishedStreamData"); + "com/simplito/java/privmx_endpoint/model/events/StreamPublishedEventData"); jmethodID ctor = ctx->GetMethodID( cls, "", diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamPublishedEventData.java similarity index 77% rename from privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java rename to privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamPublishedEventData.java index b356b4f6..2daa75e4 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/PublishedStreamData.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/model/events/StreamPublishedEventData.java @@ -4,7 +4,7 @@ // todo: which to choose // same as StreamPublishedEventData -public class PublishedStreamData { +public class StreamPublishedEventData { /** * StreamRoom ID @@ -18,7 +18,7 @@ public class PublishedStreamData { public String userId; - public PublishedStreamData(String streamRoomId, StreamInfo stream, String userId) { + public StreamPublishedEventData(String streamRoomId, StreamInfo stream, String userId) { this.streamRoomId = streamRoomId; this.stream = stream; this.userId = userId; From c5bedd19fae9662d2c162b13769aa4660626f334 Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:32:15 +0100 Subject: [PATCH 16/26] feat: add buildSubscriptionQuery to StreamApiLow --- .../src/cpp/streams/modules/StreamApiLow.cpp | 32 +++++++++++++++++++ .../modules/stream/StreamApiLow.java | 14 +++++--- 2 files changed, 41 insertions(+), 5 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 8a73037d..afbc03d5 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -649,6 +649,38 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_unsubscribeF }); } +extern "C" +JNIEXPORT jstring JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_buildSubscriptionQuery( + JNIEnv *env, + jobject thiz, + jlong event_type, + jlong selector_type, + jstring selector_id +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(selector_id, "SelectorID")) { + return nullptr; + } + + jstring result = nullptr; + ctx.callResultEndpointApi( + &result, + [&ctx, &thiz, &event_type, &selector_type, &selector_id]() { + std::string query_result_c = getStreamApi(ctx, thiz)->buildSubscriptionQuery( + static_cast(event_type), + static_cast(selector_type), + ctx.jString2string(selector_id) + ); + return ctx->NewStringUTF(query_result_c.c_str()); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + extern "C" JNIEXPORT void JNICALL Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_keyManagement( diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index 96cf1d44..b8741b1c 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -220,14 +220,18 @@ public void acceptOfferOnReconfigure( public native void unsubscribeFrom(List subscriptionIds); - // todo - // public native String buildSubscriptionQuery( - public String buildSubscriptionQuery ( + private native String buildSubscriptionQuery(long eventType, long selectorType, String selectorId); + + public String buildSubscriptionQuery( StreamEventType eventType, StreamEventSelectorType selectorType, String selectorId - ){ - return ""; + ) { + return buildSubscriptionQuery( + eventType.ordinal(), + selectorType.ordinal(), + selectorId + ); } From 30f71a135fd035bdb1e336b8ef7947dd06a7128c Mon Sep 17 00:00:00 2001 From: Doominika Date: Wed, 4 Feb 2026 11:38:01 +0100 Subject: [PATCH 17/26] feat: add class for handling parsing functions used by EventQueue --- jni-wrappers/privmx-endpoint/CMakeLists.txt | 1 + .../endpoint/wrapper/modules/EventsList.h | 42 +++++++++++++++++++ .../src/cpp/modules/EventQueue.cpp | 7 ++-- .../src/cpp/streams/modules/StreamApiLow.cpp | 4 +- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h diff --git a/jni-wrappers/privmx-endpoint/CMakeLists.txt b/jni-wrappers/privmx-endpoint/CMakeLists.txt index 91ce8815..bca774ac 100644 --- a/jni-wrappers/privmx-endpoint/CMakeLists.txt +++ b/jni-wrappers/privmx-endpoint/CMakeLists.txt @@ -29,6 +29,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/ExtKey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/Utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/KvdbApi.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/EventsList.cpp src/cpp/streams/modules/StreamApiLow.cpp src/cpp/streams/modules/WebRTCInterfaceJNI.cpp src/cpp/streams/modules/StreamSettingsJNI.cpp diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h new file mode 100644 index 00000000..cf77091c --- /dev/null +++ b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h @@ -0,0 +1,42 @@ +#ifndef PRIVMXENDPOINT_EVENTSLIST_H +#define PRIVMXENDPOINT_EVENTSLIST_H + +#include "privmx/endpoint/wrapper/parsers/parser.h" + +class EventsList { +private: + EventsList() { + addParser(parseEvent); + } + +public: + static EventsList &instance(){ + static EventsList eventsList; + return eventsList; + } + + void addParser( jobject (*fun)(JniContextUtils&, std::shared_ptr)){ + list_of_parsers.push_back(fun); + } + + jobject getEvent( + JniContextUtils& ctx, + std::shared_ptr event + ) { + int size = list_of_parsers.size() -1; + for(int i=size; i>=0; --i) + { + jobject res = list_of_parsers[i](ctx, event); + if (res != nullptr) { + return res; + } + } + + return nullptr; + } + + std::vector< jobject (*)(JniContextUtils &ctx, std::shared_ptr event)> list_of_parsers; +}; + + +#endif //PRIVMXENDPOINT_EVENTSLIST_H diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp index 22af8d15..6c5b833c 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp @@ -13,6 +13,7 @@ #include #include "privmx/endpoint/wrapper/utils/utils.hpp" #include "privmx/endpoint/wrapper/parsers/parser.h" +#include "privmx/endpoint/wrapper/modules/EventsList.h" using namespace privmx::endpoint::core; @@ -36,7 +37,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_core_EventQueue_waitEvent( JniContextUtils ctx(env); jobject result; ctx.callResultEndpointApi(&result, [&ctx]() { - return parseEvent(ctx, EventQueue::getInstance().waitEvent().get()); + return EventsList::instance().getEvent(ctx, EventQueue::getInstance().waitEvent().get()); }); if (ctx->ExceptionCheck()) { return nullptr; @@ -54,8 +55,8 @@ Java_com_simplito_java_privmx_1endpoint_modules_core_EventQueue_getEvent( ctx.callResultEndpointApi(&result, [&ctx]() { auto eventHolder = EventQueue::getInstance().getEvent(); return !eventHolder.has_value() ? - nullptr : - parseEvent(ctx, eventHolder.value().get()); + nullptr : + EventsList::instance().getEvent(ctx, eventHolder.value().get()); }); if (ctx->ExceptionCheck()) { return nullptr; 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 afbc03d5..568c4276 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -13,7 +13,7 @@ #include "privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h" #include "privmx/endpoint/wrapper/streams/parsers/parser.h" -//#include +#include "privmx/endpoint/wrapper/modules/EventsList.h" using namespace privmx::endpoint::stream; using namespace privmx::endpoint; @@ -75,6 +75,8 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_create( return nullptr; } + EventsList::instance().addParser(parseStreamEvent); + // jobject result; // ctx.callResultEndpointApi(&result, [&ctx, &env, &clazz, &connection, &eventApi] { jmethodID initMID = ctx->GetMethodID(clazz, "", From f82213cbce8fe81fb8afc6c5e87bc43b63d5fc8c Mon Sep 17 00:00:00 2001 From: Doominika Date: Fri, 6 Feb 2026 10:53:03 +0100 Subject: [PATCH 18/26] refactor: move stream events to core events and remove EventsList class --- jni-wrappers/privmx-endpoint/CMakeLists.txt | 1 - .../endpoint/wrapper/modules/EventsList.h | 42 ----- .../privmx/endpoint/wrapper/parsers/parser.h | 3 - .../endpoint/wrapper/streams/parsers/parser.h | 4 +- .../src/cpp/modules/EventQueue.cpp | 5 +- .../src/cpp/parsers/parser.cpp | 129 ++++++++++++++++ .../src/cpp/streams/modules/StreamApiLow.cpp | 4 - .../src/cpp/streams/parsers/parser.cpp | 143 ------------------ 8 files changed, 132 insertions(+), 199 deletions(-) delete mode 100644 jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h diff --git a/jni-wrappers/privmx-endpoint/CMakeLists.txt b/jni-wrappers/privmx-endpoint/CMakeLists.txt index bca774ac..91ce8815 100644 --- a/jni-wrappers/privmx-endpoint/CMakeLists.txt +++ b/jni-wrappers/privmx-endpoint/CMakeLists.txt @@ -29,7 +29,6 @@ add_library(${CMAKE_PROJECT_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/ExtKey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/Utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/KvdbApi.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/modules/EventsList.cpp src/cpp/streams/modules/StreamApiLow.cpp src/cpp/streams/modules/WebRTCInterfaceJNI.cpp src/cpp/streams/modules/StreamSettingsJNI.cpp diff --git a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h b/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h deleted file mode 100644 index cf77091c..00000000 --- a/jni-wrappers/privmx-endpoint/includes/privmx/endpoint/wrapper/modules/EventsList.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef PRIVMXENDPOINT_EVENTSLIST_H -#define PRIVMXENDPOINT_EVENTSLIST_H - -#include "privmx/endpoint/wrapper/parsers/parser.h" - -class EventsList { -private: - EventsList() { - addParser(parseEvent); - } - -public: - static EventsList &instance(){ - static EventsList eventsList; - return eventsList; - } - - void addParser( jobject (*fun)(JniContextUtils&, std::shared_ptr)){ - list_of_parsers.push_back(fun); - } - - jobject getEvent( - JniContextUtils& ctx, - std::shared_ptr event - ) { - int size = list_of_parsers.size() -1; - for(int i=size; i>=0; --i) - { - jobject res = list_of_parsers[i](ctx, event); - if (res != nullptr) { - return res; - } - } - - return nullptr; - } - - std::vector< jobject (*)(JniContextUtils &ctx, std::shared_ptr event)> list_of_parsers; -}; - - -#endif //PRIVMXENDPOINT_EVENTSLIST_H 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 a8df0ade..696db804 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 @@ -37,9 +37,6 @@ privmx::endpoint::core::ItemPolicy parseItemPolicy(JniContextUtils &ctx, jobject privmx::endpoint::inbox::FilesConfig parseFilesConfig(JniContextUtils &ctx, jobject filesConfig); -jobject initEvent(JniContextUtils &ctx, std::string type, std::string channel, int64_t connectionId, - std::vector &subscriptions, int64_t timestamp, jobject data_j) ; - jobject parseEvent(JniContextUtils &ctx, std::shared_ptr event); privmx::endpoint::core::PagingQuery parsePagingQuery(JniContextUtils &ctx, jobject pagingQuery); 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 5f17fdf9..136ad2ab 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 @@ -31,6 +31,4 @@ privmx::endpoint::stream::StreamSettings parseStreamSettings(JNIEnv *env, jobjec privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextUtils &ctx, jobject streamSubscription); -//#endif //PRIVMX_POCKET_LIB_PARSER_H - jobject parseStreamEvent(JniContextUtils &ctx, std::shared_ptr event); - +privmx::endpoint::stream::SdpWithTypeModel parseSdpWithTypeModel(JniContextUtils &ctx, jobject sdpWithTypeModel); diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp index 6c5b833c..b5a2b810 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/EventQueue.cpp @@ -13,7 +13,6 @@ #include #include "privmx/endpoint/wrapper/utils/utils.hpp" #include "privmx/endpoint/wrapper/parsers/parser.h" -#include "privmx/endpoint/wrapper/modules/EventsList.h" using namespace privmx::endpoint::core; @@ -37,7 +36,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_core_EventQueue_waitEvent( JniContextUtils ctx(env); jobject result; ctx.callResultEndpointApi(&result, [&ctx]() { - return EventsList::instance().getEvent(ctx, EventQueue::getInstance().waitEvent().get()); + return parseEvent(ctx, EventQueue::getInstance().waitEvent().get()); }); if (ctx->ExceptionCheck()) { return nullptr; @@ -56,7 +55,7 @@ Java_com_simplito_java_privmx_1endpoint_modules_core_EventQueue_getEvent( auto eventHolder = EventQueue::getInstance().getEvent(); return !eventHolder.has_value() ? nullptr : - EventsList::instance().getEvent(ctx, eventHolder.value().get()); + parseEvent(ctx, eventHolder.value().get()); }); if (ctx->ExceptionCheck()) { return nullptr; diff --git a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp index c14a2497..64587b35 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/parsers/parser.cpp @@ -647,6 +647,135 @@ parseEvent(JniContextUtils &ctx, std::shared_ptr event_cast.timestamp, privmx::wrapper::kvdbDeletedEntryEventData2Java(ctx, event_cast.data) ); + } else if (stream::Events::isStreamRoomCreatedEvent(event)) { + privmx::endpoint::stream::StreamRoomCreatedEvent event_cast = stream::Events::extractStreamRoomCreatedEvent( + event); + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamRoomUpdatedEvent(event)) { + privmx::endpoint::stream::StreamRoomUpdatedEvent event_cast = + stream::Events::extractStreamRoomUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamRoomDeletedEvent(event)) { + privmx::endpoint::stream::StreamRoomDeletedEvent event_cast = + stream::Events::extractStreamRoomDeletedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamRoomDeletedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamPublishedEvent(event)) { + privmx::endpoint::stream::StreamPublishedEvent event_cast = + stream::Events::extractStreamPublishedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamPublishedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamUpdatedEvent(event)) { + privmx::endpoint::stream::StreamUpdatedEvent event_cast = + stream::Events::extractStreamUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamUpdatedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamJoinedEvent(event)) { + privmx::endpoint::stream::StreamJoinedEvent event_cast = + stream::Events::extractStreamJoinedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamUnpublishedEvent(event)) { + privmx::endpoint::stream::StreamUnpublishedEvent event_cast = + stream::Events::extractStreamUnpublishedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamUnpublishedEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamLeftEvent(event)) { + privmx::endpoint::stream::StreamLeftEvent event_cast = + stream::Events::extractStreamLeftEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamNewStreamsEvent(event)) { + privmx::endpoint::stream::StreamNewStreamsEvent event_cast = + stream::Events::extractStreamNewStreamsEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::newStreams2Java(ctx, event_cast.data) + ); + } else if (stream::Events::isStreamsUpdatedEvent(event)) { + privmx::endpoint::stream::StreamsUpdatedEvent event_cast = + stream::Events::extractStreamsUpdatedEvent(event); + + return initEvent( + ctx, + event_cast.type, + event_cast.channel, + event_cast.connectionId, + event_cast.subscriptions, + event_cast.timestamp, + privmx::wrapper::streams::streamsUpdated2Java(ctx, event_cast.data) + ); } else { return initEvent( ctx, 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 568c4276..32a23873 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -13,8 +13,6 @@ #include "privmx/endpoint/wrapper/streams/parsers/model_native_initializers.h" #include "privmx/endpoint/wrapper/streams/parsers/parser.h" -#include "privmx/endpoint/wrapper/modules/EventsList.h" - using namespace privmx::endpoint::stream; using namespace privmx::endpoint; //using namespace privmx::wrapper; @@ -75,8 +73,6 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_create( return nullptr; } - EventsList::instance().addParser(parseStreamEvent); - // jobject result; // ctx.callResultEndpointApi(&result, [&ctx, &env, &clazz, &connection, &eventApi] { jmethodID initMID = ctx->GetMethodID(clazz, "", 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 68e5c18e..e16d244f 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp @@ -104,146 +104,3 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU return result; } - -jobject -parseStreamEvent(JniContextUtils &ctx, std::shared_ptr event) { - try { - if (stream::Events::isStreamRoomCreatedEvent(event)) { - privmx::endpoint::stream::StreamRoomCreatedEvent event_cast = stream::Events::extractStreamRoomCreatedEvent( - event); - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamRoomUpdatedEvent(event)) { - privmx::endpoint::stream::StreamRoomUpdatedEvent event_cast = - stream::Events::extractStreamRoomUpdatedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamRoom2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamRoomDeletedEvent(event)) { - privmx::endpoint::stream::StreamRoomDeletedEvent event_cast = - stream::Events::extractStreamRoomDeletedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamRoomDeletedEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamPublishedEvent(event)) { - privmx::endpoint::stream::StreamPublishedEvent event_cast = - stream::Events::extractStreamPublishedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamPublishedEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamUpdatedEvent(event)) { - privmx::endpoint::stream::StreamUpdatedEvent event_cast = - stream::Events::extractStreamUpdatedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamUpdatedEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamJoinedEvent(event)) { - privmx::endpoint::stream::StreamJoinedEvent event_cast = - stream::Events::extractStreamJoinedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamUnpublishedEvent(event)) { - privmx::endpoint::stream::StreamUnpublishedEvent event_cast = - stream::Events::extractStreamUnpublishedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamUnpublishedEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamLeftEvent(event)) { - privmx::endpoint::stream::StreamLeftEvent event_cast = - stream::Events::extractStreamLeftEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamEventData2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamNewStreamsEvent(event)) { - privmx::endpoint::stream::StreamNewStreamsEvent event_cast = - stream::Events::extractStreamNewStreamsEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::newStreams2Java(ctx, event_cast.data) - ); - } else if (stream::Events::isStreamsUpdatedEvent(event)) { - privmx::endpoint::stream::StreamsUpdatedEvent event_cast = - stream::Events::extractStreamsUpdatedEvent(event); - - return initEvent( - ctx, - event_cast.type, - event_cast.channel, - event_cast.connectionId, - event_cast.subscriptions, - event_cast.timestamp, - privmx::wrapper::streams::streamsUpdated2Java(ctx, event_cast.data) - ); - } - else { - return nullptr; - } - - } catch (const std::exception &e) { - throw e; - } - return nullptr; -} \ No newline at end of file From d0b340503a12ebfef7894f6916bfb653cd58f030 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 11:51:24 +0100 Subject: [PATCH 19/26] refactor: add missing type to StreamEventType --- .../privmx_endpoint/model/events/eventTypes/StreamEventType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventTypes/StreamEventType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventTypes/StreamEventType.java index 54f7f7ad..99e18c0f 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventTypes/StreamEventType.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventTypes/StreamEventType.java @@ -4,6 +4,7 @@ public enum StreamEventType implements EventType{ STREAMROOM_CREATE, STREAMROOM_UPDATE, STREAMROOM_DELETE, + EMPTY, STREAM_JOIN, STREAM_LEAVE, STREAM_PUBLISH, From 4acf01ce800baa8168f99024d30ecd9afe95a88e Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 11:52:18 +0100 Subject: [PATCH 20/26] chore: change removeVideoTrack --- .../modules/stream/JanusPublisher.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/JanusPublisher.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/JanusPublisher.java index 8c1128ec..027e9259 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/JanusPublisher.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/JanusPublisher.java @@ -92,9 +92,24 @@ public void removeAudioTrack(String id) { public void removeVideoTrack(String id) { VideoTrackInfo videoTrackInfo = videoTracks.get(id); if(videoTrackInfo == null) return; +// peerConnection.removeTrack(videoTrackInfo.sender); +// videoTracks.remove(id); +// videoCapturers.remove(id); + + videoTrackInfo.track.setEnabled(false); + VideoCapturer videoCapturer = videoCapturers.get(id); + + if (videoCapturer != null) { + try { + videoCapturer.stopCapture(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// videoCapturer.dispose(); + } peerConnection.removeTrack(videoTrackInfo.sender); - videoTracks.remove(id); - videoCapturers.remove(id); + + System.out.println("track video removed"); } public String createOffer(){ From 9026e420b0b0f1a5edf5d6024e21a3f55fbd7312 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 11:54:10 +0100 Subject: [PATCH 21/26] feat: add missing methods --- .../src/cpp/streams/modules/StreamApiLow.cpp | 55 +++++++++++++++++++ .../modules/stream/StreamApiLow.java | 8 +-- 2 files changed, 58 insertions(+), 5 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 32a23873..2c3e2c94 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -867,4 +867,59 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_subscribeToR parseSettings(ctx, options) ); }); +} +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_updateStream( + JNIEnv *env, + jobject thiz, + jobject stream_handle +) { + JniContextUtils ctx(env); + jobject result; + + ctx.callResultEndpointApi( + &result, [ + &ctx, + &env, + &thiz, + &stream_handle + ] { + + auto stream_handle_c = parseStreamHandle(ctx, stream_handle); + auto stream_result = getStreamApi(ctx, thiz)->updateStream( + stream_handle_c + ); + + return privmx::wrapper::streams::streamPublishResult2Java( + ctx, + stream_result + ); + + }); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_acceptOfferOnReconfigure( + JNIEnv *env, + jobject thiz, + jlong session_id, + jobject sdp +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(sdp, " SDP")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &session_id, &sdp]() { + + getStreamApi(ctx, thiz)->acceptOfferOnReconfigure( + session_id, + parseSdpWithTypeModel(ctx, sdp) + ); + }); } \ No newline at end of file diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index b8741b1c..63a809d2 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -208,13 +208,11 @@ public StreamPublishResult updateStream( // todo - // public native void acceptOfferOnReconfigure( - public void acceptOfferOnReconfigure( + public native void acceptOfferOnReconfigure( +// public void acceptOfferOnReconfigure( long sessionId, SdpWithTypeModel sdp - ){ - - } + ); public native List subscribeFor(List subscriptionQueries); From 492800ac3544f308dc04db08c6788d6871ceb9b4 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 15:15:51 +0100 Subject: [PATCH 22/26] chore: cleaning --- .../src/cpp/streams/modules/StreamApiLow.cpp | 10 ++-- .../cpp/streams/modules/StreamSettingsJNI.cpp | 50 +++++++++---------- .../src/cpp/streams/parsers/parser.cpp | 17 +++++++ .../modules/stream/StreamApiLow.java | 10 +--- .../modules/core/Connection.java | 1 + .../modules/inbox/InboxApi.java | 2 + settings.gradle | 6 ++- 7 files changed, 55 insertions(+), 41 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 2c3e2c94..0033d88e 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamApiLow.cpp @@ -422,12 +422,10 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_publishStrea auto result = getStreamApi(ctx, thiz)->publishStream( parseStreamHandle(ctx, stream_handle) ); - return nullptr; - //TODO: Return result -// return privmx::wrapper::streams::streamPublishResult2Java( -// ctx, -// result -// ); + return privmx::wrapper::streams::streamPublishResult2Java( + ctx, + result + ); }); if (ctx->ExceptionCheck()) { return nullptr; diff --git a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamSettingsJNI.cpp b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamSettingsJNI.cpp index e9685892..64075393 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamSettingsJNI.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/modules/StreamSettingsJNI.cpp @@ -25,31 +25,31 @@ namespace privmx::wrapper::streams { this->jstreamSettings = env->NewGlobalRef(jstreamSettings); - this->OnFrame = [this]( - int64_t a, - int64_t b, - const std::shared_ptr &frame, - const std::string &c - ) { - JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( - javaVM, - privmx::wrapper::jni::getPrivmxCallbackThreadName()); - JniContextUtils ctx(env); - }; - - this->OnVideo = [this](const std::string &a) { - JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( - javaVM, - privmx::wrapper::jni::getPrivmxCallbackThreadName()); - JniContextUtils ctx(env); - }; - - this->OnVideoRemove = [this](const std::string &a) { - JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( - javaVM, - privmx::wrapper::jni::getPrivmxCallbackThreadName()); - JniContextUtils ctx(env); - }; +// this->OnFrame = [this]( +// int64_t a, +// int64_t b, +// const std::shared_ptr &frame, +// const std::string &c +// ) { +// JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( +// javaVM, +// privmx::wrapper::jni::getPrivmxCallbackThreadName()); +// JniContextUtils ctx(env); +// }; +// +// this->OnVideo = [this](const std::string &a) { +// JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( +// javaVM, +// privmx::wrapper::jni::getPrivmxCallbackThreadName()); +// JniContextUtils ctx(env); +// }; +// +// this->OnVideoRemove = [this](const std::string &a) { +// JNIEnv *env = privmx::wrapper::jni::AttachCurrentThreadIfNeeded( +// javaVM, +// privmx::wrapper::jni::getPrivmxCallbackThreadName()); +// JniContextUtils ctx(env); +// }; } // void StreamSettingsJNI::StreamSettingsJNI::onVideo2( 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 e16d244f..942ec002 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/streams/parsers/parser.cpp @@ -104,3 +104,20 @@ privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextU return result; } + +privmx::endpoint::stream::SdpWithTypeModel parseSdpWithTypeModel(JniContextUtils &ctx, jobject sdpWithTypeModel){ + jclass cls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/SdpWithTypeModel"); + + jfieldID sdpFID = ctx->GetFieldID(cls, "sdp", "Ljava/lang/String;"); + jfieldID typeFID = ctx->GetFieldID(cls, "type", "Ljava/lang/String;"); + + jstring sdp_j = (jstring) ctx->GetObjectField(sdpWithTypeModel, sdpFID); + jstring type_j = (jstring) ctx->GetObjectField(sdpWithTypeModel, typeFID); + + privmx::endpoint::stream::SdpWithTypeModel result; + result.sdp = ctx.jString2string(sdp_j); + result.type = ctx.jString2string(type_j); + + return result; +} diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java index 63a809d2..65f8c233 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -189,12 +189,7 @@ public native StreamHandle createStream( public native StreamPublishResult publishStream(StreamHandle streamHandle); // todo - // public native StreamPublishResult updateStream( - public StreamPublishResult updateStream( - StreamHandle streamHandle - ){ - return new StreamPublishResult(false); - } + public native StreamPublishResult updateStream(StreamHandle streamHandle); public native void unpublishStream(StreamHandle streamHandle); @@ -208,8 +203,7 @@ public StreamPublishResult updateStream( // todo - public native void acceptOfferOnReconfigure( -// public void acceptOfferOnReconfigure( + public native void acceptOfferOnReconfigure( long sessionId, SdpWithTypeModel sdp ); diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/core/Connection.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/core/Connection.java index b2668a26..dfe54837 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/core/Connection.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/core/Connection.java @@ -20,6 +20,7 @@ import com.simplito.java.privmx_endpoint.model.events.eventTypes.CoreEventType; import com.simplito.java.privmx_endpoint.model.exceptions.NativeException; import com.simplito.java.privmx_endpoint.model.exceptions.PrivmxException; +import java.util.List; /** * Manages a connection between the Endpoint and the Bridge server. diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/inbox/InboxApi.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/inbox/InboxApi.java index a1976813..df7a3033 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/inbox/InboxApi.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/inbox/InboxApi.java @@ -26,6 +26,8 @@ import com.simplito.java.privmx_endpoint.modules.core.Connection; import com.simplito.java.privmx_endpoint.modules.store.StoreApi; import com.simplito.java.privmx_endpoint.modules.thread.ThreadApi; +import com.simplito.java.privmx_endpoint.model.events.InboxDeletedEventData; +import com.simplito.java.privmx_endpoint.model.events.InboxEntryDeletedEventData; import java.util.Collections; import java.util.List; diff --git a/settings.gradle b/settings.gradle index 0e3aaebb..76c9202b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -39,8 +39,10 @@ include ':privmx-endpoint-android' include ':privmx-endpoint-jni' include ':examples:privmx-snippets' +include ":jni-wrappers" + // streams -include ':privmx-endpoint-streams-android' -include ':privmx-endpoint-streams:jvm' +include ':privmx-endpoint-streams:android' +//include ':privmx-endpoint-streams:jvm' project(':privmx-endpoint-jni').projectDir = file("privmx-endpoint/src/main/cpp") \ No newline at end of file From fd809274cd5932d9b7f2449667a9de1cacc953af Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 15:19:38 +0100 Subject: [PATCH 23/26] chore: delete privmx-endpoint-streams-android --- .../src/main/AndroidManifest.xml | 4 - .../model/AudioTrackInfo.java | 22 - .../model/ConnectionType.java | 6 - .../model/DeviceType.java | 7 - .../privmx_endpoint_streams/model/Frame.java | 8 - .../model/JanusConnection.java | 13 - .../privmx_endpoint_streams/model/Key.java | 28 - .../model/KeyType.java | 17 - .../model/MediaDevice.java | 13 - .../model/OnFrameCallback.java | 8 - .../model/PcObserver.java | 158 ---- .../model/PeerConnection2.java | 54 -- .../model/PeerConnectionManager.java | 57 -- .../model/PmxPeerConnectionObserver.java | 118 --- .../model/PublishedStreamData.java | 13 - .../model/SdpWithTypeModel.java | 25 - .../model/Settings.java | 6 - .../privmx_endpoint_streams/model/Stream.java | 25 - .../model/StreamHandle.java | 13 - .../model/StreamInfo.java | 49 - .../model/StreamPublishResult.java | 18 - .../model/StreamRoom.java | 62 -- .../model/StreamSettings.java | 38 - .../model/StreamStatus.java | 6 - .../model/StreamSubscription.java | 15 - .../model/StreamTrackInfo.java | 99 -- .../model/TurnCredentials.java | 31 - .../model/VideoTrackInfo.java | 21 - .../modules/PmxPeerConnectionClient2.java | 472 ---------- .../modules/StreamApi.java | 860 ------------------ .../modules/StreamApiLow.java | 163 ---- .../modules/WebRTCInterface.java | 29 - 32 files changed, 2458 deletions(-) delete mode 100644 privmx-endpoint-streams-android/src/main/AndroidManifest.xml delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/AudioTrackInfo.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/ConnectionType.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/DeviceType.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Frame.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/JanusConnection.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Key.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/KeyType.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/MediaDevice.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/OnFrameCallback.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PcObserver.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnection2.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnectionManager.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PmxPeerConnectionObserver.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PublishedStreamData.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/SdpWithTypeModel.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Settings.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Stream.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamHandle.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamInfo.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamRoom.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSettings.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamStatus.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSubscription.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamTrackInfo.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/TurnCredentials.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/VideoTrackInfo.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/PmxPeerConnectionClient2.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApi.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApiLow.java delete mode 100644 privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/WebRTCInterface.java diff --git a/privmx-endpoint-streams-android/src/main/AndroidManifest.xml b/privmx-endpoint-streams-android/src/main/AndroidManifest.xml deleted file mode 100644 index a8800291..00000000 --- a/privmx-endpoint-streams-android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/AudioTrackInfo.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/AudioTrackInfo.java deleted file mode 100644 index da07e0d8..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/AudioTrackInfo.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - - -import org.webrtc.AudioTrack; -import org.webrtc.PmxFrameCryptor; -import org.webrtc.RtpSender; - -public class AudioTrackInfo { - public org.webrtc.AudioTrack track; - public org.webrtc.RtpSender sender; - public PmxFrameCryptor frameCryptor; - - public AudioTrackInfo( - AudioTrack track, - RtpSender sender, - PmxFrameCryptor frameCryptor - ) { - this.track = track; - this.sender = sender; - this.frameCryptor = frameCryptor; - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/ConnectionType.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/ConnectionType.java deleted file mode 100644 index 0a2a9a56..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/ConnectionType.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public enum ConnectionType { - Subscriber, - Publisher -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/DeviceType.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/DeviceType.java deleted file mode 100644 index f378c1f4..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/DeviceType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public enum DeviceType { - Audio, - Video, - Desktop -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Frame.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Frame.java deleted file mode 100644 index 0bf56551..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Frame.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public abstract class Frame { - public Frame() {} - public int ConvertToRGBA(byte dst_argb, int dst_stride_argb, int dest_width, int dest_height){ - return 0; - }; -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/JanusConnection.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/JanusConnection.java deleted file mode 100644 index 5582972b..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/JanusConnection.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class JanusConnection { - public final PeerConnection2 peerConnection; - public final long sessionId; - public final boolean hasSubscriptions; - - public JanusConnection(PeerConnection2 peerConnection, long sessionId, boolean hasSubscriptions) { - this.peerConnection = peerConnection; - this.sessionId = sessionId; - this.hasSubscriptions = hasSubscriptions; - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Key.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Key.java deleted file mode 100644 index e3ffd299..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Key.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -public class Key { - public String keyId; - public byte[] key; - public KeyType type; - - public Key( - String keyId, - byte[] key, - KeyType type - ) { - this.keyId = keyId; - this.key = key; - this.type = type; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/KeyType.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/KeyType.java deleted file mode 100644 index 5bb6a732..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/KeyType.java +++ /dev/null @@ -1,17 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -public enum KeyType { - LOCAL, - REMOTE -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/MediaDevice.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/MediaDevice.java deleted file mode 100644 index 091dbc65..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/MediaDevice.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class MediaDevice { - public String name; - public String id; - public DeviceType type; - - public MediaDevice(String name, String id, DeviceType type) { - this.name = name; - this.id = id; - this.type = type; - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/OnFrameCallback.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/OnFrameCallback.java deleted file mode 100644 index 6309bf87..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/OnFrameCallback.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import com.simplito.java.privmx_endpoint.model.Frame; - -@FunctionalInterface -public interface OnFrameCallback { - void run(long a, long b, Frame c, String d); -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PcObserver.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PcObserver.java deleted file mode 100644 index b7a5db31..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PcObserver.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import org.webrtc.DataChannel; -import org.webrtc.IceCandidate; -import org.webrtc.MediaStream; -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 org.webrtc.RtpReceiver; -import org.webrtc.RtpTransceiver; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -public class PcObserver implements PeerConnection.Observer { - Map frameCryptorMap = new HashMap<>(); - PmxKeyStore keyStore; - private PeerConnectionFactory peerConnectionFactory; - private String streamRoomId; - private PmxFrameCryptor.PmxFrameCryptorOptions options; - - private BiConsumer, RtpReceiver> onAddTrack; - private Consumer onVideoTrack; - private OnFrameCallback onFrameCallback = null; - private Consumer onRemoveVideoTrack = null; - - private Consumer onSignalingState; - private Consumer onPeerConnectionState; - private Consumer onIceGatheringState; - private Consumer onIceConnectionState; - private Consumer onIceCandidate; - private Consumer onAddStream; - private Consumer onRemoveStream; - private Consumer onDataChannel; - private Runnable onRenegotiationNeeded; - private Consumer onTrack; - private Consumer onRemoveTrack; - - - public PcObserver(PeerConnectionFactory peerConnectionFactory, String streamRoomId, PmxKeyStore store, PmxFrameCryptor.PmxFrameCryptorOptions options) { - this.peerConnectionFactory = peerConnectionFactory; - this.streamRoomId = streamRoomId; - this.keyStore = store; - this.options = options; - } - - public void setOnAddTrack(BiConsumer, RtpReceiver> onAddTrack) { - this.onAddTrack = onAddTrack; - } - - public void setOnVideoTrack(Consumer onVideoTrack) { - this.onVideoTrack = onVideoTrack; - } - - @Override - public void onSignalingChange(PeerConnection.SignalingState signalingState) { - - } - - @Override - public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) { - - } - - @Override - public void onIceConnectionReceivingChange(boolean b) { - - } - - @Override - public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) { - - } - - @Override - public void onIceCandidate(IceCandidate iceCandidate) { - - } - - @Override - public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) { - - } - - @Override - public void onAddStream(MediaStream mediaStream) { - - } - - @Override - public void onRemoveStream(MediaStream mediaStream) { - - } - - @Override - public void onDataChannel(DataChannel dataChannel) { - - } - - @Override - public void onRenegotiationNeeded() { - - } - - @Override - public void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams) { - if (peerConnectionFactory != null && receiver.track() != null && receiver.track().id().equals(null)) { - frameCryptorMap.put( - receiver.track().id(), - PmxFrameCryptorFactory.createPmxFrameCryptorForRtpReceiver( - peerConnectionFactory, - receiver, - keyStore - ) - ); - } - if (onAddTrack != null) { - onAddTrack.accept(Arrays.asList(mediaStreams), receiver); - - if (Objects.equals(receiver.track().kind(), MediaStreamTrack.VIDEO_TRACK_KIND)) { - onVideoTrack.accept(receiver.track().id()); - } - } - } - - @Override - public void onTrack(RtpTransceiver transceiver) { - // todo -check -// RtpReceiver rtpReceiver = transceiver.getReceiver(); -// MediaStreamTrack track = rtpReceiver.track(); -// if (trackObserver != null) trackObserver.onTrack(track); -// // TODO: check if no duplication -// PmxFrameCryptorFactory.createPmxFrameCryptorForRtpReceiver(peerConnectionFactory, rtpReceiver, store); - - onTrack.accept(transceiver); - } - - public void setFrameCryptorOptions(PmxFrameCryptor.PmxFrameCryptorOptions options) { - this.options = options; - frameCryptorMap.forEach((k, v) -> v.setOptions(options)); - } - - public void setOnFrame(OnFrameCallback onFrame) { - this.onFrameCallback = onFrame; - } - - public void setOnRemoveVideoTrack(Consumer onRemoveVideoTrack) { - this.onRemoveVideoTrack = onRemoveVideoTrack; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnection2.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnection2.java deleted file mode 100644 index 2b95eec8..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnection2.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import org.webrtc.PeerConnection; -import org.webrtc.PmxFrameCryptor; -import org.webrtc.PmxKeyStore; - -import java.util.HashMap; -import java.util.Map; - -public class PeerConnection2 { - public PeerConnection pc; - public PcObserver observer; - public PmxKeyStore keys; - public Map audioTracks = new HashMap<>(); - public Map videoTracks = new HashMap<>(); - - public PeerConnection2(PeerConnection pc, PcObserver observer, PmxKeyStore keys) { - this.pc = pc; - this.observer = observer; - this.keys = keys; - } - - public void addVideoTrack(String id, VideoTrackInfo track) { - videoTracks.put(id, track); - } - - public void addAudioTrack(String id, AudioTrackInfo track) { - audioTracks.put(id, track); - } - - public void removeAudioTrack(String id) { - AudioTrackInfo audioTrack = audioTracks.get(id); - assert audioTrack != null; - pc.removeTrack(audioTrack.sender); - audioTracks.remove(id); - } - - public void removeVideoTrack(String id) { - VideoTrackInfo videoTrack = videoTracks.get(id); - assert videoTrack != null; - pc.removeTrack(videoTrack.sender); - videoTracks.remove(id); - } - - public void setFrameCryptorOptions(PmxFrameCryptor.PmxFrameCryptorOptions options) { - observer.setFrameCryptorOptions(options); - } - - - // std::map audioTracks; -// std::map videoTracks; -// std::shared_mutex trackMutex; -// std::shared_ptr keys; -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnectionManager.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnectionManager.java deleted file mode 100644 index 4fdd88c1..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PeerConnectionManager.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import org.webrtc.PeerConnection; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -public class PeerConnectionManager { - - private Map> connections = new HashMap<>(); - - public PeerConnectionManager( - Function peerConnectionCreator, - Function onTrickle - ) { - - } - - public void initialize (String streamRoomId, ConnectionType connectionType, Long sessionId){ - if(connections.containsKey(streamRoomId)) { - Map roomConnections = connections.get(streamRoomId); - - assert roomConnections != null; - if(roomConnections.getOrDefault(connectionType, null) == null){ - // throw exception - } - } - -// PeerConnection pc = createPeerConnection(streamRoomId); -// setOnIceCandidate - - } - - public void initialize (String streamRoomId, ConnectionType connectionType){ - initialize(streamRoomId, connectionType, -1L); - } - - void updateSessionForConnection(String streamRoomId, ConnectionType connectionType, long sessionId){ - - } - -// boolean hasConnection(String streamRoomId, ConnectionType connectionType){ -// -// } -// - JanusConnection getConnectionWithSession(String streamRoomId, ConnectionType connectionType){ - - return new JanusConnection(null, 0, false); // todo - } - - private PeerConnection createPeerConnection(String streamRoomId){ - return null; // todo - } -} - - diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PmxPeerConnectionObserver.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PmxPeerConnectionObserver.java deleted file mode 100644 index f54fa60a..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PmxPeerConnectionObserver.java +++ /dev/null @@ -1,118 +0,0 @@ -//package com.simplito.java.privmx_endpoint_streams; -// -//import org.webrtc.CandidatePairChangeEvent; -//import org.webrtc.DataChannel; -//import org.webrtc.FrameCryptorAlgorithm; -//import org.webrtc.FrameCryptorFactory; -//import org.webrtc.IceCandidate; -//import org.webrtc.IceCandidateErrorEvent; -//import org.webrtc.MediaStream; -//import org.webrtc.PeerConnection; -//import org.webrtc.PeerConnectionFactory; -//import org.webrtc.PmxFrameCryptor; -//import org.webrtc.PmxFrameCryptorFactory; -//import org.webrtc.PmxKeyStore; -//import org.webrtc.RtpReceiver; -//import org.webrtc.RtpTransceiver; -// -//public class PmxPeerConnectionObserver implements PeerConnection.Observer { -// -// public PeerConnectionFactory peerConnectionFactory; -// public String streamRoomId; -// public PmxKeyStore store; -// public PmxFrameCryptor.PmxFrameCryptorOptions options; -// -// public PmxPeerConnectionObserver(PeerConnectionFactory peerConnectionFactory, String streamRoomId, PmxKeyStore store, PmxFrameCryptor.PmxFrameCryptorOptions options) { -// this.peerConnectionFactory = peerConnectionFactory; -// this.streamRoomId = streamRoomId; -// this.store = store; -// this.options = options; -// } -// -// @Override -// public void onSignalingChange(PeerConnection.SignalingState signalingState) { -// -// } -// -// @Override -// public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) { -// -// } -// -// @Override -// public void onStandardizedIceConnectionChange(PeerConnection.IceConnectionState newState) { -// PeerConnection.Observer.super.onStandardizedIceConnectionChange(newState); -// } -// -// @Override -// public void onConnectionChange(PeerConnection.PeerConnectionState newState) { -// PeerConnection.Observer.super.onConnectionChange(newState); -// } -// -// @Override -// public void onIceConnectionReceivingChange(boolean b) { -// -// } -// -// @Override -// public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) { -// -// } -// -// @Override -// public void onIceCandidate(IceCandidate iceCandidate) { -// -// } -// -// @Override -// public void onIceCandidateError(IceCandidateErrorEvent event) { -// PeerConnection.Observer.super.onIceCandidateError(event); -// } -// -// @Override -// public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) { -// -// } -// -// @Override -// public void onSelectedCandidatePairChanged(CandidatePairChangeEvent event) { -// PeerConnection.Observer.super.onSelectedCandidatePairChanged(event); -// } -// -// @Override -// public void onAddStream(MediaStream mediaStream) { -// -// } -// -// @Override -// public void onRemoveStream(MediaStream mediaStream) { -// -// } -// -// @Override -// public void onDataChannel(DataChannel dataChannel) { -// -// } -// -// @Override -// public void onRenegotiationNeeded() { -// -// } -// -// @Override -// public void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams) { -// -// FrameCryptorFactory.createFrameCryptorForRtpReceiver(peerConnectionFactory,receiver, FrameCryptorAlgorithm.AES_GCM, store); -// PeerConnection.Observer.super.onAddTrack(receiver, mediaStreams); -// } -// -// @Override -// public void onRemoveTrack(RtpReceiver receiver) { -// PeerConnection.Observer.super.onRemoveTrack(receiver); -// } -// -// @Override -// public void onTrack(RtpTransceiver transceiver) { -// PeerConnection.Observer.super.onTrack(transceiver); -// } -//} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PublishedStreamData.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PublishedStreamData.java deleted file mode 100644 index ec303f13..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/PublishedStreamData.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class PublishedStreamData { - public String streamRoomId; - public StreamInfo stream; - public String userId; - - public PublishedStreamData(String streamRoomId, StreamInfo stream, String userId) { - this.streamRoomId = streamRoomId; - this.stream = stream; - this.userId = userId; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/SdpWithTypeModel.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/SdpWithTypeModel.java deleted file mode 100644 index 7a9c9022..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/SdpWithTypeModel.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2025 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -public class SdpWithTypeModel { - public String sdp; - public String type; - - public SdpWithTypeModel( - String sdp, - String type - ) { - this.sdp = sdp; - this.type = type; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Settings.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Settings.java deleted file mode 100644 index 9eea6021..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Settings.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class Settings { - public Settings() { - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Stream.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Stream.java deleted file mode 100644 index 2d8c2daa..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/Stream.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -public class Stream { - public Long streamId; - public String userId; - - public Stream( - Long streamId, - String userId - ) { - this.streamId = streamId; - this.userId = userId; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamHandle.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamHandle.java deleted file mode 100644 index 8eb27eb9..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamHandle.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class StreamHandle { - private final Long value; - - public StreamHandle(Long value) { - this.value = value; - } - - public Long getValue() { - return value; - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamInfo.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamInfo.java deleted file mode 100644 index a8ffc2bf..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamInfo.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -import com.simplito.java.privmx_endpoint.model.StreamTrackInfo; - -import java.util.List; - -public class StreamInfo { - public Long id; - public String userId; - public List tracks; - public Long streamId; - public String metadata; // optional - public Boolean dummy; // optional - public Boolean talking; // optional - - - public StreamInfo(Long id, String userId, List tracks, Long streamId) { - this(id, userId, tracks, streamId, null, null, null); - } - - public StreamInfo(Long id, String userId, List tracks, Long streamId, String metadata) { - this(id, userId, tracks, streamId, metadata, null, null); - } - - public StreamInfo(Long id, String userId, List tracks, Long streamId, String metadata, Boolean dummy) { - this(id, userId, tracks, streamId, metadata, dummy, null); - } - - public StreamInfo(Long id, String userId, List tracks, Long streamId, String metadata, Boolean dummy, Boolean talking) { - this.id = id; - this.userId = userId; - this.tracks = tracks; - this.streamId = streamId; - this.metadata = metadata; - this.dummy = dummy; - this.talking = talking; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java deleted file mode 100644 index e322f97e..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamPublishResult.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class StreamPublishResult { - public Boolean published; - public PublishedStreamData data; - - public StreamPublishResult(Boolean published) { - this(published, null); - } - - public StreamPublishResult( - Boolean published, - PublishedStreamData data - ) { - this.published = published; - this.data = data; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamRoom.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamRoom.java deleted file mode 100644 index c00fcfbd..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamRoom.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -import com.simplito.java.privmx_endpoint.model.ContainerPolicy; - -import java.util.List; - -public class StreamRoom { - public String contextId; - public String streamRoomId; - public Long createDate; - public String creator; - public Long lastModificationDate; - public String lastModifier; - public List users; - public List managers; - public Long version; - public byte[] publicMeta; - public byte[] privateMeta; - public ContainerPolicy policy; - public Long statusCode; - - public StreamRoom( - String contextId, - String streamRoomId, - Long createDate, - String creator, - Long lastModificationDate, - String lastModifier, - List users, - List managers, - Long version, - byte[] publicMeta, - byte[] privateMeta, - ContainerPolicy policy, - Long statusCode - ) { - this.contextId = contextId; - this.streamRoomId = streamRoomId; - this.createDate = createDate; - this.creator = creator; - this.lastModificationDate = lastModificationDate; - this.lastModifier = lastModifier; - this.users = users; - this.managers = managers; - this.version = version; - this.publicMeta = publicMeta; - this.privateMeta = privateMeta; - this.policy = policy; - this.statusCode = statusCode; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSettings.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSettings.java deleted file mode 100644 index a64e6086..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSettings.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import java.util.function.Consumer; - -public class StreamSettings { - public Settings settings; - public boolean dropCorruptedFrames = true; - public OnFrameCallback OnFrame = null; - public Consumer OnVideo = null; // _onVideoTrack.value()(_streamRoomId + "-" + receiver->track()->id().std_string()); - - public Consumer OnVideoRemove = null; - - public StreamSettings(Settings settings, boolean dropCorruptedFrames, OnFrameCallback onFrame, Consumer onVideo, Consumer onVideoRemove) { - this.settings = settings; - this.dropCorruptedFrames = dropCorruptedFrames; - OnFrame = onFrame; - OnVideo = onVideo; - OnVideoRemove = onVideoRemove; - } - - public StreamSettings(Settings settings, boolean dropCorruptedFrames, OnFrameCallback onFrame, Consumer onVideo) { - this(settings, dropCorruptedFrames, onFrame, onVideo, null); - } - - public StreamSettings(Settings settings, OnFrameCallback onFrame, boolean dropCorruptedFrames) { - this(settings, dropCorruptedFrames, onFrame, null, null); - - } - - public StreamSettings(Settings settings, boolean dropCorruptedFrames) { - this(settings, dropCorruptedFrames, null, null, null); - - } - - public StreamSettings(Settings settings) { - this(settings, true, null, null, null); - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamStatus.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamStatus.java deleted file mode 100644 index 64d42db6..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamStatus.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public enum StreamStatus { - Offline, - Online -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSubscription.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSubscription.java deleted file mode 100644 index 356ce6e3..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamSubscription.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class StreamSubscription { - public long streamId; - public String streamTrackId; - - public StreamSubscription(long streamId, String streamTrackId) { - this.streamId = streamId; - this.streamTrackId = streamTrackId; - } - - public StreamSubscription(long streamId) { - this.streamId = streamId; - } -} \ No newline at end of file diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamTrackInfo.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamTrackInfo.java deleted file mode 100644 index acb3b9cb..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/StreamTrackInfo.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -public class StreamTrackInfo { - public String type; - public Long mindex; - public String mid; - - public Boolean disabled; // optional - public String codec; // optional - public String description; // optional - public Boolean moderated; // optional - public Boolean simulcast; // optional - public Boolean talking; // optional - - public StreamTrackInfo( - String type, - Long mindex, - String mid - ) { - this(type, mindex, mid, null, null, null, null, null, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled - ) { - this(type, mindex, mid, disabled, null, null, null, null, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled, - String codec - ) { - this(type, mindex, mid, disabled, codec, null, null, null, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled, - String codec, - String description - ) { - this(type, mindex, mid, disabled, codec, description, null, null, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled, - String codec, - String description, - Boolean moderated - ) { - this(type, mindex, mid, disabled, codec, description, moderated, null, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled, - String codec, - String description, - Boolean moderated, - Boolean simulcast - ) { - this(type, mindex, mid, disabled, codec, description, moderated, simulcast, null); - } - - public StreamTrackInfo( - String type, - Long mindex, - String mid, - Boolean disabled, - String codec, - String description, - Boolean moderated, - Boolean simulcast, - Boolean talking - ) { - this.type = type; - this.mindex = mindex; - this.mid = mid; - this.disabled = disabled; - this.codec = codec; - this.description = description; - this.moderated = moderated; - this.simulcast = simulcast; - this.talking = talking; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/TurnCredentials.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/TurnCredentials.java deleted file mode 100644 index 37e9be28..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/TurnCredentials.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2025 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.model; - -public class TurnCredentials { - public String url; - public String username; - public String password; - public Long expirationTime; - - public TurnCredentials( - String url, - String username, - String password, - Long expirationTime - ) { - this.url = url; - this.username = username; - this.password = password; - this.expirationTime = expirationTime; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/VideoTrackInfo.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/VideoTrackInfo.java deleted file mode 100644 index 3912e152..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/model/VideoTrackInfo.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.model; - -import org.webrtc.*; -import org.webrtc.RtpSender; -import org.webrtc.VideoTrack; - -public class VideoTrackInfo { - public VideoTrack track; - public RtpSender sender; - public PmxFrameCryptor frameCryptor; - - public VideoTrackInfo( - VideoTrack track, - RtpSender sender, - PmxFrameCryptor frameCryptor - ) { - this.track = track; - this.sender = sender; - this.frameCryptor = frameCryptor; - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/PmxPeerConnectionClient2.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/PmxPeerConnectionClient2.java deleted file mode 100644 index e8b153a5..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/PmxPeerConnectionClient2.java +++ /dev/null @@ -1,472 +0,0 @@ -/* -package com.simplito.java.privmx_endpoint_streams.modules; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.Nullable; - -import com.simplito.java.privmx_endpoint.model.exceptions.PrivmxException; -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 org.appspot.apprtc.RecordedAudioToFileController; -import org.webrtc.AudioSource; -import org.webrtc.AudioTrack; -import org.webrtc.CameraVideoCapturer; -import org.webrtc.DefaultVideoDecoderFactory; -import org.webrtc.DefaultVideoEncoderFactory; -import org.webrtc.EglBase; -import org.webrtc.IceCandidate; -import org.webrtc.MediaConstraints; -import org.webrtc.MediaStreamTrack; -import org.webrtc.PeerConnectionFactory; -import org.webrtc.RtpSender; -import org.webrtc.SessionDescription; -import org.webrtc.SoftwareVideoDecoderFactory; -import org.webrtc.SoftwareVideoEncoderFactory; -import org.webrtc.SurfaceTextureHelper; -import org.webrtc.VideoCapturer; -import org.webrtc.VideoDecoderFactory; -import org.webrtc.VideoEncoderFactory; -import org.webrtc.VideoSink; -import org.webrtc.VideoSource; -import org.webrtc.VideoTrack; -import org.webrtc.audio.AudioDeviceModule; -import org.webrtc.audio.JavaAudioDeviceModule; -import org.webrtc.audio.JavaAudioDeviceModule.AudioRecordErrorCallback; -import org.webrtc.audio.JavaAudioDeviceModule.AudioRecordStateCallback; -import org.webrtc.audio.JavaAudioDeviceModule.AudioTrackErrorCallback; -import org.webrtc.audio.JavaAudioDeviceModule.AudioTrackStateCallback; - -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -* - * Peer connection client implementation. - * - *

All public methods are routed to local looper thread. - * All PeerConnectionEvents callbacks are invoked from the same looper thread. - * This class is a singleton. - - -public class PmxPeerConnectionClient2 { - public static final String VIDEO_TRACK_ID = "ARDAMSv0"; - public static final String AUDIO_TRACK_ID = "ARDAMSa0"; - public static final String VIDEO_TRACK_TYPE = "video"; - private static final String TAG = "PCRTCClient"; - - // Executor thread is started once in private ctor and is used for all - // peer connection API calls to ensure new peer connection factory is - // created on the same thread as previously destroyed factory. - private static final ExecutorService executor = Executors.newSingleThreadExecutor(); - - private final Timer statsTimer = new Timer(); - private final Timer dropTimer = new Timer(); - - private final EglBase rootEglBase; - private final Context appContext; - - @Nullable - private PeerConnectionFactory factory; - @Nullable - private AudioSource audioSource; - @Nullable private SurfaceTextureHelper surfaceTextureHelper; - @Nullable private VideoSource videoSource; -// private boolean preferIsac; - private boolean videoCapturerStopped; - private boolean isError; - @Nullable - private VideoSink localRender; -// @Nullable private List remoteSinks; - private TrackObserverImpl trackObserver; -// private int remoteSinkId; -// private SignalingParameters signalingParameters; -// private int videoWidth; -// private int videoHeight; -// private int videoFps; - private MediaConstraints audioConstraints; - private MediaConstraints sdpMediaConstraints; - // Queued remote ICE candidates are consumed only after both local and - // remote descriptions are set. Similarly local ICE candidates are sent to - // remote peer after both local and remote description are set. - @Nullable - private List queuedRemoteCandidates; - private boolean isInitiator; - @Nullable private SessionDescription localDescription; // either offer or answer description - @Nullable - private VideoCapturer videoCapturer; - // enableVideo is set to true if video should be rendered and sent. - private boolean renderVideo = true; - @Nullable - private VideoTrack localVideoTrack; -// @Nullable -// private VideoTrack remoteVideoTrack; - @Nullable - private RtpSender localVideoSender; - // enableAudio is set to true if audio should be sent. - private boolean enableAudio = true; - @Nullable - private AudioTrack localAudioTrack; - // Implements the WebRtcAudioRecordSamplesReadyCallback interface and writes - // recorded audio samples to an output file. - @Nullable private RecordedAudioToFileController saveRecordedAudioToFile; - - private final String bridgeUrl; - private final String solutionId; - private final String contextId; - private final String userPrivKey; - private final String adminPrivKey; - private final String streamRoomId; - private Connection connection; - private StreamApiLow streamApi; - private Long localStreamId1; - private Long localStreamId2; - private StreamApi api; - -* - * Create a PeerConnectionClient with the specified parameters. PeerConnectionClient takes - * ownership of `eglBase`. - - - public PmxPeerConnectionClient2(Context appContext, EglBase eglBase, String bridgeUrl, String solutionId, String contextId, String userPrivKey, String adminPrivKey, String streamRoomId) { - this.rootEglBase = eglBase; - this.appContext = appContext; - this.bridgeUrl = bridgeUrl; - this.solutionId = solutionId; - this.contextId = contextId; - this.userPrivKey = userPrivKey; - this.adminPrivKey = adminPrivKey; - this.streamRoomId = streamRoomId; - - executor.execute(() -> { - PeerConnectionFactory.initialize( - PeerConnectionFactory.InitializationOptions.builder(appContext) - .createInitializationOptions()); - }); - - audioConstraints = new MediaConstraints(); - } - -* - * This function should only be called once. - - - public void createPeerConnectionFactory(PeerConnectionFactory.Options options) { - if (factory != null) { - throw new IllegalStateException("PeerConnectionFactory has already been constructed"); - } - executor.execute(() -> createPeerConnectionFactoryInternal(options)); - } - - class TrackObserverImpl implements StreamApi.TrackObserver { - private List remoteSinks; - private int remoteSinkId; - - TrackObserverImpl(List videoSinks) { - this.remoteSinks = videoSinks; - this.remoteSinkId = 0; - } - - @Override - public void onTrack(MediaStreamTrack track) { - if (track.kind().equals(VIDEO_TRACK_TYPE)) { - VideoTrack vt = (VideoTrack) track; - if (remoteSinks.size() > remoteSinkId) { - vt.addSink(remoteSinks.get(remoteSinkId)); - ++remoteSinkId; - } - } - } - } - - - public void createPeerConnection2(final VideoSink renderer, final List remoteSinks, final VideoCapturer videoCapturer) { // WIP - this.localRender = renderer; - this.videoCapturer = videoCapturer; - this.trackObserver = new TrackObserverImpl(remoteSinks); - - connection = Connection.connect( - userPrivKey, - solutionId, - bridgeUrl - ); - var id = connection.getConnectionId(); - EventApi eventApi = new EventApi(connection); - StreamApiLow api2 = StreamApiLow.create(connection, eventApi); - streamApi = api2; - try { // TODO: FIX this - while (factory == null) Thread.sleep(200); - } catch (java.lang.InterruptedException ignore) {} - api = new StreamApi(appContext, rootEglBase, connection, api2, factory); - - try { - var room = api.getStreamRoom(streamRoomId); - } catch (PrivmxException e) { - //Login as admin and add main account to this room (unnecessary) - if (e.getCode() == 4026531888L) { - var connection2 = Connection.connect( - adminPrivKey, - solutionId, - bridgeUrl - ); - EventApi eventApi2 = new EventApi(connection2); - StreamApiLow low2 = StreamApiLow.create(connection2, eventApi2); - var streamApi2 = new StreamApi(appContext, rootEglBase, connection, low2, factory); - var contextUsers = connection2.getContextUsers(contextId); - List users = new ArrayList(); - for (var user : contextUsers) { - users.add(user.user); - } - streamApi2.updateStreamRoom(streamRoomId, users, users, new byte[]{}, new byte[]{}, 0, true, false, null); - connection2.disconnect(); - } - } - - localStreamId1 = api.createStream(streamRoomId); - var videoTrack = createVideoTrack(videoCapturer); - var audioTrack = createAudioTrack(); - api.addTrack(localStreamId1, videoTrack, null); - api.addTrack(localStreamId1, audioTrack, null); - api.publishStream(localStreamId1); - - executor.execute(() -> { - CameraVideoCapturer v = (CameraVideoCapturer)videoCapturer; - v.switchCamera(null); - }); - - dropTimer.schedule(wrap(() -> { - Log.d(TAG,"joinStream="); - var streams = api.listStreams(streamRoomId); - List streamsToJoin = new ArrayList(); - for (var stream : streams) { - streamsToJoin.add(stream.streamId); - } - localStreamId2 = api.joinStreamRoom(streamRoomId, streamsToJoin, trackObserver, null); - Log.d(TAG,"joinStream=END"); - }), (long)1000); - - } - private static TimerTask wrap(Runnable r) { - return new TimerTask() { - - @Override - public void run() { - r.run(); - } - }; - } - - - public void close() { - executor.execute(this ::closeInternal); - } - - private void createPeerConnectionFactoryInternal(PeerConnectionFactory.Options options) { - isError = false; - - final AudioDeviceModule adm = createJavaAudioDevice(); - - // Create peer connection factory. - if (options != null) { - Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMask); - } - final boolean enableH264HighProfile = false; - final VideoEncoderFactory encoderFactory; - final VideoDecoderFactory decoderFactory; - - if (true) { - encoderFactory = new DefaultVideoEncoderFactory( - rootEglBase.getEglBaseContext(), true - enableIntelVp8Encoder -, enableH264HighProfile); - decoderFactory = new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext()); - } else { - encoderFactory = new SoftwareVideoEncoderFactory(); - decoderFactory = new SoftwareVideoDecoderFactory(); - } - - factory = PeerConnectionFactory.builder() - .setOptions(options) - .setAudioDeviceModule(adm) - .setVideoEncoderFactory(encoderFactory) - .setVideoDecoderFactory(decoderFactory) - .createPeerConnectionFactory(); - Log.d(TAG, "Peer connection factory created."); - adm.release(); - } - - AudioDeviceModule createJavaAudioDevice() { - // Enable/disable OpenSL ES playback. -// if (!peerConnectionParameters.useOpenSLES) { -// Log.w(TAG, "External OpenSLES ADM not implemented yet."); -// // TODO(magjed): Add support for external OpenSLES ADM. -// } - - // Set audio record error callbacks. - AudioRecordErrorCallback audioRecordErrorCallback = new AudioRecordErrorCallback() { - @Override - public void onWebRtcAudioRecordInitError(String errorMessage) { - Log.e(TAG, "onWebRtcAudioRecordInitError: " + errorMessage); - reportError(errorMessage); - } - - @Override - public void onWebRtcAudioRecordStartError( - JavaAudioDeviceModule.AudioRecordStartErrorCode errorCode, String errorMessage) { - Log.e(TAG, "onWebRtcAudioRecordStartError: " + errorCode + ". " + errorMessage); - reportError(errorMessage); - } - - @Override - public void onWebRtcAudioRecordError(String errorMessage) { - Log.e(TAG, "onWebRtcAudioRecordError: " + errorMessage); - reportError(errorMessage); - } - }; - - AudioTrackErrorCallback audioTrackErrorCallback = new AudioTrackErrorCallback() { - @Override - public void onWebRtcAudioTrackInitError(String errorMessage) { - Log.e(TAG, "onWebRtcAudioTrackInitError: " + errorMessage); - reportError(errorMessage); - } - - @Override - public void onWebRtcAudioTrackStartError( - JavaAudioDeviceModule.AudioTrackStartErrorCode errorCode, String errorMessage) { - Log.e(TAG, "onWebRtcAudioTrackStartError: " + errorCode + ". " + errorMessage); - reportError(errorMessage); - } - - @Override - public void onWebRtcAudioTrackError(String errorMessage) { - Log.e(TAG, "onWebRtcAudioTrackError: " + errorMessage); - reportError(errorMessage); - } - }; - - // Set audio record state callbacks. - AudioRecordStateCallback audioRecordStateCallback = new AudioRecordStateCallback() { - @Override - public void onWebRtcAudioRecordStart() { - Log.i(TAG, "Audio recording starts"); - } - - @Override - public void onWebRtcAudioRecordStop() { - Log.i(TAG, "Audio recording stops"); - } - }; - - // Set audio track state callbacks. - AudioTrackStateCallback audioTrackStateCallback = new AudioTrackStateCallback() { - @Override - public void onWebRtcAudioTrackStart() { - Log.i(TAG, "Audio playout starts"); - } - - @Override - public void onWebRtcAudioTrackStop() { - Log.i(TAG, "Audio playout stops"); - } - }; - - return JavaAudioDeviceModule.builder(appContext) - .setSamplesReadyCallback(saveRecordedAudioToFile) - .setAudioRecordErrorCallback(audioRecordErrorCallback) - .setAudioTrackErrorCallback(audioTrackErrorCallback) - .setAudioRecordStateCallback(audioRecordStateCallback) - .setAudioTrackStateCallback(audioTrackStateCallback) - .createAudioDeviceModule(); - } - - private void closeInternal() { - Log.d(TAG, "Closing peer connection."); - statsTimer.cancel(); - if (api != null) { - api.unpublishStream(localStreamId1); - api.leaveStreamRoom(localStreamId2); - } - if (connection != null) { - connection.disconnect(); - } - Log.d(TAG, "Closing audio source."); - if (audioSource != null) { - audioSource.dispose(); - audioSource = null; - } - Log.d(TAG, "Stopping capture."); - if (videoCapturer != null) { - try { - videoCapturer.stopCapture(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - videoCapturerStopped = true; - videoCapturer.dispose(); - videoCapturer = null; - } - Log.d(TAG, "Closing video source."); - if (videoSource != null) { - videoSource.dispose(); - videoSource = null; - } - if (surfaceTextureHelper != null) { - surfaceTextureHelper.dispose(); - surfaceTextureHelper = null; - } - if (saveRecordedAudioToFile != null) { - Log.d(TAG, "Closing audio file for recorded input audio."); - saveRecordedAudioToFile.stop(); - saveRecordedAudioToFile = null; - } - localRender = null; - Log.d(TAG, "Closing peer connection factory."); - if (factory != null) { - factory.dispose(); - factory = null; - } - rootEglBase.release(); - Log.d(TAG, "Closing peer connection done."); - PeerConnectionFactory.stopInternalTracingCapture(); - PeerConnectionFactory.shutdownInternalTracer(); - } - - private void reportError(final String errorMessage) { - Log.e(TAG, "Peerconnection error: " + errorMessage); - executor.execute(() -> { - if (!isError) { - isError = true; - } - }); - } - - @Nullable - private AudioTrack createAudioTrack() { - audioSource = factory.createAudioSource(audioConstraints); - localAudioTrack = factory.createAudioTrack(AUDIO_TRACK_ID, audioSource); - localAudioTrack.setEnabled(enableAudio); - return localAudioTrack; - } - - @Nullable - private VideoTrack createVideoTrack(VideoCapturer capturer) { - surfaceTextureHelper = - SurfaceTextureHelper.create("CaptureThread", rootEglBase.getEglBaseContext()); - videoSource = factory.createVideoSource(false); - capturer.initialize(surfaceTextureHelper, appContext, videoSource.getCapturerObserver()); - capturer.startCapture(1920, 1080, 30); - - localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource); - localVideoTrack.setEnabled(renderVideo); - localVideoTrack.addSink(localRender); - return localVideoTrack; - } -} -*/ diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApi.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApi.java deleted file mode 100644 index 8123cb0d..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApi.java +++ /dev/null @@ -1,860 +0,0 @@ -package com.simplito.java.privmx_endpoint_streams.modules; - - -import static android.media.AudioManager.GET_DEVICES_OUTPUTS; - -import android.content.Context; -import android.media.AudioManager; -import android.media.AudioRecordingConfiguration; - -import androidx.annotation.Nullable; - - -import com.simplito.java.privmx_endpoint.model.events.eventSelectorTypes.StreamEventSelectorType; -import com.simplito.java.privmx_endpoint.model.events.eventTypes.StreamEventType; -import com.simplito.java.privmx_endpoint_streams.model.AudioTrackInfo; -import com.simplito.java.privmx_endpoint_streams.model.ConnectionType; -import com.simplito.java.privmx_endpoint_streams.model.DeviceType; -import com.simplito.java.privmx_endpoint_streams.model.JanusConnection; -import com.simplito.java.privmx_endpoint_streams.model.Key; -import com.simplito.java.privmx_endpoint_streams.model.KeyType; -import com.simplito.java.privmx_endpoint_streams.model.MediaDevice; -import com.simplito.java.privmx_endpoint_streams.model.OnFrameCallback; -import com.simplito.java.privmx_endpoint_streams.model.PcObserver; -import com.simplito.java.privmx_endpoint_streams.model.PeerConnection2; -import com.simplito.java.privmx_endpoint_streams.model.PeerConnectionManager; -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; -import com.simplito.java.privmx_endpoint_streams.model.StreamRoom; -import com.simplito.java.privmx_endpoint_streams.model.StreamSettings; -import com.simplito.java.privmx_endpoint_streams.model.StreamStatus; -import com.simplito.java.privmx_endpoint_streams.model.StreamSubscription; -import com.simplito.java.privmx_endpoint_streams.model.VideoTrackInfo; - -import org.webrtc.AudioSource; -import org.webrtc.AudioTrack; -import org.webrtc.Camera1Enumerator; -import org.webrtc.Camera2Enumerator; -import org.webrtc.CameraEnumerator; -import org.webrtc.CameraVideoCapturer; -import org.webrtc.EglBase; -import org.webrtc.FrameCryptorKeyProvider; -import org.webrtc.MediaConstraints; -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 org.webrtc.RtpSender; -import org.webrtc.SessionDescription; -import org.webrtc.VideoCapturer; -import org.webrtc.VideoSource; -import org.webrtc.VideoTrack; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class StreamApi { - public static final String VIDEO_TRACK_ID = "ARDAMSv0"; - public static final String AUDIO_TRACK_ID = "ARDAMSa0"; - public static final String VIDEO_TRACK_TYPE = "video"; - private static final String TAG = "StreamApi"; - - public class TrackParams { - public String params_JSON; - } - - public class StreamJoinSettings { - - } - - public interface TrackObserver { - void onTrack(MediaStreamTrack track); - } - - - private final Context appContext; - private final EglBase rootEglBase; - // private final Connection connection; - private final StreamApiLow api; - - @Nullable - private PeerConnectionFactory peerConnectionFactory; - private FrameCryptorKeyProvider frameCryptorKeyProvider; - - private static final ExecutorService executor = Executors.newSingleThreadExecutor(); - - public StreamApi( - Context appContext, - EglBase rootEglBase, - StreamApiLow api, - @Nullable PeerConnectionFactory peerConnectionFactory - ) { - this.appContext = appContext; - this.rootEglBase = rootEglBase; - this.api = api; - this.peerConnectionFactory = peerConnectionFactory; - } - - private class WebRTCImpl implements WebRTCInterface { - - private PmxKeyStore store = PmxFrameCryptorFactory.createPmxKeyStore(); - private PeerConnection peerConnection; - private TrackObserver trackObserver; - public PcObserver pcObserver; - PeerConnectionManager peerConnectionManager; - - - // -------------------------------------------------------------- - class SdpObserver implements org.webrtc.SdpObserver { - private CompletableFuture res; - - SdpObserver(CompletableFuture res) { - this.res = res; - } - - @Override - public void onCreateSuccess(SessionDescription sessionDescription) { - executor.execute(() -> { - peerConnection.setLocalDescription(this, sessionDescription); - }); - res.complete(sessionDescription.description); - } - - @Override - public void onSetSuccess() { - } - - @Override - public void onCreateFailure(String s) { - } - - @Override - public void onSetFailure(String s) { - } - } - - // -------------------------------------------------------------- - class SdpObserver2 implements org.webrtc.SdpObserver { - private CompletableFuture res; - - SdpObserver2(CompletableFuture res) { - this.res = res; - } - - @Override - public void onCreateSuccess(SessionDescription sessionDescription) { - executor.execute(() -> { - peerConnection.setLocalDescription(new SdpObserver(null), sessionDescription); - }); - res.complete(sessionDescription.description); - } - - @Override - public void onSetSuccess() { - executor.execute(() -> { - peerConnection.createAnswer(this, new MediaConstraints()); - }); - } - - @Override - public void onCreateFailure(String s) { - } - - @Override - public void onSetFailure(String s) { - } - } - - - // -------------------------------------------------------------- - // -------------------------------------------------------------- - - - WebRTCImpl(TrackObserver trackObserver) { - this.trackObserver = trackObserver; - } - - PeerConnection createPeerConnection(String streamRoomId) { - executor.execute(() -> { - // TODO: get ice servers from Bridge using getTurnCredentials() - PeerConnection2 peerConnection; - ArrayList iceServers = new ArrayList<>(); - PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers); - assert peerConnectionFactory != null; - PeerConnection tmpPeerConnection = peerConnectionFactory.createPeerConnection(rtcConfig, pcObserver); - - // todo - store twice ?? - peerConnection = new PeerConnection2( - tmpPeerConnection, - new PcObserver( - peerConnectionFactory, - streamRoomId, - store, - null - ), - store - ); - - peerConnection.pc.createNativePeerConnectionObserver(peerConnection.observer); // todo - nie powinno sie samo robic w konstruktorze? - }); - - - // gdzies przechowywac? - return peerConnection; - } - - // addAudio/Video - - @Override - public String createOfferAndSetLocalDescription(String streamRoomId) { - CompletableFuture res = new CompletableFuture<>(); - executor.execute(() -> { - PeerConnection pc = peerConnectionManager.getConnectionWithSession( - streamRoomId, - ConnectionType.Publisher - ).peerConnection.pc; - - pc.createOffer( - new SdpObserver(res), - new MediaConstraints() - ); - }); - try { - return res.get(); - } catch (ExecutionException | InterruptedException ignored) { - } - return ""; - } - - @Override - public String createAnswerAndSetDescriptions(String streamRoomId, String sdp, String type) { - CompletableFuture res = new CompletableFuture<>(); - executor.execute(() -> { - PeerConnection pc = peerConnectionManager.getConnectionWithSession( - streamRoomId, - ConnectionType.Subscriber - ).peerConnection.pc; - - // todo - idk czy type dobrze - pc.setRemoteDescription( - new SdpObserver2(res), - new SessionDescription( - SessionDescription.Type.fromCanonicalForm(type), - sdp - ) - ); - }); - try { - return res.get(); - } catch (ExecutionException | InterruptedException ignored) { - } - return ""; - } - - @Override - public void setAnswerAndSetRemoteDescription(String streamRoomId, String sdp, String type) { - executor.execute(() -> { - peerConnection.setRemoteDescription( - new SdpObserver(null), - new SessionDescription( - SessionDescription.Type.fromCanonicalForm(type), - sdp - ) - ); - }); - } - - @Override - public void close(String streamRoomId) { - executor.execute(() -> { - if (peerConnection == null) return; - JanusConnection connection = peerConnectionManager.getConnectionWithSession( - streamRoomId, - ConnectionType.Subscriber - ); - connection.peerConnection.audioTracks.clear(); - connection.peerConnection.videoTracks.clear(); - connection.peerConnection.pc.close(); - }); - } - - @Override - public void updateKeys(String streamRoomId, List keys) { - // todo - check with c++ - executor.execute(() -> { - ArrayList list = new ArrayList<>(); - for (Key key : keys) { - list.add(new PmxKeyStore.Key(key.keyId, key.key, key.type == KeyType.LOCAL ? PmxKeyStore.KeyType.LOCAL : PmxKeyStore.KeyType.REMOTE)); - } - store.setKeys(list); - }); - } - - @Override - public void updateSessionId(String streamRoomId, Long sessionId, String connectionType) { - switch (connectionType) { - case "subscriber": - peerConnectionManager.updateSessionForConnection( - streamRoomId, - ConnectionType.Subscriber, - sessionId - ); - break; - - case "publisher": - peerConnectionManager.updateSessionForConnection( - streamRoomId, - ConnectionType.Publisher, - sessionId - ); - break; - } - } - - public void addAudioTrack( - String streamRoomId, - AudioTrack audioTrack, - String id - ) { - if (peerConnectionFactory != null) { - RtpSender rtpSender = peerConnection.addTrack(audioTrack); - PmxFrameCryptor frameCryptor = PmxFrameCryptorFactory.createPmxFrameCryptorFromRtpSender( - peerConnectionFactory, - rtpSender, - store - // options ? - ); - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Publisher) - .peerConnection - .addAudioTrack( - id, - new AudioTrackInfo( - audioTrack, - rtpSender, - frameCryptor - ) - ); - } - } - - public void addVideoTrack( - String streamRoomId, - VideoTrack videoTrack, - String id - ) { - if (peerConnectionFactory != null) { - RtpSender rtpSender = peerConnection.addTrack(videoTrack); - PmxFrameCryptor frameCryptor = PmxFrameCryptorFactory.createPmxFrameCryptorFromRtpSender( - peerConnectionFactory, - rtpSender, - store - // options ? - ); - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Publisher) - .peerConnection - .addVideoTrack( - id, - new VideoTrackInfo( - videoTrack, - rtpSender, - frameCryptor - ) - ); - } - } - - public void removeAudioTrack( - String streamRoomId, - String id - ) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Publisher) - .peerConnection - .removeAudioTrack(id); - } - - public void removeVideoTrack( - String streamRoomId, - String id - ) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Publisher) - .peerConnection - .removeVideoTrack(id); - } - - // TODO !! - public void setFrameCryptorOptions( - String streamRoomId, - PmxFrameCryptor.PmxFrameCryptorOptions options - ) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Subscriber) - .peerConnection - .setFrameCryptorOptions(options); - } - - public void setOnFrame( - String streamRoomId, - OnFrameCallback onFrame - ) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Subscriber) - .peerConnection - .observer - .setOnFrame(onFrame); - } - - public void setOnRemoveVideoTrack(String streamRoomId, Consumer onVideoRemove) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Subscriber) - .peerConnection - .observer - .setOnRemoveVideoTrack(onVideoRemove); - } - - public void setOnVideoTrack( - String streamRoomId, - Consumer onVideoTrack - ) { - peerConnectionManager - .getConnectionWithSession(streamRoomId, ConnectionType.Subscriber) - .peerConnection - .observer - .setOnVideoTrack(onVideoTrack); - } - - } - - // streamHandle - trackObserver - StreamRoomId - private class StreamData { - public long streamHandle; - public String streamRoomId; - StreamStatus status; - Map streamCapturers; // different from c++ - @Nullable - public WebRTCImpl webRTC; - } - - class StreamMap { - private Map map = new HashMap<>(); - private long currentId = 1; - - // StreamData get(long streamId) { - StreamData get(long streamId) { - synchronized (map) { - return map.get(streamId); - } - } - - public long getRandomHandle() { - Random random = new Random(1024L); - long h = random.nextLong(); - while (map.containsKey(h)) { - h = random.nextLong(); - } - return h; - } - - StreamData create( - TrackObserver trackObserver - ) { - synchronized (map) { - long handle = getRandomHandle(); - StreamData streamData = new StreamData(); - streamData.streamHandle = handle; - streamData.webRTC = new WebRTCImpl(trackObserver); -// streamData.webRTC.createPeerConnection(); // create without observer? - streamData.status = StreamStatus.Online; - streamData.streamCapturers = new HashMap<>(); - map.put(handle, streamData); - return streamData; - } - } - - StreamData create( - TrackObserver trackObserver, - String StreamRoomId - ) { - synchronized (map) { - long handle = getRandomHandle(); - StreamData streamData = new StreamData(); - streamData.streamHandle = handle; - streamData.webRTC = new WebRTCImpl(trackObserver); - streamData.webRTC.createPeerConnection(StreamRoomId); - streamData.status = StreamStatus.Online; - streamData.streamRoomId = StreamRoomId; - map.put(handle, streamData); - return streamData; - } - } - - StreamData create( - StreamHandle streamHandle, - TrackObserver trackObserver - ) { - synchronized (map) { -// long streamId = currentId++; - StreamData streamData = new StreamData(); - streamData.streamHandle = streamHandle.getValue(); - streamData.webRTC = new WebRTCImpl(trackObserver); -// streamData.webRTC.createPeerConnection(); // create without observer? - streamData.status = StreamStatus.Online; - streamData.streamCapturers = new HashMap<>(); - map.put(streamHandle.getValue(), streamData); - return streamData; - } - } - - StreamData create( - StreamHandle streamHandle, - TrackObserver trackObserver, - String StreamRoomId - ) { - synchronized (map) { -// long streamId = currentId++; - StreamData streamData = new StreamData(); - streamData.streamHandle = streamHandle.getValue(); - streamData.webRTC = new WebRTCImpl(trackObserver); - streamData.webRTC.createPeerConnection(StreamRoomId); - streamData.status = StreamStatus.Online; - streamData.streamRoomId = StreamRoomId; - map.put(streamHandle.getValue(), streamData); - return streamData; - } - } - } - - - private StreamMap streamMap = new StreamMap(); - -// StreamApi(Context appContext, EglBase rootEglBase, Connection connection, StreamApiLow api, PeerConnectionFactory peerConnectionFactory) { -// this.appContext = appContext; -// this.rootEglBase = rootEglBase; -// this.connection = connection; -// this.api = api; -// this.peerConnectionFactory = peerConnectionFactory; -// } - - - public String createStreamRoom( - String contextId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta, - ContainerPolicy policies // todo - can be null ?? - ) { - return api.createStreamRoom(contextId, users, managers, publicMeta, privateMeta, policies); - } - - public void updateStreamRoom( - String streamRoomId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta, - long version, - boolean force, - boolean forceGenerateNewKey, - ContainerPolicy policies - ) { - api.updateStreamRoom(streamRoomId, users, managers, publicMeta, privateMeta, version, force, forceGenerateNewKey, policies); - } - - public PagingList listStreamRooms( - String contextId, - long skip, - long limit, - String sortOrder, - String lastId, - String sortBy - ) { - return api.listStreamRooms(contextId, skip, limit, sortOrder, lastId, sortBy); - } - - public StreamRoom getStreamRoom(String streamRoomId) { - return api.getStreamRoom(streamRoomId); - } - - public void deleteStreamRoom(String streamRoomId) { - api.deleteStreamRoom(streamRoomId); - } - - public List listStreams(String streamRoomId) { - return api.listStreams(streamRoomId); - } - - public void joinStreamRoom( - String streamRoomId, - TrackObserver trackObserver - ) { - StreamData streamData = streamMap.create(trackObserver); - api.joinStreamRoom(streamRoomId, streamData.webRTC); - } - - // todo - probably wrong - public void leaveStreamRoom(String streamRoomId) { - streamMap.map.forEach((k, v) -> { - if (Objects.equals(v.streamRoomId, streamRoomId)) - streamMap.map.remove(k); - }); - api.leaveStreamRoom(streamRoomId); - } - - // TODO ?? - public StreamHandle createStream(String streamRoomId) { - StreamHandle handle = api.createStream(streamRoomId); - streamMap.create(handle, null, streamRoomId); - - return handle; - } - - // TODO - public List getMediaDevices() { - List result = new ArrayList<>(); - - AudioManager audioManager = (AudioManager) appContext.getSystemService(Context.AUDIO_SERVICE); - CameraEnumerator videoManager; - - android.media.AudioDeviceInfo[] audioDevices = audioManager.getDevices(GET_DEVICES_OUTPUTS); - if (Camera2Enumerator.isSupported(appContext)) { - videoManager = new Camera2Enumerator(appContext); - } else { - videoManager = new Camera1Enumerator(true); - } - String[] videoDevices = videoManager.getDeviceNames(); - - audioManager.getActiveRecordingConfigurations().forEach(AudioRecordingConfiguration::getAudioDevice); - - List audio = Arrays.stream(audioDevices).map(it -> - new MediaDevice( - it.getProductName().toString(), - String.valueOf(it.getId()), - DeviceType.Audio - ) - ).collect(Collectors.toList()); - result.addAll(audio); - - List video = Arrays.stream(videoDevices).map(it -> - new MediaDevice( - it, - it, // todo: what else can it be? - DeviceType.Audio - ) - ).collect(Collectors.toList()); - result.addAll(video); - - return result; - } - - public void addTrack( - StreamHandle streamHandle, - MediaDevice track - ) { - StreamData streamData = streamMap.get(streamHandle.getValue()); - if (peerConnectionFactory != null && streamData.webRTC != null) { - - switch (track.type) { - case Audio: { - AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints()); - AudioTrack audioTrack = peerConnectionFactory.createAudioTrack(track.name, audioSource); - audioTrack.setVolume(10.0); - - streamData.webRTC.addAudioTrack( - streamData.streamRoomId, - audioTrack, - track.id - ); - break; - } - - case Video: { - VideoSource videoSource = peerConnectionFactory.createVideoSource(false, false); // todo - zaimplementowac caly capturer? - VideoTrack videoTrack = peerConnectionFactory.createVideoTrack(track.name, videoSource); - - streamData.webRTC.addVideoTrack( - streamData.streamRoomId, - videoTrack, - track.id - ); - - CameraVideoCapturer capturer; - CameraEnumerator enumerator; - - if (Camera2Enumerator.isSupported(appContext)) { - enumerator = new Camera2Enumerator(appContext); - } else { - enumerator = new Camera1Enumerator(true); - } - - capturer = enumerator.createCapturer(track.name, null); - streamData.streamCapturers.put(String.valueOf(track.id), capturer); - - if (streamData.status == StreamStatus.Online) - capturer.startCapture(1280, 720, 30); // ??? - break; - } - } - } - } - - public void removeTrack( - StreamHandle streamHandle, - MediaStreamTrack track - ) { - StreamData streamData = streamMap.get(streamHandle.getValue()); - - if (streamData == null || streamData.webRTC == null) return; - - if (track instanceof AudioTrack) { - streamData.webRTC.removeAudioTrack(streamData.streamRoomId, track.id()); - } else if (track instanceof VideoTrack) { - streamData.webRTC.removeVideoTrack(streamData.streamRoomId, track.id()); - } - } - - // TODO ???? - probably sth else - more - public StreamPublishResult publishStream(StreamHandle streamHandle) { - return api.publishStream(streamHandle); - } - - // TODO ???? - probably sth else - more - public StreamPublishResult updateStream(StreamHandle streamHandle) { - return api.updateStream(streamHandle); - } - - public void unpublishStream(StreamHandle streamHandle) { - api.unpublishStream(streamHandle); - } - - // TODO ?? - public void subscribeToRemoteStreams( - String streamRoomId, - List subscriptions, - StreamSettings options - ) { - StreamData streamData = streamMap.create( - null, - streamRoomId - ); - - if (options.OnFrame != null) { - assert streamData.webRTC != null; - streamData.webRTC.setOnFrame(streamRoomId, options.OnFrame); - } - - if (options.OnVideoRemove != null) { - assert streamData.webRTC != null; - streamData.webRTC.setOnRemoveVideoTrack(streamRoomId, options.OnVideoRemove); - } - - api.subscribeToRemoteStreams(streamRoomId, subscriptions, options); - } - - public void modifyRemoteStreamsSubscriptions( - String streamRoomId, - List subscriptionsToAdd, - List subscriptionsToRemove, - StreamSettings options - ) { - // todo - nie ma w c++, ale czy nie jest potrzebne ? - streamMap.map.forEach((k, v) -> { - if (Objects.equals(v.streamRoomId, streamRoomId)) { - assert v.webRTC != null; - - if (options.OnFrame != null) { - v.webRTC.setOnFrame(streamRoomId, options.OnFrame); - } - if (options.OnVideoRemove != null) { - v.webRTC.setOnRemoveVideoTrack(streamRoomId, options.OnVideoRemove); - } - } - }); - - - api.modifyRemoteStreamsSubscriptions( - streamRoomId, - subscriptionsToAdd, - subscriptionsToRemove, - options - ); - } - - public void unsubscribeFromRemoteStreams( - String streamRoomId, - List subscriptionsToRemove - ) { - // todo - nie ma w c++, ale czy nie jest potrzebne ? - streamMap.map.forEach((k, v) -> { - if (Objects.equals(v.streamRoomId, streamRoomId)) { - assert v.webRTC != null; - - streamMap.map.remove(k); // ?? - - v.webRTC.setOnFrame(streamRoomId, null); - v.webRTC.setOnRemoveVideoTrack(streamRoomId, null); - } - }); - - - api.unsubscribeFromRemoteStreams( - streamRoomId, - subscriptionsToRemove - ); - } - - public void dropBrokenFrames( - String streamRoomId, - boolean enable - ) { - streamMap.map.forEach((k, v) -> { - if (Objects.equals(v.streamRoomId, streamRoomId)) { - PmxFrameCryptor.PmxFrameCryptorOptions options = new PmxFrameCryptor.PmxFrameCryptorOptions(); - options.dropFrameIfCryptionFailed = enable; - - assert v.webRTC != null; - v.webRTC.setFrameCryptorOptions( - streamRoomId, - options - ); - } - }); - } - - public List subscribeFor(List subscriptionQueries) { - return api.subscribeFor(subscriptionQueries); - } - - public void unsubscribeFrom(List subscriptionIds) { - api.unsubscribeFrom(subscriptionIds); - } - - public String buildSubscriptionQuery( - StreamEventType eventType, - StreamEventSelectorType selectorType, - String selectorId - ) { - return api.buildSubscriptionQuery( - eventType, - selectorType, - selectorId - ); - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApiLow.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApiLow.java deleted file mode 100644 index bb323192..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/StreamApiLow.java +++ /dev/null @@ -1,163 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2025 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.modules; - -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.events.eventSelectorTypes.StreamEventSelectorType; -import com.simplito.java.privmx_endpoint.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.StreamHandle; -import com.simplito.java.privmx_endpoint_streams.model.StreamInfo; -import com.simplito.java.privmx_endpoint_streams.model.StreamPublishResult; -import com.simplito.java.privmx_endpoint_streams.model.StreamRoom; -import com.simplito.java.privmx_endpoint_streams.model.StreamSettings; -import com.simplito.java.privmx_endpoint_streams.model.StreamSubscription; -import com.simplito.java.privmx_endpoint_streams.model.TurnCredentials; - - -import java.util.List; - -public class StreamApiLow implements AutoCloseable { - static { - System.loadLibrary("crypto"); - System.loadLibrary("ssl"); - System.loadLibrary("privmx-endpoint-java"); - } - - @SuppressWarnings("FieldCanBeLocal") - private final Long api; - - private StreamApiLow(Long api) { - this.api = api; - } - - public static native StreamApiLow create( - Connection connection, - EventApi eventApi - ); - - public native List getTurnCredentials(); - - public String createStreamRoom( - String contextId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta - ) { - return this.createStreamRoom(contextId, users, managers, publicMeta, privateMeta, null); - } - - public native String createStreamRoom( - String contextId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta, - ContainerPolicy policies - ); - - //TODO: write methods with default values for force and forceGenerateNewKey parameters - public void updateStreamRoom( - String streamRoomId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta, - long version, - boolean force, - boolean forceGenerateNewKey - ) { - this.updateStreamRoom(streamRoomId, users, managers, publicMeta, privateMeta, version, force, forceGenerateNewKey, null); - } - - public native void updateStreamRoom( - String streamRoomId, - List users, - List managers, - byte[] publicMeta, - byte[] privateMeta, - long version, - boolean force, - boolean forceGenerateNewKey, - ContainerPolicy policies - ); - - public native PagingList listStreamRooms( - String contextId, - long skip, - long limit, - String sortOrder, - String lastId, - String sortBy - ); - - public native StreamRoom getStreamRoom(String streamRoomId); - - public native void deleteStreamRoom(String streamRoomId); - - // Stream - public native List listStreams(String streamRoomId); - - public native void joinStreamRoom( - String streamRoomId, - WebRTCInterface webRtc - ); - - public native void leaveStreamRoom(String streamRoomId); - - public native StreamHandle createStream( - String streamRoomId - ); - - public native StreamPublishResult publishStream(StreamHandle streamHandle); - - public native StreamPublishResult updateStream(StreamHandle streamHandle); - - public native void unpublishStream(StreamHandle streamHandle); - - public native void subscribeToRemoteStreams(String streamRoomId, List subscriptions, StreamSettings options); - - public native void modifyRemoteStreamsSubscriptions(String streamRoomId, List subscriptionsToAdd, List subscriptionsToRemove, StreamSettings options); - - public native void unsubscribeFromRemoteStreams(String streamRoomId, List subscriptionsToRemove); - - public native void trickle(long sessionId, String candidateAsJson); - - - public native void acceptOfferOnReconfigure( - long sessionId, - SdpWithTypeModel sdp - ); - - public native List subscribeFor(List subscriptionQueries); - - public native void unsubscribeFrom(List subscriptionIds); - - public native String buildSubscriptionQuery(StreamEventType eventType, StreamEventSelectorType selectorType, String selectorId); - - - public native void keyManagement(String streamRoomId, boolean disable); - -// public native void reconfigureStream(long localStreamId, String optionsJSON); - - private native void deinit() throws IllegalStateException; - - @Override - public void close() throws Exception { - deinit(); - } -} diff --git a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/WebRTCInterface.java b/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/WebRTCInterface.java deleted file mode 100644 index b227287f..00000000 --- a/privmx-endpoint-streams-android/src/main/java/com/simplito/java/privmx_endpoint_streams/modules/WebRTCInterface.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// PrivMX Endpoint Java. -// Copyright © 2024 Simplito sp. z o.o. -// -// This file is part of the PrivMX Platform (https://privmx.dev). -// This software is Licensed under the MIT License. -// -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package com.simplito.java.privmx_endpoint_streams.modules; - - -import java.util.List; - -public interface WebRTCInterface { -// String createOfferAndSetLocalDescription(String streamRoomId); -// -// String createAnswerAndSetDescriptions(String streamRoomId, String sdp, String type); -// -// void setAnswerAndSetRemoteDescription(String streamRoomId, String sdp, String type); -// -// void updateSessionId(String streamRoomId, Long sessionId, String connectionType); -// -// void close(String streamRoomId); -// -// void updateKeys(String streamRoomId, List keys); -} From 432062bc210086b4f678172c18b003f51e3c3f64 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 17:08:51 +0100 Subject: [PATCH 24/26] feat: add draft methods for audio and video to streamApi --- .../modules/stream/StreamApi.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java index c859e703..ec581f9e 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java @@ -6,6 +6,7 @@ import android.content.Context; import android.media.AudioManager; import android.media.AudioRecordingConfiguration; +import android.util.DisplayMetrics; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -51,6 +52,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; //TODO: Good to remove context from StreamApi @@ -273,6 +275,38 @@ private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) { return null; } + + private VideoCapturer createCameraCapturer(CameraEnumerator enumerator, boolean isBackFacing) { + final String[] deviceNames = enumerator.getDeviceNames(); + // First, try to find front facing camera + Logging.d(TAG, "Looking for front facing cameras."); + for (String deviceName : deviceNames) { + if (enumerator.isFrontFacing(deviceName)) { + Logging.d(TAG, "Creating front facing camera capturer."); + VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null); + + if (videoCapturer != null && !isBackFacing) { + return videoCapturer; + } + } + } + + // Front facing camera not found, try something else + Logging.d(TAG, "Looking for other cameras."); + for (String deviceName : deviceNames) { + if (!enumerator.isFrontFacing(deviceName)) { + Logging.d(TAG, "Creating other camera capturer."); + VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null); + + if (videoCapturer != null && isBackFacing) { + return videoCapturer; + } + } + } + + return null; + } + /** * @param context * @param localSink @@ -326,6 +360,67 @@ public void addTrack( } } + public void addTrackAudio( + AudioTrack audioTrack, + StreamHandle streamHandle, + MediaDevice track + ) { + RoomJanusSession session = pcManager.getSession(streamHandle); + JanusPublisher connection = session.getPublisher(); + if (session == null) + throw new IllegalStateException("Stream not exists. Create stream first."); + if (connection == null) + throw new IllegalStateException("This StreamHandle has not created companion publisher."); + + if (track.type == DeviceType.Audio) { + audioTrack.setEnabled(true); + connection.addAudioTrack(audioTrack); + } + } + + public void addTrackVideo( + Context context, + VideoSink localSink, + StreamHandle streamHandle, + MediaDevice track, + Boolean isScreenCast, + VideoCapturer capturer, + boolean isBackFacing + ) { + RoomJanusSession session = pcManager.getSession(streamHandle); + JanusPublisher connection = session.getPublisher(); + SurfaceTextureHelper surfaceTextureHelper; + + VideoCapturer currentCapturer; + if (isScreenCast) { + surfaceTextureHelper = SurfaceTextureHelper.create("ScreenCaptureThread", rootEglBase.getEglBaseContext()); + currentCapturer = capturer; + } else { + surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", rootEglBase.getEglBaseContext()); + currentCapturer = createCameraCapturer(new Camera2Enumerator(context), isBackFacing); + } + + VideoSource videoSource = connection.peerConnectionFactory.createVideoSource(isScreenCast); + currentCapturer.initialize(surfaceTextureHelper, appContext, videoSource.getCapturerObserver()); + + VideoTrack videoTrack = connection.peerConnectionFactory.createVideoTrack(track.name, videoSource); + videoTrack.setEnabled(true); + videoTrack.addSink(localSink); + connection.addVideoTrack( + videoTrack, + currentCapturer + ); + + DisplayMetrics metrics = new DisplayMetrics(); + Objects.requireNonNull(context.getDisplay()).getMetrics(metrics); + + int width = metrics.widthPixels; + int height = metrics.heightPixels; + + currentCapturer.startCapture(width, height, 30); + + } + /** * @param streamHandle * @param track From c275e8b281719f1e5acb59ea2225653eaa4cb2ea Mon Sep 17 00:00:00 2001 From: Dawid Jenczewski Date: Mon, 9 Feb 2026 17:10:28 +0100 Subject: [PATCH 25/26] chore: update build configs --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 67aec5d6..5e6dab21 100644 --- a/settings.gradle +++ b/settings.gradle @@ -42,7 +42,7 @@ include ':examples:privmx-snippets' include ":jni-wrappers" // streams -include ':privmx-endpoint-streams-android' +include ':privmx-endpoint-streams:android' include ':privmx-endpoint-streams:jvm' project(':privmx-endpoint-jni').projectDir = file("privmx-endpoint/src/main/cpp") \ No newline at end of file From f057c8df5844e70c5e15e35e4af997948b749785 Mon Sep 17 00:00:00 2001 From: Doominika Date: Mon, 9 Feb 2026 17:24:30 +0100 Subject: [PATCH 26/26] feat: add draft removeTrack method --- .../modules/stream/StreamApi.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java index ec581f9e..1557c700 100644 --- a/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java +++ b/privmx-endpoint-streams/android/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java @@ -443,6 +443,24 @@ public void removeTrack( } } + public void removeTrack( + StreamHandle streamHandle, + MediaDevice track + ) throws IllegalStateException { + RoomJanusSession session = pcManager.getSession(streamHandle); + if (session == null) + throw new IllegalStateException("Stream with this StreamHandle doesn't exist."); + JanusPublisher publisher = session.getPublisher(); + + if (publisher == null) + throw new IllegalStateException("This StreamHandle has not created companion publisher."); + if (track.type == DeviceType.Audio) { + publisher.removeAudioTrack(track.name); + } else if (track.type == DeviceType.Video) { + publisher.removeVideoTrack(track.name); + } + } + public StreamPublishResult publishStream(StreamHandle streamHandle) { return api.publishStream(streamHandle); }