Add initial Android RTSP interfaces with test cases
authorChanhee Lee <ch2102.lee@samsung.com>
Mon, 7 Nov 2022 00:53:57 +0000 (09:53 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Wed, 9 Nov 2022 08:27:18 +0000 (17:27 +0900)
[Problem] There's no RTSP support in Android AITT.
[Solution] Add basic interfaces for Android RTSP.

24 files changed:
android/aitt/src/main/java/com/samsung/android/aitt/Aitt.java
android/aitt/src/main/java/com/samsung/android/aitt/Definitions.java
android/aitt/src/main/java/com/samsung/android/aitt/IpcHandler.java [deleted file]
android/aitt/src/main/java/com/samsung/android/aitt/ModuleFactory.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/TransportFactory.java [deleted file]
android/aitt/src/main/java/com/samsung/android/aitt/TransportHandler.java [deleted file]
android/aitt/src/main/java/com/samsung/android/aitt/WebRTCHandler.java [deleted file]
android/aitt/src/main/java/com/samsung/android/aitt/handler/IpcHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/handler/ModuleHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/handler/RTSPHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/handler/StreamHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/handler/TransportHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/handler/WebRTCHandler.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/stream/AittStream.java [new file with mode: 0644]
android/aitt/src/main/java/com/samsung/android/aitt/stream/RTSPStream.java [new file with mode: 0644]
android/modules/rtsp/.gitignore [new file with mode: 0644]
android/modules/rtsp/build.gradle [new file with mode: 0644]
android/modules/rtsp/consumer-rules.pro [new file with mode: 0644]
android/modules/rtsp/proguard-rules.pro [new file with mode: 0644]
android/modules/rtsp/src/androidTest/java/com/samsung/android/modules/rtsp/RTSPInstrumentedTest.java [new file with mode: 0644]
android/modules/rtsp/src/main/AndroidManifest.xml [new file with mode: 0644]
android/modules/rtsp/src/main/res/values/strings.xml [new file with mode: 0644]
android/settings.gradle
settings.gradle

index 7d56cca400054df91df177aa4658c1f3184d4478..f5d4f608075d09e4918e522bd3fca0608c734ee3 100644 (file)
  */
 package com.samsung.android.aitt;
 
+import static com.samsung.android.aitt.ModuleFactory.createModuleHandler;
+
+import com.samsung.android.aitt.handler.*;
+
 import android.content.Context;
 import android.util.Log;
 import android.util.Pair;
@@ -22,6 +26,7 @@ import android.util.Pair;
 import androidx.annotation.Nullable;
 
 import com.google.flatbuffers.FlexBuffers;
+import com.samsung.android.aitt.stream.AittStream;
 import com.samsung.android.aittnative.JniInterface;
 
 import java.nio.ByteBuffer;
@@ -64,12 +69,14 @@ public class Aitt {
     /**
      * List of protocols supported by AITT framework
      */
+    // TODO: Separate Stream protocols (WebRTC, RTSP).
     public enum Protocol {
         MQTT(0x1),           // Publish message through the MQTT
         TCP(0x1 << 1),            // Publish message to peers using the TCP
         TCP_SECURE(0x1 << 2),     // Publish message to peers using the Secure TCP
         WEBRTC(0x1 << 3),         // Publish message to peers using the WEBRTC
-        IPC(0x1 << 4);            // Publish message to peers using the IPC
+        IPC(0x1 << 4),            // Publish message to peers using the IPC
+        RTSP(0x1 << 5);                 // Publish message to peers using the RTSP
 
         private final int value;
 
@@ -306,9 +313,10 @@ public class Aitt {
      * @param message                Data to be transferred over WebRTC
      */
     private void publishHandler(Protocol protocol, PortTable portTable, String topic, Object transportHandlerObject, String ip, int port, byte[] message) {
+        // TODO: Validate protocol type.
         TransportHandler transportHandler;
         if (transportHandlerObject == null) {
-            transportHandler = TransportFactory.createTransport(protocol);
+            transportHandler = (TransportHandler) createModuleHandler(protocol);
             if (transportHandler != null)
                 transportHandler.setAppContext(appContext);
             portTable.portMap.replace(port, new Pair<>(protocol, transportHandler));
@@ -389,7 +397,7 @@ public class Aitt {
 
         for (Protocol pro : protocols) {
             try {
-                TransportHandler transportHandler = TransportFactory.createTransport(pro);
+                TransportHandler transportHandler = (TransportHandler) createModuleHandler(pro);
 
                 if (transportHandler != null) {
                     synchronized (this) {
@@ -698,4 +706,16 @@ public class Aitt {
         }
     }
 
+    public AittStream createStream(Protocol protocol, String topic, AittStream.StreamRole streamRole) {
+        // TODO: update this function.
+        ModuleHandler moduleHandler = createModuleHandler(protocol);
+        if (moduleHandler != null && protocol == Protocol.RTSP)
+            return ((RTSPHandler) moduleHandler).newStreamModule(protocol, topic, streamRole);
+        return null;
+    }
+
+    public void destroyStream(AittStream aittStream) {
+        // TODO: implement this function.
+    }
+
 }
index bf4be833d52531022876f63684d9ec6dc05f321c..31ec7a0f377b7b49bdc25e2194d45c70b9a0d707 100644 (file)
@@ -15,7 +15,8 @@
  */
 package com.samsung.android.aitt;
 
-class Definitions {
+public class Definitions {
+
     public static final String WILL_LEAVE_NETWORK = "disconnected";
     public static final String AITT_LOCALHOST = "127.0.0.1";
     public static final int AITT_PORT = 1883;
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/IpcHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/IpcHandler.java
deleted file mode 100644 (file)
index 84a2eb5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.samsung.android.aitt;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.google.flatbuffers.FlexBuffersBuilder;
-import com.samsung.android.modules.ipc.Ipc;
-
-import java.nio.ByteBuffer;
-
-class IpcHandler implements TransportHandler {
-
-    private static final String TAG = "IpcHandler";
-    private Context context;
-    private String ip;
-    private Ipc ipc;
-    private byte[] publishData;
-
-    public IpcHandler() {
-        //ToDo : Copy jni interface and use to communicate with JNI
-    }
-
-    @Override
-    public void setAppContext(Context appContext) {
-        context = appContext;
-    }
-
-    @Override
-    public void setSelfIP(String ip) {
-        this.ip = ip;
-    }
-
-    @Override
-    public byte[] getPublishData() {
-        return publishData;
-    }
-
-    @Override
-    public void subscribe(String topic, HandlerDataCallback handlerDataCallback) {
-        publishData = wrapPublishData(topic);
-        try {
-            Ipc.ReceiveFrameCallback cb = handlerDataCallback::pushHandlerData;
-            ipc = new Ipc(context, cb);
-            ipc.initConsumer();
-
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to subscribe to IPC");
-        }
-    }
-
-    /**
-     * Method to wrap topic, device IP address, webRTC server instance port number for publishing
-     *
-     * @param topic      Topic to which the application has subscribed to
-     * @return Byte data wrapped, contains topic, device IP, webRTC server port number
-     */
-    private byte[] wrapPublishData(String topic) {
-        FlexBuffersBuilder fbb = new FlexBuffersBuilder(ByteBuffer.allocate(512));
-        {
-            int smap = fbb.startMap();
-            fbb.putString(Definitions.STATUS, Definitions.JOIN_NETWORK);
-            fbb.putString("host", ip);
-            {
-                int smap1 = fbb.startMap();
-                fbb.putInt("protocol", Aitt.Protocol.IPC.getValue());
-                fbb.putInt("port", Definitions.DEFAULT_IPC_PORT);
-                fbb.endMap(topic, smap1);
-            }
-            fbb.endMap(null, smap);
-        }
-        ByteBuffer buffer = fbb.finish();
-        byte[] data = new byte[buffer.remaining()];
-        buffer.get(data, 0, data.length);
-        return data;
-    }
-
-    @Override
-    public void publish(String topic, String ip, int port, byte[] message) {
-        if (ipc == null)
-        {
-            ipc = new Ipc(context);
-            ipc.initProducer();
-        }
-        ipc.writeToMemory(message);
-    }
-
-    @Override
-    public void unsubscribe() {
-        if (ipc != null)
-            ipc.close();
-    }
-
-    @Override
-    public void disconnect() {
-        //ToDo : Implement disconnect method
-    }
-}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/ModuleFactory.java b/android/aitt/src/main/java/com/samsung/android/aitt/ModuleFactory.java
new file mode 100644 (file)
index 0000000..3b799a5
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt;
+
+import com.samsung.android.aitt.handler.IpcHandler;
+import com.samsung.android.aitt.handler.ModuleHandler;
+import com.samsung.android.aitt.handler.RTSPHandler;
+import com.samsung.android.aitt.handler.WebRTCHandler;
+
+class ModuleFactory {
+
+    public static ModuleHandler createModuleHandler(Aitt.Protocol protocol) {
+        ModuleHandler moduleHandler;
+        switch (protocol) {
+            case WEBRTC:
+                moduleHandler = new WebRTCHandler();
+                break;
+            case IPC:
+                moduleHandler = new IpcHandler();
+                break;
+            case RTSP:
+                moduleHandler = new RTSPHandler();
+                break;
+            default:
+                moduleHandler = null;
+        }
+        return moduleHandler;
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/TransportFactory.java b/android/aitt/src/main/java/com/samsung/android/aitt/TransportFactory.java
deleted file mode 100644 (file)
index fdb09f8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.samsung.android.aitt;
-
-class TransportFactory {
-    public static TransportHandler createTransport(Aitt.Protocol protocol) {
-        TransportHandler transportHandler;
-        switch (protocol) {
-            case WEBRTC:
-                transportHandler = new WebRTCHandler();
-                break;
-            case IPC:
-                transportHandler = new IpcHandler();
-                break;
-            default:
-                transportHandler = null;
-        }
-        return transportHandler;
-    }
-}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/TransportHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/TransportHandler.java
deleted file mode 100644 (file)
index 0e388a5..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.samsung.android.aitt;
-
-import android.content.Context;
-
-/**
- * An interface to create a transportHandler and provide APIs for protocol specific implementation
- */
-interface TransportHandler {
-    /**
-     * Method to implement protocol specific subscribe functionalities
-     *
-     * @param topic               String topic to which subscribe is called
-     * @param handlerDataCallback callback object to send data from transport handler layer to aitt layer
-     */
-    void subscribe(String topic, HandlerDataCallback handlerDataCallback);
-
-    /**
-     * Method to implement protocol specific publish functionalities
-     *
-     * @param topic   String topic to which publish is called
-     * @param ip      IP address of the destination
-     * @param port    port number of the destination
-     * @param message message to be published to specific topic
-     */
-    void publish(String topic, String ip, int port, byte[] message);
-
-    /**
-     * Method to implement protocol specific unsubscribe functionalities
-     */
-    void unsubscribe();
-
-    /**
-     * Method to implement protocol specific disconnect functionalities
-     */
-    void disconnect();
-
-    /**
-     * Method to set application context to transport handler
-     *
-     * @param appContext application context
-     */
-    void setAppContext(Context appContext);
-
-    /**
-     * Method to set IP address of self device to transport handler
-     *
-     * @param ip IP address of the device
-     */
-    void setSelfIP(String ip);
-
-    /**
-     * Method to get data to publish self details
-     *
-     * @return returns details of self device
-     */
-    byte[] getPublishData();
-
-    /**
-     * Interface to implement handler data callback mechanism
-     */
-    interface HandlerDataCallback {
-        void pushHandlerData(byte[] data);
-    }
-}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/WebRTCHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/WebRTCHandler.java
deleted file mode 100644 (file)
index b106a05..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.samsung.android.aitt;
-
-import android.content.Context;
-
-import com.google.flatbuffers.FlexBuffersBuilder;
-import com.samsung.android.modules.webrtc.WebRTC;
-import com.samsung.android.modules.webrtc.WebRTCServer;
-
-import java.nio.ByteBuffer;
-
-class WebRTCHandler implements TransportHandler {
-    private Context appContext;
-    private String ip;
-    private byte[] publishData;
-    private WebRTC webrtc;
-    private WebRTCServer ws;
-    //ToDo - For now using sample app parameters, later fetch frameWidth & frameHeight from app
-    private final Integer frameWidth = 640;
-    private final Integer frameHeight = 480;
-
-    public WebRTCHandler() {
-        //ToDo : Copy jni interface and use to communicate with JNI
-    }
-
-    @Override
-    public void setAppContext(Context appContext) {
-        this.appContext = appContext;
-    }
-
-    @Override
-    public void setSelfIP(String ip) {
-        this.ip = ip;
-    }
-
-    @Override
-    public void subscribe(String topic, HandlerDataCallback handlerDataCallback) {
-        WebRTC.ReceiveDataCallback cb = handlerDataCallback::pushHandlerData;
-        ws = new WebRTCServer(appContext, cb);
-        int serverPort = ws.start();
-        if (serverPort < 0) {
-            throw new IllegalArgumentException("Failed to start webRTC server-socket");
-        }
-
-        publishData = wrapPublishData(topic, serverPort);
-    }
-
-    @Override
-    public byte[] getPublishData() {
-        return publishData;
-    }
-
-    /**
-     * Method to wrap topic, device IP address, webRTC server instance port number for publishing
-     *
-     * @param topic      Topic to which the application has subscribed to
-     * @param serverPort Port number of the WebRTC server instance
-     * @return Byte data wrapped, contains topic, device IP, webRTC server port number
-     */
-    private byte[] wrapPublishData(String topic, int serverPort) {
-        FlexBuffersBuilder fbb = new FlexBuffersBuilder(ByteBuffer.allocate(512));
-        {
-            int smap = fbb.startMap();
-            fbb.putString(Definitions.STATUS, Definitions.JOIN_NETWORK);
-            fbb.putString("host", ip);
-            {
-                int smap1 = fbb.startMap();
-                fbb.putInt("protocol", Aitt.Protocol.WEBRTC.getValue());
-                fbb.putInt("port", serverPort);
-                fbb.endMap(topic, smap1);
-            }
-            fbb.endMap(null, smap);
-        }
-        ByteBuffer buffer = fbb.finish();
-        byte[] data = new byte[buffer.remaining()];
-        buffer.get(data, 0, data.length);
-        return data;
-    }
-
-    @Override
-    public void publish(String topic, String ip, int port, byte[] message) {
-        if (webrtc == null) {
-            webrtc = new WebRTC(appContext);
-            webrtc.connect(ip, port);
-        }
-        if (topic.endsWith(Definitions.RESPONSE_POSTFIX)) {
-            webrtc.sendMessageData(message);
-        } else {
-            webrtc.sendVideoData(message, frameWidth, frameHeight);
-        }
-    }
-
-    @Override
-    public void unsubscribe() {
-        ws.stop();
-    }
-
-    @Override
-    public void disconnect() {
-
-    }
-}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/IpcHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/IpcHandler.java
new file mode 100644 (file)
index 0000000..8ff2445
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+import android.content.Context;
+import android.util.Log;
+import com.google.flatbuffers.FlexBuffersBuilder;
+import com.samsung.android.aitt.Aitt;
+import com.samsung.android.aitt.Definitions;
+import com.samsung.android.modules.ipc.Ipc;
+
+import java.nio.ByteBuffer;
+
+public class IpcHandler implements TransportHandler {
+
+    private static final String TAG = "IpcHandler";
+    private Context context;
+    private String ip;
+    private Ipc ipc;
+    private byte[] publishData;
+
+    public IpcHandler() {
+        //ToDo : Copy jni interface and use to communicate with JNI
+    }
+
+    @Override
+    public void setAppContext(Context appContext) {
+        context = appContext;
+    }
+
+    @Override
+    public void setSelfIP(String ip) {
+        this.ip = ip;
+    }
+
+    @Override
+    public byte[] getPublishData() {
+        return publishData;
+    }
+
+    @Override
+    public void subscribe(String topic, HandlerDataCallback handlerDataCallback) {
+        publishData = wrapPublishData(topic);
+        try {
+            Ipc.ReceiveFrameCallback cb = handlerDataCallback::pushHandlerData;
+            ipc = new Ipc(context, cb);
+            ipc.initConsumer();
+
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to subscribe to IPC");
+        }
+    }
+
+    /**
+     * Method to wrap topic, device IP address, webRTC server instance port number for publishing
+     *
+     * @param topic      Topic to which the application has subscribed to
+     * @return Byte data wrapped, contains topic, device IP, webRTC server port number
+     */
+    private byte[] wrapPublishData(String topic) {
+        FlexBuffersBuilder fbb = new FlexBuffersBuilder(ByteBuffer.allocate(512));
+        {
+            int smap = fbb.startMap();
+            fbb.putString(Definitions.STATUS, Definitions.JOIN_NETWORK);
+            fbb.putString("host", ip);
+            {
+                int smap1 = fbb.startMap();
+                fbb.putInt("protocol", Aitt.Protocol.IPC.getValue());
+                fbb.putInt("port", Definitions.DEFAULT_IPC_PORT);
+                fbb.endMap(topic, smap1);
+            }
+            fbb.endMap(null, smap);
+        }
+        ByteBuffer buffer = fbb.finish();
+        byte[] data = new byte[buffer.remaining()];
+        buffer.get(data, 0, data.length);
+        return data;
+    }
+
+    @Override
+    public void publish(String topic, String ip, int port, byte[] message) {
+        if (ipc == null)
+        {
+            ipc = new Ipc(context);
+            ipc.initProducer();
+        }
+        ipc.writeToMemory(message);
+    }
+
+    @Override
+    public void unsubscribe() {
+        if (ipc != null)
+            ipc.close();
+    }
+
+    @Override
+    public void disconnect() {
+        //ToDo : Implement disconnect method
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/ModuleHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/ModuleHandler.java
new file mode 100644 (file)
index 0000000..15c236a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+import android.content.Context;
+
+public interface ModuleHandler {
+    /**
+     * Method to set application context to transport handler
+     *
+     * @param appContext application context
+     */
+    void setAppContext(Context appContext);
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/RTSPHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/RTSPHandler.java
new file mode 100644 (file)
index 0000000..62f48d8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+import com.samsung.android.aitt.Aitt;
+import com.samsung.android.aitt.stream.AittStream;
+import com.samsung.android.aitt.stream.RTSPStream;
+
+public class RTSPHandler extends StreamHandler {
+
+    @Override
+    public AittStream newStreamModule(Aitt.Protocol protocol, String topic, AittStream.StreamRole role) {
+        // TODO: implement this function.
+        return new RTSPStream();
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/StreamHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/StreamHandler.java
new file mode 100644 (file)
index 0000000..2fa6dc2
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+import android.content.Context;
+
+import com.samsung.android.aitt.Aitt;
+import com.samsung.android.aitt.stream.AittStream;
+
+public class StreamHandler implements ModuleHandler {
+
+    AittStream newStreamModule(Aitt.Protocol protocol, String topic, AittStream.StreamRole role) {
+        // TODO: Change this function properly after refactoring WebRTC modules.
+        return null;
+    }
+
+    @Override
+    public void setAppContext(Context appContext) {
+        // TODO: implement this function.
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/TransportHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/TransportHandler.java
new file mode 100644 (file)
index 0000000..2015c4a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+/**
+ * An interface to create a transportHandler and provide APIs for protocol specific implementation
+ */
+public interface TransportHandler extends ModuleHandler {
+    /**
+     * Method to implement protocol specific subscribe functionalities
+     *
+     * @param topic               String topic to which subscribe is called
+     * @param handlerDataCallback callback object to send data from transport handler layer to aitt layer
+     */
+    void subscribe(String topic, HandlerDataCallback handlerDataCallback);
+
+    /**
+     * Method to implement protocol specific publish functionalities
+     *
+     * @param topic   String topic to which publish is called
+     * @param ip      IP address of the destination
+     * @param port    port number of the destination
+     * @param message message to be published to specific topic
+     */
+    void publish(String topic, String ip, int port, byte[] message);
+
+    /**
+     * Method to implement protocol specific unsubscribe functionalities
+     */
+    void unsubscribe();
+
+    /**
+     * Method to implement protocol specific disconnect functionalities
+     */
+    void disconnect();
+
+    /**
+     * Method to set IP address of self device to transport handler
+     *
+     * @param ip IP address of the device
+     */
+    void setSelfIP(String ip);
+
+    /**
+     * Method to get data to publish self details
+     *
+     * @return returns details of self device
+     */
+    byte[] getPublishData();
+
+    /**
+     * Interface to implement handler data callback mechanism
+     */
+    interface HandlerDataCallback {
+        void pushHandlerData(byte[] data);
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/handler/WebRTCHandler.java b/android/aitt/src/main/java/com/samsung/android/aitt/handler/WebRTCHandler.java
new file mode 100644 (file)
index 0000000..36960bd
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.handler;
+
+import android.content.Context;
+
+import com.google.flatbuffers.FlexBuffersBuilder;
+import com.samsung.android.aitt.Aitt;
+import com.samsung.android.aitt.Definitions;
+import com.samsung.android.modules.webrtc.WebRTC;
+import com.samsung.android.modules.webrtc.WebRTCServer;
+
+import java.nio.ByteBuffer;
+
+public class WebRTCHandler implements TransportHandler {
+
+    private Context appContext;
+    private String ip;
+    private byte[] publishData;
+    private WebRTC webrtc;
+    private WebRTCServer ws;
+    //ToDo - For now using sample app parameters, later fetch frameWidth & frameHeight from app
+    private final Integer frameWidth = 640;
+    private final Integer frameHeight = 480;
+
+    public WebRTCHandler() {
+        //ToDo : Copy jni interface and use to communicate with JNI
+    }
+
+    @Override
+    public void setAppContext(Context appContext) {
+        this.appContext = appContext;
+    }
+
+    @Override
+    public void setSelfIP(String ip) {
+        this.ip = ip;
+    }
+
+    @Override
+    public void subscribe(String topic, HandlerDataCallback handlerDataCallback) {
+        WebRTC.ReceiveDataCallback cb = handlerDataCallback::pushHandlerData;
+        ws = new WebRTCServer(appContext, cb);
+        int serverPort = ws.start();
+        if (serverPort < 0) {
+            throw new IllegalArgumentException("Failed to start webRTC server-socket");
+        }
+
+        publishData = wrapPublishData(topic, serverPort);
+    }
+
+    @Override
+    public byte[] getPublishData() {
+        return publishData;
+    }
+
+    /**
+     * Method to wrap topic, device IP address, webRTC server instance port number for publishing
+     *
+     * @param topic      Topic to which the application has subscribed to
+     * @param serverPort Port number of the WebRTC server instance
+     * @return Byte data wrapped, contains topic, device IP, webRTC server port number
+     */
+    private byte[] wrapPublishData(String topic, int serverPort) {
+        FlexBuffersBuilder fbb = new FlexBuffersBuilder(ByteBuffer.allocate(512));
+        {
+            int smap = fbb.startMap();
+            fbb.putString(Definitions.STATUS, Definitions.JOIN_NETWORK);
+            fbb.putString("host", ip);
+            {
+                int smap1 = fbb.startMap();
+                fbb.putInt("protocol", Aitt.Protocol.WEBRTC.getValue());
+                fbb.putInt("port", serverPort);
+                fbb.endMap(topic, smap1);
+            }
+            fbb.endMap(null, smap);
+        }
+        ByteBuffer buffer = fbb.finish();
+        byte[] data = new byte[buffer.remaining()];
+        buffer.get(data, 0, data.length);
+        return data;
+    }
+
+    @Override
+    public void publish(String topic, String ip, int port, byte[] message) {
+        if (webrtc == null) {
+            webrtc = new WebRTC(appContext);
+            webrtc.connect(ip, port);
+        }
+        if (topic.endsWith(Definitions.RESPONSE_POSTFIX)) {
+            webrtc.sendMessageData(message);
+        } else {
+            webrtc.sendVideoData(message, frameWidth, frameHeight);
+        }
+    }
+
+    @Override
+    public void unsubscribe() {
+        ws.stop();
+    }
+
+    @Override
+    public void disconnect() {
+
+    }
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/stream/AittStream.java b/android/aitt/src/main/java/com/samsung/android/aitt/stream/AittStream.java
new file mode 100644 (file)
index 0000000..9ad96ab
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.stream;
+
+public interface AittStream {
+
+    enum StreamRole {
+        PUBLISHER,
+        SUBSCRIBER
+    }
+
+    void setConfig();
+
+    void start();
+
+    void stop();
+
+    void setStateCallback();
+
+    void setReceiveCallback();
+}
diff --git a/android/aitt/src/main/java/com/samsung/android/aitt/stream/RTSPStream.java b/android/aitt/src/main/java/com/samsung/android/aitt/stream/RTSPStream.java
new file mode 100644 (file)
index 0000000..199913f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.aitt.stream;
+
+public class RTSPStream implements AittStream {
+
+    @Override
+    public void setConfig() {
+        // TODO: implement this function.
+    }
+
+    @Override
+    public void start() {
+        // TODO: implement this function.
+    }
+
+    @Override
+    public void stop() {
+        // TODO: implement this function.
+    }
+
+    public void pause() {
+        // TODO: implement this function.
+    }
+
+    public void record() {
+        // TODO: implement this function.
+    }
+
+    @Override
+    public void setStateCallback() {
+        // TODO: implement this function.
+    }
+
+    @Override
+    public void setReceiveCallback() {
+        // TODO: implement this function.
+    }
+}
diff --git a/android/modules/rtsp/.gitignore b/android/modules/rtsp/.gitignore
new file mode 100644 (file)
index 0000000..796b96d
--- /dev/null
@@ -0,0 +1 @@
+/build
diff --git a/android/modules/rtsp/build.gradle b/android/modules/rtsp/build.gradle
new file mode 100644 (file)
index 0000000..dcaed71
--- /dev/null
@@ -0,0 +1,36 @@
+plugins {
+    id 'com.android.library'
+}
+
+android {
+    compileSdkVersion 31
+
+    defaultConfig {
+        minSdkVersion 28
+        targetSdkVersion 31
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        consumerProguardFiles "consumer-rules.pro"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+}
+
+dependencies {
+    implementation 'androidx.appcompat:appcompat:1.4.1'
+    implementation 'com.google.android.material:material:1.4.0'
+
+    androidTestImplementation 'junit:junit:4.13.2'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+    androidTestImplementation project(path: ':android:aitt')
+}
diff --git a/android/modules/rtsp/consumer-rules.pro b/android/modules/rtsp/consumer-rules.pro
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/android/modules/rtsp/proguard-rules.pro b/android/modules/rtsp/proguard-rules.pro
new file mode 100644 (file)
index 0000000..f1b4245
--- /dev/null
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/android/modules/rtsp/src/androidTest/java/com/samsung/android/modules/rtsp/RTSPInstrumentedTest.java b/android/modules/rtsp/src/androidTest/java/com/samsung/android/modules/rtsp/RTSPInstrumentedTest.java
new file mode 100644 (file)
index 0000000..cd2d6bc
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.samsung.android.modules.rtsp;
+
+import static com.samsung.android.aitt.stream.AittStream.StreamRole.PUBLISHER;
+import static com.samsung.android.aitt.stream.AittStream.StreamRole.SUBSCRIBER;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.samsung.android.aitt.Aitt;
+import com.samsung.android.aitt.stream.AittStream;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class RTSPInstrumentedTest {
+
+    private static final String TEST_TOPIC = "android/test/rtsp";
+    private static final String AITT_ID = "AITT_ANDROID";
+    private static final String ERROR_MESSAGE_AITT_NULL = "An AITT instance is null.";
+    private static final int PORT = 1883;
+
+    private static String brokerIp;
+    private static Context appContext;
+
+    @BeforeClass
+    public static void initialize() {
+        appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        appContext.getString(R.string.testBrokerIp);
+    }
+
+    @Test
+    public void testRTSPBasicStreaming() {
+        try {
+            Aitt aitt = new Aitt(appContext, AITT_ID);
+            assertNotNull(ERROR_MESSAGE_AITT_NULL, aitt);
+            aitt.connect(brokerIp, PORT);
+
+            AittStream subscriber = aitt.createStream(Aitt.Protocol.RTSP, TEST_TOPIC, SUBSCRIBER);
+            subscriber.setReceiveCallback(/* TODO */);
+            subscriber.start();
+
+            AittStream publisher = aitt.createStream(Aitt.Protocol.RTSP, TEST_TOPIC, PUBLISHER);
+            publisher.setConfig(/* TODO */);
+            publisher.start();
+
+            publisher.stop();
+            subscriber.stop();
+
+            aitt.destroyStream(publisher);
+            aitt.destroyStream(subscriber);
+        } catch (Exception e) {
+            fail("Failed testRTSPBasicStreaming, (" + e + ")");
+        }
+    }
+}
diff --git a/android/modules/rtsp/src/main/AndroidManifest.xml b/android/modules/rtsp/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..994629d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.samsung.android.modules.rtsp">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+</manifest>
diff --git a/android/modules/rtsp/src/main/res/values/strings.xml b/android/modules/rtsp/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..98ea3ee
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="testBrokerIp">192.168.1.59</string>
+</resources>
\ No newline at end of file
index 1883453e6e1bbef5db9b91f145c9d684337c4ddc..98ed042139a71567076071f650c57148c21f4f03 100644 (file)
@@ -3,3 +3,4 @@ include ':flatbuffers'
 include ':mosquitto'
 include ':modules:tcp'
 include ':modules:webrtc'
+include ':modules:rtsp'
index c528e385fc9ef337abf05cfa94b9c02b4508ea1a..304a34d026ca773c0d336a2a152898137f87dfef 100644 (file)
@@ -1,7 +1,8 @@
 include ':android:aitt'
+include ':android:aitt-native'
 include ':android:flatbuffers'
 include ':android:mosquitto'
+include ':android:modules:ipc'
+include ':android:modules:rtsp'
 include ':android:modules:tcp'
 include ':android:modules:webrtc'
-include ':android:aitt-native'
-include ':android:modules:ipc'