diff --git a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp index ca5814bc..dfdf24c4 100644 --- a/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp +++ b/jni-wrappers/privmx-endpoint/src/cpp/modules/StreamApiLow.cpp @@ -26,77 +26,33 @@ StreamApiLow *getStreamApi(JniContextUtils &ctx, jobject streamApiInstance) { return (stream::StreamApiLow *) ctx.getObject(apiLong).getLongValue(); } -//extern "C" -//JNIEXPORT jobject JNICALL -//Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_init( -// JNIEnv *env, -// jobject thiz, -// jobject connection, -// jobject eventApi -//) { -// JniContextUtils ctx(env); -// jobject result; -// -// if (ctx.nullCheck(connection, "Connection") || -// ctx.nullCheck(eventApi, "EventApi")) { -// return nullptr; -// } -// -//// ctx.callResultEndpointApi(&result, [&ctx, &env, &thiz, &connection, &eventApi] { -// auto connection_c = getConnection(env, connection); -// auto eventApi_c = getEventApi(ctx, eventApi); -// auto streamApiLow = stream::StreamApiLow::create( -// *connection_c, -// *eventApi_c -// ); -// auto streamApiLow_ptr = new stream::StreamApiLow(); -// *streamApiLow_ptr = streamApiLow; -// return ctx.long2jLong((jlong) streamApiLow_ptr); -//// }); -// if (ctx->ExceptionCheck()) { -// return nullptr; -// } -// return result; -//} - extern "C" JNIEXPORT jobject JNICALL -Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_create( +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApiLow_init( JNIEnv *env, - jclass clazz, + jobject thiz, jobject connection, jobject eventApi ) { JniContextUtils ctx(env); - if (ctx.nullCheck(connection, "Connection")) { - return nullptr; - } - -// jobject result; -// ctx.callResultEndpointApi(&result, [&ctx, &env, &clazz, &connection, &eventApi] { - jmethodID initMID = ctx->GetMethodID(clazz, "", - "(Ljava/lang/Long;)V"); - auto connection_c = getConnection(env, connection); - auto eventApi_c = getEventApi(env, eventApi); - auto streamApiLow = StreamApiLow::create( - *connection_c, - *eventApi_c - ); - auto *api = new StreamApiLow(); - *api = streamApiLow; - - jobject result = ctx->NewObject( - clazz, - initMID, - ctx.long2jLong((jlong) api) - ); - return result; + jobject result; -// }); - if (ctx->ExceptionCheck()) { + if (ctx.nullCheck(connection, "Connection") || + ctx.nullCheck(eventApi, "EventApi")) { return nullptr; } - return result; + + ctx.callResultEndpointApi(&result, [&ctx, &env, &connection, &eventApi] { + auto connection_c = getConnection(env, connection); + auto eventApi_c = getEventApi(env, eventApi); + auto streamApiLow = stream::StreamApiLow::create( + *connection_c, + *eventApi_c + ); + auto streamApiLow_ptr = new stream::StreamApiLow(); + *streamApiLow_ptr = streamApiLow; + return ctx.long2jLong((jlong) streamApiLow_ptr); + }); } extern "C" diff --git a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventDispatcher.java b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventDispatcher.java index dcff3c2c..57042f74 100644 --- a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventDispatcher.java +++ b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventDispatcher.java @@ -248,9 +248,13 @@ public enum SubscriptionModule { */ KVDB, /** - * CoreModules + * Core module case. */ - CORE + CORE, + /** + * Stream module case. + */ + STREAM } private static class Pair { diff --git a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventType.java b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventType.java index 038b262a..2c257b2b 100644 --- a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventType.java +++ b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/events/EventType.java @@ -47,6 +47,16 @@ import com.simplito.java.privmx_endpoint.model.events.eventTypes.KvdbEventType; import com.simplito.java.privmx_endpoint.model.events.eventTypes.StoreEventType; import com.simplito.java.privmx_endpoint.model.events.eventTypes.ThreadEventType; +import com.simplito.java.privmx_endpoint.streams.model.StreamRoom; +import com.simplito.java.privmx_endpoint.streams.model.events.NewStreams; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamEventData; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamPublishedEventData; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamRoomDeletedEventData; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamUnpublishedEventData; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamUpdatedEventData; +import com.simplito.java.privmx_endpoint.streams.model.events.StreamsUpdatedData; +import com.simplito.java.privmx_endpoint.streams.model.events.eventSelectorTypes.StreamEventSelectorType; +import com.simplito.java.privmx_endpoint.streams.model.events.eventTypes.StreamEventType; import java.util.Objects; @@ -715,4 +725,103 @@ public static EventType ContextUsersStatusCh ); } + public static EventType StreamRoomCreatedEvent(String contextId) { + return new EventType<>( + "streamRoomCreated", + StreamEventType.STREAMROOM_CREATE, + StreamEventSelectorType.CONTEXT_ID, + contextId, + StreamRoom.class + ); + } + + public static EventType StreamRoomUpdatedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamRoomUpdated", + StreamEventType.STREAMROOM_UPDATE, + selectorType, + selectorId, + StreamRoom.class + ); + } + + public static EventType StreamRoomDeletedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamRoomDeleted", + StreamEventType.STREAMROOM_DELETE, + StreamEventSelectorType.CONTEXT_ID, + selectorId, + StreamRoomDeletedEventData.class + ); + } + + public static EventType StreamPublishedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamPublished", + StreamEventType.STREAM_PUBLISH, + selectorType, + selectorId, + StreamPublishedEventData.class + ); + } + + public static EventType StreamUpdatedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamUpdated", + StreamEventType.STREAMROOM_UPDATE, + selectorType, + selectorId, + StreamUpdatedEventData.class + ); + } + + public static EventType StreamJoinedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamJoined", + StreamEventType.STREAM_JOIN, + selectorType, + selectorId, + StreamEventData.class + ); + } + + public static EventType StreamUnpublishedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamUnpublished", + StreamEventType.STREAM_UNPUBLISH, + selectorType, + selectorId, + StreamUnpublishedEventData.class + ); + } + + public static EventType StreamLeftEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamLeft", + StreamEventType.STREAM_LEAVE, + selectorType, + selectorId, + StreamEventData.class + ); + } + + public static EventType StreamNewStreamsEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "StreamNewStreams", + StreamEventType.STREAMROOM_UPDATE, + selectorType, + selectorId, + NewStreams.class + ); + } + + public static EventType StreamsUpdatedEvent(StreamEventSelectorType selectorType, String selectorId) { + return new EventType<>( + "streamsUpdated", + StreamEventType.STREAMROOM_UPDATE, + selectorType, + selectorId, + StreamsUpdatedData.class + ); + } } \ No newline at end of file diff --git a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/BasicPrivmxEndpoint.java b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/BasicPrivmxEndpoint.java index e7970f0e..8589e082 100644 --- a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/BasicPrivmxEndpoint.java +++ b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/BasicPrivmxEndpoint.java @@ -20,6 +20,7 @@ import com.simplito.java.privmx_endpoint.modules.inbox.InboxApi; import com.simplito.java.privmx_endpoint.modules.kvdb.KvdbApi; import com.simplito.java.privmx_endpoint.modules.store.StoreApi; +import com.simplito.java.privmx_endpoint.modules.stream.StreamApiLow; import com.simplito.java.privmx_endpoint.modules.thread.ThreadApi; import com.simplito.java.privmx_endpoint_extra.model.Modules; @@ -62,6 +63,10 @@ public class BasicPrivmxEndpoint implements AutoCloseable { */ public final Connection connection; + /** + * Reference to STREAM module. + */ + protected StreamApiLow streamApiLow; /** * Initializes modules and connects to PrivMX Bridge server using given parameters. @@ -120,6 +125,17 @@ public BasicPrivmxEndpoint( this(enableModule, userPrivateKey, solutionId, bridgeUrl, null); } + public StreamApiLow initializeStreamApiLow() throws IllegalStateException, PrivmxException { + if (streamApiLow == null) { + if (eventApi == null) throw new IllegalStateException("eventApi is not initialized."); + + streamApiLow = new StreamApiLow(connection, eventApi); + return streamApiLow; + } + + return streamApiLow; + } + /** * Disconnects from PrivMX Bridge and frees memory. * @@ -133,5 +149,6 @@ public void close() throws Exception { if (eventApi != null) eventApi.close(); if (kvdbApi != null) kvdbApi.close(); if (connection != null) connection.close(); + if (streamApiLow != null) streamApiLow.close(); } } diff --git a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/PrivmxEndpoint.java b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/PrivmxEndpoint.java index 3c1504c9..19c5aae7 100644 --- a/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/PrivmxEndpoint.java +++ b/privmx-endpoint-extra/src/main/java/com/simplito/java/privmx_endpoint_extra/lib/PrivmxEndpoint.java @@ -26,6 +26,8 @@ import com.simplito.java.privmx_endpoint.model.events.eventTypes.ThreadEventType; import com.simplito.java.privmx_endpoint.model.exceptions.NativeException; import com.simplito.java.privmx_endpoint.model.exceptions.PrivmxException; +import com.simplito.java.privmx_endpoint.model.stream.events.eventSelectorTypes.StreamEventSelectorType; +import com.simplito.java.privmx_endpoint.model.stream.events.eventTypes.StreamEventType; import com.simplito.java.privmx_endpoint.modules.crypto.CryptoApi; import com.simplito.java.privmx_endpoint_extra.events.CallbackRegistration; import com.simplito.java.privmx_endpoint_extra.events.EventCallback; @@ -212,6 +214,17 @@ public List registerManyCallbacks( (CoreEventSelectorType) eventType.eventSelectorType, eventType.eventSelectorId ); + } else if (eventType.libEventType instanceof StreamEventType) { + if (streamApiLow != null) { + module = EventDispatcher.SubscriptionModule.STREAM; + query = streamApiLow.buildSubscriptionQuery( + (StreamEventType) eventType.libEventType, + (StreamEventSelectorType) eventType.eventSelectorType, + eventType.eventSelectorId + ); + } else { + throw new IllegalStateException("streamApiLow is not initialized. Try to initialize it first by calling the initializeStreamApiLow method."); + } } EventsToSubscribe eventsToSubscribe = eventsToSubscribeByModule.getOrDefault( module, @@ -256,6 +269,11 @@ private void unsubscribeMany(EventDispatcher.SubscriptionModule module, List callbacks = value.queriesMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventSelectorTypes/StreamEventSelectorType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventSelectorTypes/StreamEventSelectorType.java deleted file mode 100644 index 8d487955..00000000 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/events/eventSelectorTypes/StreamEventSelectorType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.simplito.java.privmx_endpoint.model.events.eventSelectorTypes; - -public enum StreamEventSelectorType implements EventSelectorType{ - CONTEXT_ID, - STREAMROOM_ID, - STREAM_ID -} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Key.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Key.java new file mode 100644 index 00000000..f016494e --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Key.java @@ -0,0 +1,28 @@ +// +// 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.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/KeyType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/KeyType.java new file mode 100644 index 00000000..515e0537 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/KeyType.java @@ -0,0 +1,17 @@ +// +// 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.model.stream; + +public enum KeyType { + LOCAL, + REMOTE +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/PublishedStreamData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/PublishedStreamData.java new file mode 100644 index 00000000..4df54f01 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/PublishedStreamData.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/SdpWithTypeModel.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/SdpWithTypeModel.java new file mode 100644 index 00000000..6d4132b1 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/SdpWithTypeModel.java @@ -0,0 +1,25 @@ +// +// 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.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Settings.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Settings.java new file mode 100644 index 00000000..225fdd24 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/Settings.java @@ -0,0 +1,6 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +public class Settings { + public Settings() { + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamHandle.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamHandle.java new file mode 100644 index 00000000..8a4e7b51 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamHandle.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamInfo.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamInfo.java new file mode 100644 index 00000000..61afba04 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamInfo.java @@ -0,0 +1,45 @@ +// +// 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.model.stream; + +import java.util.List; + +public class StreamInfo { + public Long id; + public String userId; + public List tracks; + public String metadata; // optional + public Boolean dummy; // optional + public Boolean talking; // optional + + + public StreamInfo(Long id, String userId, List tracks) { + this(id, userId, tracks, null, null, null); + } + + public StreamInfo(Long id, String userId, List tracks, String metadata) { + this(id, userId, tracks, metadata, null, null); + } + + public StreamInfo(Long id, String userId, List tracks, String metadata, Boolean dummy) { + this(id, userId, tracks, metadata, dummy, null); + } + + public StreamInfo(Long id, String userId, List tracks, String metadata, Boolean dummy, Boolean talking) { + this.id = id; + this.userId = userId; + this.tracks = tracks; + this.metadata = metadata; + this.dummy = dummy; + this.talking = talking; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamPublishResult.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamPublishResult.java new file mode 100644 index 00000000..cf3022a9 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamPublishResult.java @@ -0,0 +1,14 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java new file mode 100644 index 00000000..36546587 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamRoom.java @@ -0,0 +1,65 @@ +// +// 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.model.stream; + +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 Long schemaVersion; + + 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, + Long schemaVersion + ) { + 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; + this.schemaVersion = schemaVersion; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java new file mode 100644 index 00000000..f9462643 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamSubscription.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackInfo.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackInfo.java new file mode 100644 index 00000000..98ebe871 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackInfo.java @@ -0,0 +1,99 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModification.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModification.java new file mode 100644 index 00000000..2b368dce --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModification.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +import java.util.List; + +public class StreamTrackModification { + public Long streamId; + public List tracks; + + public StreamTrackModification(Long streamId, List tracks) { + this.streamId = streamId; + this.tracks = tracks; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModificationPair.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModificationPair.java new file mode 100644 index 00000000..5ff41eb7 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/StreamTrackModificationPair.java @@ -0,0 +1,19 @@ +package com.simplito.java.privmx_endpoint.model.stream; + +public class StreamTrackModificationPair { + public StreamTrackInfo before; + public StreamTrackInfo after; + + public StreamTrackModificationPair(StreamTrackInfo before, StreamTrackInfo after) { + this.before = before; + this.after = after; + } + + public StreamTrackModificationPair(StreamTrackInfo before) { + this(before, null); + } + + public StreamTrackModificationPair() { + this(null, null); + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/TurnCredentials.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/TurnCredentials.java new file mode 100644 index 00000000..88990e89 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/TurnCredentials.java @@ -0,0 +1,31 @@ +// +// 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.model.stream; + +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/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/NewStreams.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/NewStreams.java new file mode 100644 index 00000000..f05caf94 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/NewStreams.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.stream.events; + + +import com.simplito.java.privmx_endpoint.model.stream.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; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamEventData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamEventData.java new file mode 100644 index 00000000..71114a60 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamEventData.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.stream.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; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamPublishedEventData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamPublishedEventData.java new file mode 100644 index 00000000..0e834766 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamPublishedEventData.java @@ -0,0 +1,27 @@ +package com.simplito.java.privmx_endpoint.model.stream.events; + + +import com.simplito.java.privmx_endpoint.model.stream.StreamInfo; + +// todo: which to choose +// same as StreamPublishedEventData +public class StreamPublishedEventData { + + /** + * StreamRoom ID + */ + public String streamRoomId; + + /** + * Stream ID's + */ + public StreamInfo stream; + + public String userId; + + public StreamPublishedEventData(String streamRoomId, StreamInfo stream, String userId) { + this.streamRoomId = streamRoomId; + this.stream = stream; + this.userId = userId; + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamRoomDeletedEventData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamRoomDeletedEventData.java new file mode 100644 index 00000000..eb81ce94 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamRoomDeletedEventData.java @@ -0,0 +1,9 @@ +package com.simplito.java.privmx_endpoint.model.stream.events; + +public class StreamRoomDeletedEventData { + public String streamRoomId; + + public StreamRoomDeletedEventData(String streamRoomId) { + this.streamRoomId = streamRoomId; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUnpublishedEventData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUnpublishedEventData.java new file mode 100644 index 00000000..f0b8935e --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUnpublishedEventData.java @@ -0,0 +1,11 @@ +package com.simplito.java.privmx_endpoint.model.stream.events; + +public class StreamUnpublishedEventData { + public String streamRoomId; + public Long streamId; + + public StreamUnpublishedEventData(String streamRoomId, Long streamId) { + this.streamRoomId = streamRoomId; + this.streamId = streamId; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUpdatedEventData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUpdatedEventData.java new file mode 100644 index 00000000..274825d9 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamUpdatedEventData.java @@ -0,0 +1,21 @@ +package com.simplito.java.privmx_endpoint.model.stream.events; + + +import com.simplito.java.privmx_endpoint.model.stream.StreamInfo; +import com.simplito.java.privmx_endpoint.model.stream.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 diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamsUpdatedData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamsUpdatedData.java new file mode 100644 index 00000000..66231546 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/StreamsUpdatedData.java @@ -0,0 +1,14 @@ +package com.simplito.java.privmx_endpoint.model.stream.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 diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/UpdatedStreamData.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/UpdatedStreamData.java new file mode 100644 index 00000000..86325aec --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/UpdatedStreamData.java @@ -0,0 +1,41 @@ +package com.simplito.java.privmx_endpoint.model.stream.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 diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventSelectorTypes/StreamEventSelectorType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventSelectorTypes/StreamEventSelectorType.java new file mode 100644 index 00000000..3ab7e769 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventSelectorTypes/StreamEventSelectorType.java @@ -0,0 +1,9 @@ +package com.simplito.java.privmx_endpoint.model.stream.events.eventSelectorTypes; + +import com.simplito.java.privmx_endpoint.model.events.eventSelectorTypes.EventSelectorType; + +public enum StreamEventSelectorType implements EventSelectorType { + CONTEXT_ID, + STREAMROOM_ID, + STREAM_ID +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventTypes/StreamEventType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventTypes/StreamEventType.java new file mode 100644 index 00000000..44d290fd --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/stream/events/eventTypes/StreamEventType.java @@ -0,0 +1,16 @@ +package com.simplito.java.privmx_endpoint.model.stream.events.eventTypes; + +import com.simplito.java.privmx_endpoint.model.events.eventTypes.EventType; + +public enum StreamEventType implements EventType { + STREAMROOM_CREATE, + STREAMROOM_UPDATE, + STREAMROOM_DELETE, + EMPTY, + STREAM_JOIN, + STREAM_LEAVE, + STREAM_PUBLISH, + STREAM_UNPUBLISH +} + + diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java new file mode 100644 index 00000000..808a6d08 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApiLow.java @@ -0,0 +1,233 @@ +// +// 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.modules.stream; + +import com.simplito.java.privmx_endpoint.model.ContainerPolicy; +import com.simplito.java.privmx_endpoint.model.PagingList; +import com.simplito.java.privmx_endpoint.model.UserWithPubKey; +import com.simplito.java.privmx_endpoint.model.stream.SdpWithTypeModel; +import com.simplito.java.privmx_endpoint.model.stream.Settings; +import com.simplito.java.privmx_endpoint.model.stream.StreamHandle; +import com.simplito.java.privmx_endpoint.model.stream.StreamInfo; +import com.simplito.java.privmx_endpoint.model.stream.StreamPublishResult; +import com.simplito.java.privmx_endpoint.model.stream.StreamRoom; +import com.simplito.java.privmx_endpoint.model.stream.StreamSubscription; +import com.simplito.java.privmx_endpoint.model.stream.TurnCredentials; +import com.simplito.java.privmx_endpoint.model.stream.events.eventSelectorTypes.StreamEventSelectorType; +import com.simplito.java.privmx_endpoint.model.stream.events.eventTypes.StreamEventType; +import com.simplito.java.privmx_endpoint.modules.core.Connection; +import com.simplito.java.privmx_endpoint.modules.event.EventApi; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class StreamApiLow implements AutoCloseable { + static { +// System.loadLibrary("crypto"); +// System.loadLibrary("ssl"); +// System.loadLibrary("privmx-endpoint-java"); +// System.loadLibrary("privmx-endpoint-streams-android"); + } + + @SuppressWarnings("FieldCanBeLocal") + private final Long api; + + private StreamApiLow(Long api) { + this.api = api; + } + + private native Long init(Connection connection, EventApi eventApi) throws IllegalStateException; + + public StreamApiLow( + Connection connection + ) throws IllegalStateException { + this.api = init(connection, null); + } + + public StreamApiLow( + Connection connection, + EventApi eventApi + ) throws IllegalStateException { + Objects.requireNonNull(connection); + EventApi tmpEventApi = eventApi == null ? new EventApi(connection) : null; + this.api = init( + connection, + Optional.ofNullable(eventApi).orElse(tmpEventApi) + ); + + try { + if (eventApi != null) tmpEventApi.close(); + } catch (Exception ignore) { + } + } + + 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, + String queryAsJson + ); + + public PagingList listStreamRooms( + String contextId, + long skip, + long limit, + String sortOrder, + String lastId, + String sortBy + ) { + return listStreamRooms(contextId, skip, limit, sortOrder, lastId, sortBy, null); + } + + public PagingList listStreamRooms( + String contextId, + long skip, + long limit, + String sortOrder, + String lastId + ) { + return listStreamRooms(contextId, skip, limit, sortOrder, lastId, null, null); + } + + public PagingList listStreamRooms( + String contextId, + long skip, + long limit, + String sortOrder + ) { + return listStreamRooms(contextId, skip, limit, sortOrder, null, null, null); + } + + public PagingList listStreamRooms( + String contextId, + long skip, + long limit + ) { + return listStreamRooms(contextId, skip, limit, "desc", null, null, null); + } + + 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); + + // todo +// public native StreamPublishResult updateStream(StreamHandle streamHandle); + + public native void unpublishStream(StreamHandle streamHandle); + + public native void subscribeToRemoteStreams(String streamRoomId, List subscriptions, Settings options); + + public native void modifyRemoteStreamsSubscriptions(String streamRoomId, List subscriptionsToAdd, List subscriptionsToRemove, Settings 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); + + private native String buildSubscriptionQuery(long eventType, long selectorType, String selectorId); + + public String buildSubscriptionQuery( + StreamEventType eventType, + StreamEventSelectorType selectorType, + String selectorId + ) { + return buildSubscriptionQuery( + eventType.ordinal(), + selectorType.ordinal(), + selectorId + ); + } + + public native void keyManagement(String streamRoomId, boolean disable); + + private native void deinit() throws IllegalStateException; + + @Override + public void close() throws Exception { + deinit(); + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java new file mode 100644 index 00000000..a7bbb8c7 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/WebRTCInterface.java @@ -0,0 +1,30 @@ +// +// 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.modules.stream; + +import com.simplito.java.privmx_endpoint.model.stream.Key; + +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); +} diff --git a/settings.gradle b/settings.gradle index 5e6dab21..67aec5d6 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