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 |