[tor-commits] [snowflake-mobile/master] Added WebRTC code

cohosh at torproject.org cohosh at torproject.org
Tue Jun 16 14:34:48 UTC 2020


commit 31ad93897d022677ad1195365f166ba5e09370a6
Author: Hashik Donthineni <HashikDonthineni at gmail.com>
Date:   Tue Jun 9 12:50:11 2020 +0530

    Added WebRTC code
---
 .../snowflake/MyPeerConnectionObserver.java        | 97 ++++++++++++++++++++++
 .../torproject/snowflake/MyPersistentService.java  | 95 ++++++++++++++++++++-
 .../interfaces/PeerConnectionObserverCallback.java | 18 ++++
 3 files changed, 208 insertions(+), 2 deletions(-)

diff --git a/app/src/main/java/org/torproject/snowflake/MyPeerConnectionObserver.java b/app/src/main/java/org/torproject/snowflake/MyPeerConnectionObserver.java
new file mode 100644
index 0000000..5d96dae
--- /dev/null
+++ b/app/src/main/java/org/torproject/snowflake/MyPeerConnectionObserver.java
@@ -0,0 +1,97 @@
+package org.torproject.snowflake;
+
+import android.util.Log;
+
+import org.torproject.snowflake.interfaces.PeerConnectionObserverCallback;
+import org.webrtc.DataChannel;
+import org.webrtc.IceCandidate;
+import org.webrtc.MediaStream;
+import org.webrtc.PeerConnection;
+import org.webrtc.RtpReceiver;
+
+public class MyPeerConnectionObserver implements PeerConnection.Observer {
+    private final String TAG;
+    private PeerConnectionObserverCallback peerconnectionObserverCallback;
+
+    public MyPeerConnectionObserver(String tag, PeerConnectionObserverCallback callback) {
+        TAG = tag + ": MyPeerConnectionObserver: ";
+        this.peerconnectionObserverCallback = callback;
+    }
+
+    @Override
+    public void onSignalingChange(PeerConnection.SignalingState signalingState) {
+        Log.d(TAG, "onSignalingChange: " + signalingState);
+    }
+
+    @Override
+    public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
+        Log.d(TAG, "onIceConnectionChange: " + iceConnectionState);
+        //TODO:Handle Connection Failure.
+    }
+
+    @Override
+    public void onIceConnectionReceivingChange(boolean b) {
+        Log.d(TAG, "onIceConnectionReceivingChange: ");
+    }
+
+    @Override
+    public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
+        Log.d(TAG, "onIceGatheringChange: " + iceGatheringState);
+        if (iceGatheringState.compareTo(PeerConnection.IceGatheringState.COMPLETE) == 0)
+            peerconnectionObserverCallback.onIceGatheringFinish();
+    }
+
+    @Override
+    public void onIceCandidate(IceCandidate iceCandidate) {
+        //Fired after each ICE candidate is gathered. AKA ICE trickling.
+        Log.d(TAG, "onIceCandidate: SDP:" + iceCandidate.sdp);
+    }
+
+    @Override
+    public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {
+        Log.d(TAG, "onIceCandidatesRemoved: ");
+    }
+
+    @Override
+    public void onAddStream(MediaStream mediaStream) {
+        Log.d(TAG, "onAddStream: ");
+    }
+
+    @Override
+    public void onRemoveStream(MediaStream mediaStream) {
+        Log.d(TAG, "onRemoveStream: ");
+    }
+
+    @Override
+    public void onDataChannel(DataChannel dataChannel) {
+        Log.d(TAG, "onDataChannel: State: " + dataChannel.state() + " Registering Observer...");
+        dataChannel.registerObserver(new DataChannel.Observer() {
+            @Override
+            public void onBufferedAmountChange(long l) {
+
+            }
+
+            @Override
+            public void onStateChange() {
+                peerconnectionObserverCallback.dataChannelStateChange(dataChannel.state());
+            }
+
+            @Override
+            public void onMessage(DataChannel.Buffer buffer) {
+                Log.d(TAG, "onMessage: Received");
+                peerconnectionObserverCallback.onMessage(buffer);
+            }
+        });
+        peerconnectionObserverCallback.onDataChannel(dataChannel);
+    }
+
+    @Override
+    public void onRenegotiationNeeded() {
+        Log.d(TAG, "onRenegotiationNeeded: ");
+    }
+
+    @Override
+    public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {
+        Log.d(TAG, "onAddTrack: ");
+    }
+}
diff --git a/app/src/main/java/org/torproject/snowflake/MyPersistentService.java b/app/src/main/java/org/torproject/snowflake/MyPersistentService.java
index 564fe03..2a7c52d 100644
--- a/app/src/main/java/org/torproject/snowflake/MyPersistentService.java
+++ b/app/src/main/java/org/torproject/snowflake/MyPersistentService.java
@@ -13,12 +13,25 @@ import android.util.Log;
 import androidx.annotation.Nullable;
 
 import org.torproject.snowflake.constants.ForegroundServiceConstants;
+import org.torproject.snowflake.interfaces.PeerConnectionObserverCallback;
+import org.webrtc.DataChannel;
+import org.webrtc.PeerConnection;
+import org.webrtc.PeerConnectionFactory;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * Main Snowflake implementation of foreground service to relay data in the background.
  */
 public class MyPersistentService extends Service {
     private static final String TAG = "MyPersistentService";
+    //WebRTC vars
+    DataChannel mainDataChannel;
+    PeerConnection mainPeerConnection;
+    PeerConnectionFactory factory;
     private SharedPreferences sharedPreferences;
     private boolean isServiceStarted;
     private PowerManager.WakeLock wakeLock;
@@ -121,7 +134,7 @@ public class MyPersistentService extends Service {
         return builder.build();
     }
 
-    //Starting and stopping service
+    /////////////// Start/Stop Service ////////////////////////
 
     /**
      * Use to star/re-start the service
@@ -140,7 +153,7 @@ public class MyPersistentService extends Service {
         wakeLock.acquire(); //WakeLock acquired for unlimited amount of time.
 
         ///
-        //TODO: Start WebRTC connection.
+        startWebRTCConnection(); //Starting WebRTC
     }
 
     /**
@@ -160,5 +173,83 @@ public class MyPersistentService extends Service {
         isServiceStarted = false;
     }
 
+    /////////////// WebRTC ////////////////////////
+
+    /**
+     * Initializing and starting WebRTC connection.
+     */
+    private void startWebRTCConnection() {
+        initializePeerConnectionFactory(); //Android Specific, you can Ignore.
+        mainPeerConnection = createPeerConnection(factory); //Creating New Peer Connection.
+        //TODO: Fetch Offer from broker.
+    }
+
+    /**
+     * Initializing peer connection factory.
+     */
+    private void initializePeerConnectionFactory() {
+        Log.d(TAG, "initializePeerConnectionFactory: Started");
+        PeerConnectionFactory.InitializationOptions initializationOptions =
+                PeerConnectionFactory.InitializationOptions.builder(this)
+                        .createInitializationOptions();
+        PeerConnectionFactory.initialize(initializationOptions);
+
+        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
+        factory = PeerConnectionFactory.builder()
+                .setOptions(options)
+                .createPeerConnectionFactory();
+        Log.d(TAG, "initializePeerConnectionFactory: Finished");
+    }
+
+    /**
+     * Creating a new peer connection.
+     *
+     * @param factory PeerConnectionFactory
+     * @return New PeerConnection
+     */
+    private PeerConnection createPeerConnection(PeerConnectionFactory factory) {
+        Log.d(TAG, "createPeerConnection: Creating a new peer connection");
+        List<PeerConnection.IceServer> iceServers = new LinkedList<>();
+//        iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()); To Add custom ICE servers.
+        PeerConnection.RTCConfiguration rtcConfiguration = new PeerConnection.RTCConfiguration(iceServers);
+        PeerConnection.Observer pcObserver = new MyPeerConnectionObserver(TAG, new PeerConnectionObserverCallback() {
+
+            @Override
+            public void onIceGatheringFinish() {
+                if (mainPeerConnection.connectionState() != PeerConnection.PeerConnectionState.CLOSED) {
+                    Log.d(TAG, "onIceGatheringFinish: Ice Gathering Finished. Sending Answer to broker...\n" + mainPeerConnection.getLocalDescription().description);
+                    //Sending the SDP Answer to the server.
+                    //TODO:Send Answer
+                }
+            }
+
+            @Override
+            public void onMessage(DataChannel.Buffer buffer) {
+                //Relay it to WebSocket
+                ByteBuffer data = ByteBuffer.wrap("HELLO".getBytes(Charset.defaultCharset())); //Sending some temporary data to test.
+                mainDataChannel.send(new DataChannel.Buffer(data, false));
+            }
+
+            @Override
+            public void onDataChannel(DataChannel dataChannel) {
+                Log.d(TAG, "onDataChannel: Setting Data Channel");
+                mainDataChannel = dataChannel;
+            }
+
+            @Override
+            public void iceConnectionFailed() {
+                Log.d(TAG, "iceConnectionFailed: ");
+                //Figuring out with trac ticket.
+            }
+
+            @Override
+            public void dataChannelStateChange(final DataChannel.State STATE) {
+                Log.d(TAG, "dataChannelStateChange: Data Channel State: " + STATE);
+            }
+        });
+
+        Log.d(TAG, "createPeerConnection: Finished creating peer connection.");
+        return factory.createPeerConnection(rtcConfiguration, pcObserver);
+    }
     /////////////////////////////////////
 }
diff --git a/app/src/main/java/org/torproject/snowflake/interfaces/PeerConnectionObserverCallback.java b/app/src/main/java/org/torproject/snowflake/interfaces/PeerConnectionObserverCallback.java
new file mode 100644
index 0000000..56be3ff
--- /dev/null
+++ b/app/src/main/java/org/torproject/snowflake/interfaces/PeerConnectionObserverCallback.java
@@ -0,0 +1,18 @@
+package org.torproject.snowflake.interfaces;
+
+import org.webrtc.DataChannel;
+
+/**
+ * Callback to MyPersistentService when even happens form PeerConnectionObserver.
+ */
+public interface PeerConnectionObserverCallback {
+    void onIceGatheringFinish();
+
+    void onMessage(DataChannel.Buffer buffer);
+
+    void onDataChannel(DataChannel dataChannel);
+
+    void dataChannelStateChange(final DataChannel.State state);
+
+    void iceConnectionFailed();
+}





More information about the tor-commits mailing list