David Liu

Enable binary encoding

@@ -7,5 +7,7 @@ class InjectionNames { @@ -7,5 +7,7 @@ class InjectionNames {
7 const val DISPATCHER_IO = "dispatcher_io"; 7 const val DISPATCHER_IO = "dispatcher_io";
8 const val DISPATCHER_MAIN = "dispatcher_main" 8 const val DISPATCHER_MAIN = "dispatcher_main"
9 const val DISPATCHER_UNCONFINED = "dispatcher_unconfined" 9 const val DISPATCHER_UNCONFINED = "dispatcher_unconfined"
  10 +
  11 + const val SIGNAL_JSON_ENABLED = "signal_json_enabled"
10 } 12 }
11 } 13 }
@@ -3,6 +3,7 @@ package io.livekit.android.dagger @@ -3,6 +3,7 @@ package io.livekit.android.dagger
3 import com.google.protobuf.util.JsonFormat 3 import com.google.protobuf.util.JsonFormat
4 import dagger.Module 4 import dagger.Module
5 import dagger.Provides 5 import dagger.Provides
  6 +import javax.inject.Named
6 7
7 @Module 8 @Module
8 class JsonFormatModule { 9 class JsonFormatModule {
@@ -16,5 +17,9 @@ class JsonFormatModule { @@ -16,5 +17,9 @@ class JsonFormatModule {
16 fun jsonFormatPrinter(): JsonFormat.Printer { 17 fun jsonFormatPrinter(): JsonFormat.Printer {
17 return JsonFormat.printer() 18 return JsonFormat.printer()
18 } 19 }
  20 +
  21 + @Provides
  22 + @Named(InjectionNames.SIGNAL_JSON_ENABLED)
  23 + fun signalJsonEnabled(): Boolean = false
19 } 24 }
20 } 25 }
@@ -2,6 +2,7 @@ package io.livekit.android.room @@ -2,6 +2,7 @@ package io.livekit.android.room
2 2
3 import com.github.ajalt.timberkt.Timber 3 import com.github.ajalt.timberkt.Timber
4 import com.google.protobuf.util.JsonFormat 4 import com.google.protobuf.util.JsonFormat
  5 +import io.livekit.android.dagger.InjectionNames
5 import io.livekit.android.room.track.Track 6 import io.livekit.android.room.track.Track
6 import kotlinx.serialization.decodeFromString 7 import kotlinx.serialization.decodeFromString
7 import kotlinx.serialization.encodeToString 8 import kotlinx.serialization.encodeToString
@@ -13,10 +14,12 @@ import okhttp3.Response @@ -13,10 +14,12 @@ import okhttp3.Response
13 import okhttp3.WebSocket 14 import okhttp3.WebSocket
14 import okhttp3.WebSocketListener 15 import okhttp3.WebSocketListener
15 import okio.ByteString 16 import okio.ByteString
  17 +import okio.ByteString.Companion.toByteString
16 import org.webrtc.IceCandidate 18 import org.webrtc.IceCandidate
17 import org.webrtc.PeerConnection 19 import org.webrtc.PeerConnection
18 import org.webrtc.SessionDescription 20 import org.webrtc.SessionDescription
19 import javax.inject.Inject 21 import javax.inject.Inject
  22 +import javax.inject.Named
20 23
21 class RTCClient 24 class RTCClient
22 @Inject 25 @Inject
@@ -24,6 +27,8 @@ constructor( @@ -24,6 +27,8 @@ constructor(
24 private val websocketFactory: WebSocket.Factory, 27 private val websocketFactory: WebSocket.Factory,
25 private val fromJson: JsonFormat.Parser, 28 private val fromJson: JsonFormat.Parser,
26 private val toJson: JsonFormat.Printer, 29 private val toJson: JsonFormat.Printer,
  30 + @Named(InjectionNames.SIGNAL_JSON_ENABLED)
  31 + private val useJson: Boolean,
27 ) : WebSocketListener() { 32 ) : WebSocketListener() {
28 33
29 private var isConnected = false 34 private var isConnected = false
@@ -55,21 +60,16 @@ constructor( @@ -55,21 +60,16 @@ constructor(
55 fromJson.merge(text, signalResponseBuilder) 60 fromJson.merge(text, signalResponseBuilder)
56 val response = signalResponseBuilder.build() 61 val response = signalResponseBuilder.build()
57 62
58 - if (!isConnected) {  
59 - // Only handle joins if not connected.  
60 - if (response.hasJoin()) {  
61 - isConnected = true  
62 - listener?.onJoin(response.join)  
63 - } else {  
64 - Timber.e { "out of order message?" }  
65 - }  
66 - return  
67 - }  
68 handleSignalResponse(response) 63 handleSignalResponse(response)
69 } 64 }
70 65
71 override fun onMessage(webSocket: WebSocket, bytes: ByteString) { 66 override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
72 - super.onMessage(webSocket, bytes) 67 + val byteArray = bytes.toByteArray()
  68 + val signalResponseBuilder = Rtc.SignalResponse.newBuilder()
  69 + .mergeFrom(byteArray)
  70 + val response = signalResponseBuilder.build()
  71 +
  72 + handleSignalResponse(response)
73 } 73 }
74 74
75 override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { 75 override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
@@ -177,8 +177,14 @@ constructor( @@ -177,8 +177,14 @@ constructor(
177 if (!isConnected || currentWs != null) { 177 if (!isConnected || currentWs != null) {
178 throw IllegalStateException("not connected!") 178 throw IllegalStateException("not connected!")
179 } 179 }
  180 + val sent: Boolean
  181 + if (useJson) {
180 val message = toJson.print(request) 182 val message = toJson.print(request)
181 - val sent = currentWs?.send(message) ?: false 183 + sent = currentWs?.send(message) ?: false
  184 + } else {
  185 + val message = request.toByteArray().toByteString()
  186 + sent = currentWs?.send(message) ?: false
  187 + }
182 188
183 if (!sent) { 189 if (!sent) {
184 Timber.d { "error sending request: $request" } 190 Timber.d { "error sending request: $request" }
@@ -188,7 +194,13 @@ constructor( @@ -188,7 +194,13 @@ constructor(
188 194
189 fun handleSignalResponse(response: Rtc.SignalResponse) { 195 fun handleSignalResponse(response: Rtc.SignalResponse) {
190 if (!isConnected) { 196 if (!isConnected) {
  197 + // Only handle joins if not connected.
  198 + if (response.hasJoin()) {
  199 + isConnected = true
  200 + listener?.onJoin(response.join)
  201 + } else {
191 Timber.e { "Received response while not connected. ${toJson.print(response)}" } 202 Timber.e { "Received response while not connected. ${toJson.print(response)}" }
  203 + }
192 return 204 return
193 } 205 }
194 when (response.messageCase) { 206 when (response.messageCase) {