From c288dc9eb522c7c4775daf6436eb4df209ad17d0 Mon Sep 17 00:00:00 2001 From: Sudharshan Date: Fri, 8 Mar 2019 15:04:37 +0800 Subject: [PATCH 1/2] refactored signaling code to move to a api provider file - closes #25 --- lib/src/resources/signaling_api_provider.dart | 34 +++++++++++++ lib/src/services/peer_connection_factory.dart | 49 ++++++------------- lib/src/services/peer_manager.dart | 10 ++-- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/lib/src/resources/signaling_api_provider.dart b/lib/src/resources/signaling_api_provider.dart index e69de29..b9d4c43 100644 --- a/lib/src/resources/signaling_api_provider.dart +++ b/lib/src/resources/signaling_api_provider.dart @@ -0,0 +1,34 @@ +import "dart:async"; +import "package:http/http.dart" as http; +import "dart:convert"; + +import "../../settings.dart"; + +// Required types +enum SignalingResponse { SUCCESSFULL, NO_DEVICE, NO_DATA } + +class SignalingApiProvider { + Future> getUserDevices(String userId) async { + var response = await http.get("$baseUrlSignaling/user/$userId/devices"); + return jsonDecode(response.body); + } + + Future sendData( + String userId, String deviceId, Map data) async { + var response = await http.post( + "$baseUrlSignaling/user/$userId/device/$deviceId", + headers: {"Content-Type": "application/json"}, + body: jsonEncode({"data": data})); + + switch (response.statusCode) { + case 200: + return SignalingResponse.SUCCESSFULL; + case 400: + return SignalingResponse.NO_DATA; + case 404: + return SignalingResponse.NO_DEVICE; + default: + return SignalingResponse.NO_DEVICE; + } + } +} diff --git a/lib/src/services/peer_connection_factory.dart b/lib/src/services/peer_connection_factory.dart index c0fb723..4077174 100644 --- a/lib/src/services/peer_connection_factory.dart +++ b/lib/src/services/peer_connection_factory.dart @@ -2,11 +2,11 @@ import "dart:async"; import "dart:convert"; import "package:eventsource/eventsource.dart"; import "package:flutter_webrtc/webrtc.dart"; -import "package:http/http.dart" as http; + +import "../resources/signaling_api_provider.dart"; import "../../settings.dart"; // Available utility enums -enum SignalingResponse { SUCCESSFULL, NO_DEVICE, NO_DATA } enum SignalType { CANDIDATE, OFFER, ANSWER } // Callback definitions @@ -18,6 +18,7 @@ class PeerConnectionFactory { EventSource _signalingServer; MediaStream _stream; + SignalingApiProvider signalingApiProvider = SignalingApiProvider(); //Callbacks OnMessageCallback onMessageCallback; @@ -61,26 +62,27 @@ class PeerConnectionFactory { }); } - newPeerConnection(String remoteUserId, String remoteDeviceId) async { + Future newPeerConnection( + String remoteUserId, String remoteDeviceId) async { RTCPeerConnection connection = await createPeerConnection(_iceServers, _config); connection.addStream(_stream); // Send candidates to remote - connection.onIceCandidate = - (candidate) => _sendToRemote(remoteUserId, remoteDeviceId, { - "fromUser": this._localUserId, - "fromDevice": this._localDeviceId, - "type": SignalType.CANDIDATE.index, - "sdpMLineIndex": candidate.sdpMlineIndex, - "sdpMid": candidate.sdpMid, - "candidate": candidate.candidate - }); + connection.onIceCandidate = (candidate) => + signalingApiProvider.sendData(remoteUserId, remoteDeviceId, { + "fromUser": this._localUserId, + "fromDevice": this._localDeviceId, + "type": SignalType.CANDIDATE.index, + "sdpMLineIndex": candidate.sdpMlineIndex, + "sdpMid": candidate.sdpMid, + "candidate": candidate.candidate + }); // Create and send the offer RTCSessionDescription session = await connection.createOffer(_constraints); connection.setLocalDescription(session); - await _sendToRemote(remoteUserId, remoteDeviceId, { + await signalingApiProvider.sendData(remoteUserId, remoteDeviceId, { "fromUser": this._localUserId, "fromDevice": this._localDeviceId, "type": SignalType.OFFER.index, @@ -101,7 +103,7 @@ class PeerConnectionFactory { String remoteDeviceId) async { RTCSessionDescription session = await connection.createAnswer(_constraints); connection.setLocalDescription(session); - _sendToRemote(remoteUserId, remoteDeviceId, { + await signalingApiProvider.sendData(remoteUserId, remoteDeviceId, { "fromUser": this._localUserId, "fromDevice": this._localDeviceId, "type": SignalType.ANSWER.index, @@ -109,23 +111,4 @@ class PeerConnectionFactory { "session": session.type, }); } - - Future _sendToRemote(String remoteUserId, - String remoteDeviceId, Map data) async { - var response = await http.post( - "$baseUrlSignaling/user/$remoteUserId/device/$remoteDeviceId", - headers: {"Content-Type": "application/json"}, - body: jsonEncode({"data": data})); - - switch (response.statusCode) { - case 200: - return SignalingResponse.SUCCESSFULL; - case 400: - return SignalingResponse.NO_DATA; - case 404: - return SignalingResponse.NO_DEVICE; - default: - return SignalingResponse.NO_DEVICE; - } - } } diff --git a/lib/src/services/peer_manager.dart b/lib/src/services/peer_manager.dart index d671503..91d5530 100644 --- a/lib/src/services/peer_manager.dart +++ b/lib/src/services/peer_manager.dart @@ -1,8 +1,7 @@ import "package:flutter_webrtc/webrtc.dart"; -import "package:http/http.dart" as http; -import "dart:convert"; import "peer_connection_factory.dart"; -import "../../settings.dart"; + +import "../resources/signaling_api_provider.dart"; class PeerManager { String _selfUserId; @@ -10,6 +9,7 @@ class PeerManager { PeerConnectionFactory _peerConnectionFactory; MediaStream _localStream; + SignalingApiProvider signalingApiProvider = SignalingApiProvider(); List _currentStreams = []; Map _currentConnections = {}; @@ -31,8 +31,8 @@ class PeerManager { } addPeer(String userId) async { - var response = await http.get("$baseUrlSignaling/user/$userId/devices"); - List deviceIds = jsonDecode(response.body); + List deviceIds = await signalingApiProvider.getUserDevices(userId); + deviceIds.forEach((deviceId) async { RTCPeerConnection connection = await _peerConnectionFactory.newPeerConnection(userId, deviceId); From 5bf2781be24449302c2ec5f5f97784920549fdc2 Mon Sep 17 00:00:00 2001 From: Sudharshan Date: Fri, 8 Mar 2019 16:26:38 +0800 Subject: [PATCH 2/2] feat: testing swift and kotlin support --- android/app/build.gradle | 6 + android/app/src/main/AndroidManifest.xml | 4 - .../example/frontendflutter/MainActivity.java | 13 --- .../example/frontendflutter/MainActivity.kt | 13 +++ .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 5454 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2601 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 9130 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 15249 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 22947 -> 1443 bytes android/build.gradle | 7 +- ios/Podfile | 2 + ios/Runner.xcodeproj/project.pbxproj | 108 +++++++++--------- .../xcshareddata/IDEWorkspaceChecks.plist | 8 -- .../xcshareddata/xcschemes/Runner.xcscheme | 4 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 -- ios/Runner/AppDelegate.h | 6 - ios/Runner/AppDelegate.m | 13 --- ios/Runner/AppDelegate.swift | 13 +++ .../Icon-App-1024x1024@1x.png | Bin 137879 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 687 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1922 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 3859 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1143 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 3676 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 7749 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1922 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 6678 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 13333 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 13333 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 18703 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 6007 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 15893 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 17195 -> 3612 bytes ios/Runner/Info.plist | 2 +- ios/Runner/Runner-Bridging-Header.h | 1 + ios/Runner/main.m | 9 -- 36 files changed, 97 insertions(+), 120 deletions(-) delete mode 100644 android/app/src/main/java/com/example/frontendflutter/MainActivity.java create mode 100644 android/app/src/main/kotlin/com/example/frontendflutter/MainActivity.kt delete mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 ios/Runner/AppDelegate.h delete mode 100644 ios/Runner/AppDelegate.m create mode 100644 ios/Runner/AppDelegate.swift create mode 100644 ios/Runner/Runner-Bridging-Header.h delete mode 100644 ios/Runner/main.m diff --git a/android/app/build.gradle b/android/app/build.gradle index 4ff3be6..ee2b42d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -22,11 +22,16 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 27 + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + lintOptions { disable 'InvalidPackage' } @@ -55,6 +60,7 @@ flutter { } dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1ceed2f..066d4be 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,10 +6,6 @@ to allow setting breakpoints, to provide hot reload, etc. --> - - - -