| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
| 12 | 12 |
| 13 import org.appspot.apprtc.RoomParametersFetcher.RoomParametersFetcherEvents; | 13 import org.appspot.apprtc.RoomParametersFetcher.RoomParametersFetcherEvents; |
| 14 import org.appspot.apprtc.WebSocketChannelClient.WebSocketChannelEvents; | 14 import org.appspot.apprtc.WebSocketChannelClient.WebSocketChannelEvents; |
| 15 import org.appspot.apprtc.WebSocketChannelClient.WebSocketConnectionState; | 15 import org.appspot.apprtc.WebSocketChannelClient.WebSocketConnectionState; |
| 16 import org.appspot.apprtc.util.AsyncHttpURLConnection; | 16 import org.appspot.apprtc.util.AsyncHttpURLConnection; |
| 17 import org.appspot.apprtc.util.AsyncHttpURLConnection.AsyncHttpEvents; | 17 import org.appspot.apprtc.util.AsyncHttpURLConnection.AsyncHttpEvents; |
| 18 import org.appspot.apprtc.util.LooperExecutor; | 18 import org.appspot.apprtc.util.LooperExecutor; |
| 19 | 19 |
| 20 import android.util.Log; | 20 import android.util.Log; |
| 21 | 21 |
| 22 import org.json.JSONArray; | |
| 23 import org.json.JSONException; | 22 import org.json.JSONException; |
| 24 import org.json.JSONObject; | 23 import org.json.JSONObject; |
| 25 import org.webrtc.IceCandidate; | 24 import org.webrtc.IceCandidate; |
| 26 import org.webrtc.SessionDescription; | 25 import org.webrtc.SessionDescription; |
| 27 | 26 |
| 28 /** | 27 /** |
| 29 * Negotiates signaling for chatting with apprtc.appspot.com "rooms". | 28 * Negotiates signaling for chatting with apprtc.appspot.com "rooms". |
| 30 * Uses the client<->server specifics of the apprtc AppEngine webapp. | 29 * Uses the client<->server specifics of the apprtc AppEngine webapp. |
| 31 * | 30 * |
| 32 * <p>To use: create an instance of this object (registering a message handler)
and | 31 * <p>To use: create an instance of this object (registering a message handler)
and |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 events.onRemoteIceCandidate(candidate); | 245 events.onRemoteIceCandidate(candidate); |
| 247 } | 246 } |
| 248 } else { | 247 } else { |
| 249 // Call receiver sends ice candidates to websocket server. | 248 // Call receiver sends ice candidates to websocket server. |
| 250 wsClient.send(json.toString()); | 249 wsClient.send(json.toString()); |
| 251 } | 250 } |
| 252 } | 251 } |
| 253 }); | 252 }); |
| 254 } | 253 } |
| 255 | 254 |
| 256 // Send removed Ice candidates to the other participant. | |
| 257 @Override | |
| 258 public void sendLocalIceCandidateRemovals(final IceCandidate[] candidates) { | |
| 259 executor.execute(new Runnable() { | |
| 260 @Override | |
| 261 public void run() { | |
| 262 JSONObject json = new JSONObject(); | |
| 263 jsonPut(json, "type", "remove-candidates"); | |
| 264 JSONArray jsonArray = new JSONArray(); | |
| 265 for (final IceCandidate candidate : candidates) { | |
| 266 jsonArray.put(toJsonCandidate(candidate)); | |
| 267 } | |
| 268 jsonPut(json, "candidates", jsonArray); | |
| 269 if (initiator) { | |
| 270 // Call initiator sends ice candidates to GAE server. | |
| 271 if (roomState != ConnectionState.CONNECTED) { | |
| 272 reportError("Sending ICE candidate removals in non connected state."
); | |
| 273 return; | |
| 274 } | |
| 275 sendPostMessage(MessageType.MESSAGE, messageUrl, json.toString()); | |
| 276 if (connectionParameters.loopback) { | |
| 277 events.onRemoteIceCandidatesRemoved(candidates); | |
| 278 } | |
| 279 } else { | |
| 280 // Call receiver sends ice candidates to websocket server. | |
| 281 wsClient.send(json.toString()); | |
| 282 } | |
| 283 } | |
| 284 }); | |
| 285 } | |
| 286 | |
| 287 // -------------------------------------------------------------------- | 255 // -------------------------------------------------------------------- |
| 288 // WebSocketChannelEvents interface implementation. | 256 // WebSocketChannelEvents interface implementation. |
| 289 // All events are called by WebSocketChannelClient on a local looper thread | 257 // All events are called by WebSocketChannelClient on a local looper thread |
| 290 // (passed to WebSocket client constructor). | 258 // (passed to WebSocket client constructor). |
| 291 @Override | 259 @Override |
| 292 public void onWebSocketMessage(final String msg) { | 260 public void onWebSocketMessage(final String msg) { |
| 293 if (wsClient.getState() != WebSocketConnectionState.REGISTERED) { | 261 if (wsClient.getState() != WebSocketConnectionState.REGISTERED) { |
| 294 Log.e(TAG, "Got WebSocket message in non registered state."); | 262 Log.e(TAG, "Got WebSocket message in non registered state."); |
| 295 return; | 263 return; |
| 296 } | 264 } |
| 297 try { | 265 try { |
| 298 JSONObject json = new JSONObject(msg); | 266 JSONObject json = new JSONObject(msg); |
| 299 String msgText = json.getString("msg"); | 267 String msgText = json.getString("msg"); |
| 300 String errorText = json.optString("error"); | 268 String errorText = json.optString("error"); |
| 301 if (msgText.length() > 0) { | 269 if (msgText.length() > 0) { |
| 302 json = new JSONObject(msgText); | 270 json = new JSONObject(msgText); |
| 303 String type = json.optString("type"); | 271 String type = json.optString("type"); |
| 304 if (type.equals("candidate")) { | 272 if (type.equals("candidate")) { |
| 305 events.onRemoteIceCandidate(toJavaCandidate(json)); | 273 IceCandidate candidate = new IceCandidate( |
| 306 } else if (type.equals("remove-candidates")) { | 274 json.getString("id"), |
| 307 JSONArray candidateArray = json.getJSONArray("candidates"); | 275 json.getInt("label"), |
| 308 IceCandidate[] candidates = new IceCandidate[candidateArray.length()]; | 276 json.getString("candidate")); |
| 309 for (int i =0; i < candidateArray.length(); ++i) { | 277 events.onRemoteIceCandidate(candidate); |
| 310 candidates[i] = toJavaCandidate(candidateArray.getJSONObject(i)); | |
| 311 } | |
| 312 events.onRemoteIceCandidatesRemoved(candidates); | |
| 313 } else if (type.equals("answer")) { | 278 } else if (type.equals("answer")) { |
| 314 if (initiator) { | 279 if (initiator) { |
| 315 SessionDescription sdp = new SessionDescription( | 280 SessionDescription sdp = new SessionDescription( |
| 316 SessionDescription.Type.fromCanonicalForm(type), | 281 SessionDescription.Type.fromCanonicalForm(type), |
| 317 json.getString("sdp")); | 282 json.getString("sdp")); |
| 318 events.onRemoteDescription(sdp); | 283 events.onRemoteDescription(sdp); |
| 319 } else { | 284 } else { |
| 320 reportError("Received answer for call initiator: " + msg); | 285 reportError("Received answer for call initiator: " + msg); |
| 321 } | 286 } |
| 322 } else if (type.equals("offer")) { | 287 } else if (type.equals("offer")) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 reportError("GAE POST error: " + result); | 369 reportError("GAE POST error: " + result); |
| 405 } | 370 } |
| 406 } catch (JSONException e) { | 371 } catch (JSONException e) { |
| 407 reportError("GAE POST JSON error: " + e.toString()); | 372 reportError("GAE POST JSON error: " + e.toString()); |
| 408 } | 373 } |
| 409 } | 374 } |
| 410 } | 375 } |
| 411 }); | 376 }); |
| 412 httpConnection.send(); | 377 httpConnection.send(); |
| 413 } | 378 } |
| 414 | |
| 415 // Converts a Java candidate to a JSONObject. | |
| 416 private JSONObject toJsonCandidate(final IceCandidate candidate) { | |
| 417 JSONObject json = new JSONObject(); | |
| 418 jsonPut(json, "label", candidate.sdpMLineIndex); | |
| 419 jsonPut(json, "id", candidate.sdpMid); | |
| 420 jsonPut(json, "candidate", candidate.sdp); | |
| 421 return json; | |
| 422 } | |
| 423 | |
| 424 // Converts a JSON candidate to a Java object. | |
| 425 IceCandidate toJavaCandidate(JSONObject json) throws JSONException { | |
| 426 return new IceCandidate(json.getString("id"), | |
| 427 json.getInt("label"), | |
| 428 json.getString("candidate")); | |
| 429 } | |
| 430 } | 379 } |
| OLD | NEW |