Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(817)

Side by Side Diff: talk/examples/android/src/org/appspot/apprtc/CallActivity.java

Issue 1235563006: Move talk/examples/* to webrtc/examples. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: 201508051337 Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2015 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 package org.appspot.apprtc;
29
30 import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
31 import org.appspot.apprtc.AppRTCClient.SignalingParameters;
32 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
33 import org.appspot.apprtc.util.LooperExecutor;
34
35 import android.app.Activity;
36 import android.app.AlertDialog;
37 import android.app.FragmentTransaction;
38 import android.content.DialogInterface;
39 import android.content.Intent;
40 import android.content.pm.PackageManager;
41 import android.net.Uri;
42 import android.opengl.GLSurfaceView;
43 import android.os.Bundle;
44 import android.util.Log;
45 import android.view.View;
46 import android.view.Window;
47 import android.view.WindowManager.LayoutParams;
48 import android.widget.Toast;
49
50 import org.webrtc.IceCandidate;
51 import org.webrtc.SessionDescription;
52 import org.webrtc.StatsReport;
53 import org.webrtc.VideoRenderer;
54 import org.webrtc.VideoRendererGui;
55 import org.webrtc.VideoRendererGui.ScalingType;
56
57 /**
58 * Activity for peer connection call setup, call waiting
59 * and call view.
60 */
61 public class CallActivity extends Activity
62 implements AppRTCClient.SignalingEvents,
63 PeerConnectionClient.PeerConnectionEvents,
64 CallFragment.OnCallEvents {
65
66 public static final String EXTRA_ROOMID =
67 "org.appspot.apprtc.ROOMID";
68 public static final String EXTRA_LOOPBACK =
69 "org.appspot.apprtc.LOOPBACK";
70 public static final String EXTRA_VIDEO_CALL =
71 "org.appspot.apprtc.VIDEO_CALL";
72 public static final String EXTRA_VIDEO_WIDTH =
73 "org.appspot.apprtc.VIDEO_WIDTH";
74 public static final String EXTRA_VIDEO_HEIGHT =
75 "org.appspot.apprtc.VIDEO_HEIGHT";
76 public static final String EXTRA_VIDEO_FPS =
77 "org.appspot.apprtc.VIDEO_FPS";
78 public static final String EXTRA_VIDEO_BITRATE =
79 "org.appspot.apprtc.VIDEO_BITRATE";
80 public static final String EXTRA_VIDEOCODEC =
81 "org.appspot.apprtc.VIDEOCODEC";
82 public static final String EXTRA_HWCODEC_ENABLED =
83 "org.appspot.apprtc.HWCODEC";
84 public static final String EXTRA_AUDIO_BITRATE =
85 "org.appspot.apprtc.AUDIO_BITRATE";
86 public static final String EXTRA_AUDIOCODEC =
87 "org.appspot.apprtc.AUDIOCODEC";
88 public static final String EXTRA_NOAUDIOPROCESSING_ENABLED =
89 "org.appspot.apprtc.NOAUDIOPROCESSING";
90 public static final String EXTRA_CPUOVERUSE_DETECTION =
91 "org.appspot.apprtc.CPUOVERUSE_DETECTION";
92 public static final String EXTRA_DISPLAY_HUD =
93 "org.appspot.apprtc.DISPLAY_HUD";
94 public static final String EXTRA_CMDLINE =
95 "org.appspot.apprtc.CMDLINE";
96 public static final String EXTRA_RUNTIME =
97 "org.appspot.apprtc.RUNTIME";
98 private static final String TAG = "CallRTCClient";
99
100 // List of mandatory application permissions.
101 private static final String[] MANDATORY_PERMISSIONS = {
102 "android.permission.MODIFY_AUDIO_SETTINGS",
103 "android.permission.RECORD_AUDIO",
104 "android.permission.INTERNET"
105 };
106
107 // Peer connection statistics callback period in ms.
108 private static final int STAT_CALLBACK_PERIOD = 1000;
109 // Local preview screen position before call is connected.
110 private static final int LOCAL_X_CONNECTING = 0;
111 private static final int LOCAL_Y_CONNECTING = 0;
112 private static final int LOCAL_WIDTH_CONNECTING = 100;
113 private static final int LOCAL_HEIGHT_CONNECTING = 100;
114 // Local preview screen position after call is connected.
115 private static final int LOCAL_X_CONNECTED = 72;
116 private static final int LOCAL_Y_CONNECTED = 72;
117 private static final int LOCAL_WIDTH_CONNECTED = 25;
118 private static final int LOCAL_HEIGHT_CONNECTED = 25;
119 // Remote video screen position
120 private static final int REMOTE_X = 0;
121 private static final int REMOTE_Y = 0;
122 private static final int REMOTE_WIDTH = 100;
123 private static final int REMOTE_HEIGHT = 100;
124
125 private PeerConnectionClient peerConnectionClient = null;
126 private AppRTCClient appRtcClient;
127 private SignalingParameters signalingParameters;
128 private AppRTCAudioManager audioManager = null;
129 private VideoRenderer.Callbacks localRender;
130 private VideoRenderer.Callbacks remoteRender;
131 private ScalingType scalingType;
132 private Toast logToast;
133 private boolean commandLineRun;
134 private int runTimeMs;
135 private boolean activityRunning;
136 private RoomConnectionParameters roomConnectionParameters;
137 private PeerConnectionParameters peerConnectionParameters;
138 private boolean iceConnected;
139 private boolean isError;
140 private boolean callControlFragmentVisible = true;
141 private long callStartedTimeMs = 0;
142
143 // Controls
144 private GLSurfaceView videoView;
145 CallFragment callFragment;
146 HudFragment hudFragment;
147
148 @Override
149 public void onCreate(Bundle savedInstanceState) {
150 super.onCreate(savedInstanceState);
151 Thread.setDefaultUncaughtExceptionHandler(
152 new UnhandledExceptionHandler(this));
153
154 // Set window styles for fullscreen-window size. Needs to be done before
155 // adding content.
156 requestWindowFeature(Window.FEATURE_NO_TITLE);
157 getWindow().addFlags(
158 LayoutParams.FLAG_FULLSCREEN
159 | LayoutParams.FLAG_KEEP_SCREEN_ON
160 | LayoutParams.FLAG_DISMISS_KEYGUARD
161 | LayoutParams.FLAG_SHOW_WHEN_LOCKED
162 | LayoutParams.FLAG_TURN_SCREEN_ON);
163 getWindow().getDecorView().setSystemUiVisibility(
164 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
165 | View.SYSTEM_UI_FLAG_FULLSCREEN
166 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
167 setContentView(R.layout.activity_call);
168
169 iceConnected = false;
170 signalingParameters = null;
171 scalingType = ScalingType.SCALE_ASPECT_FILL;
172
173 // Create UI controls.
174 videoView = (GLSurfaceView) findViewById(R.id.glview_call);
175 callFragment = new CallFragment();
176 hudFragment = new HudFragment();
177
178 // Create video renderers.
179 VideoRendererGui.setView(videoView, new Runnable() {
180 @Override
181 public void run() {
182 createPeerConnectionFactory();
183 }
184 });
185 remoteRender = VideoRendererGui.create(
186 REMOTE_X, REMOTE_Y,
187 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
188 localRender = VideoRendererGui.create(
189 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
190 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
191
192 // Show/hide call control fragment on view click.
193 videoView.setOnClickListener(new View.OnClickListener() {
194 @Override
195 public void onClick(View view) {
196 toggleCallControlFragmentVisibility();
197 }
198 });
199
200 // Check for mandatory permissions.
201 for (String permission : MANDATORY_PERMISSIONS) {
202 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_ GRANTED) {
203 logAndToast("Permission " + permission + " is not granted");
204 setResult(RESULT_CANCELED);
205 finish();
206 return;
207 }
208 }
209
210 // Get Intent parameters.
211 final Intent intent = getIntent();
212 Uri roomUri = intent.getData();
213 if (roomUri == null) {
214 logAndToast(getString(R.string.missing_url));
215 Log.e(TAG, "Didn't get any URL in intent!");
216 setResult(RESULT_CANCELED);
217 finish();
218 return;
219 }
220 String roomId = intent.getStringExtra(EXTRA_ROOMID);
221 if (roomId == null || roomId.length() == 0) {
222 logAndToast(getString(R.string.missing_url));
223 Log.e(TAG, "Incorrect room ID in intent!");
224 setResult(RESULT_CANCELED);
225 finish();
226 return;
227 }
228 boolean loopback = intent.getBooleanExtra(EXTRA_LOOPBACK, false);
229 peerConnectionParameters = new PeerConnectionParameters(
230 intent.getBooleanExtra(EXTRA_VIDEO_CALL, true),
231 loopback,
232 intent.getIntExtra(EXTRA_VIDEO_WIDTH, 0),
233 intent.getIntExtra(EXTRA_VIDEO_HEIGHT, 0),
234 intent.getIntExtra(EXTRA_VIDEO_FPS, 0),
235 intent.getIntExtra(EXTRA_VIDEO_BITRATE, 0),
236 intent.getStringExtra(EXTRA_VIDEOCODEC),
237 intent.getBooleanExtra(EXTRA_HWCODEC_ENABLED, true),
238 intent.getIntExtra(EXTRA_AUDIO_BITRATE, 0),
239 intent.getStringExtra(EXTRA_AUDIOCODEC),
240 intent.getBooleanExtra(EXTRA_NOAUDIOPROCESSING_ENABLED, false),
241 intent.getBooleanExtra(EXTRA_CPUOVERUSE_DETECTION, true));
242 commandLineRun = intent.getBooleanExtra(EXTRA_CMDLINE, false);
243 runTimeMs = intent.getIntExtra(EXTRA_RUNTIME, 0);
244
245 // Create connection client and connection parameters.
246 appRtcClient = new WebSocketRTCClient(this, new LooperExecutor());
247 roomConnectionParameters = new RoomConnectionParameters(
248 roomUri.toString(), roomId, loopback);
249
250 // Send intent arguments to fragments.
251 callFragment.setArguments(intent.getExtras());
252 hudFragment.setArguments(intent.getExtras());
253 // Activate call and HUD fragments and start the call.
254 FragmentTransaction ft = getFragmentManager().beginTransaction();
255 ft.add(R.id.call_fragment_container, callFragment);
256 ft.add(R.id.hud_fragment_container, hudFragment);
257 ft.commit();
258 startCall();
259
260 // For command line execution run connection for <runTimeMs> and exit.
261 if (commandLineRun && runTimeMs > 0) {
262 videoView.postDelayed(new Runnable() {
263 public void run() {
264 disconnect();
265 }
266 }, runTimeMs);
267 }
268 }
269
270 // Activity interfaces
271 @Override
272 public void onPause() {
273 super.onPause();
274 videoView.onPause();
275 activityRunning = false;
276 if (peerConnectionClient != null) {
277 peerConnectionClient.stopVideoSource();
278 }
279 }
280
281 @Override
282 public void onResume() {
283 super.onResume();
284 videoView.onResume();
285 activityRunning = true;
286 if (peerConnectionClient != null) {
287 peerConnectionClient.startVideoSource();
288 }
289 }
290
291 @Override
292 protected void onDestroy() {
293 disconnect();
294 super.onDestroy();
295 if (logToast != null) {
296 logToast.cancel();
297 }
298 activityRunning = false;
299 }
300
301 // CallFragment.OnCallEvents interface implementation.
302 @Override
303 public void onCallHangUp() {
304 disconnect();
305 }
306
307 @Override
308 public void onCameraSwitch() {
309 if (peerConnectionClient != null) {
310 peerConnectionClient.switchCamera();
311 }
312 }
313
314 @Override
315 public void onVideoScalingSwitch(ScalingType scalingType) {
316 this.scalingType = scalingType;
317 updateVideoView();
318 }
319
320 // Helper functions.
321 private void toggleCallControlFragmentVisibility() {
322 if (!iceConnected || !callFragment.isAdded()) {
323 return;
324 }
325 // Show/hide call control fragment
326 callControlFragmentVisible = !callControlFragmentVisible;
327 FragmentTransaction ft = getFragmentManager().beginTransaction();
328 if (callControlFragmentVisible) {
329 ft.show(callFragment);
330 ft.show(hudFragment);
331 } else {
332 ft.hide(callFragment);
333 ft.hide(hudFragment);
334 }
335 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
336 ft.commit();
337 }
338
339 private void updateVideoView() {
340 VideoRendererGui.update(remoteRender,
341 REMOTE_X, REMOTE_Y,
342 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
343 if (iceConnected) {
344 VideoRendererGui.update(localRender,
345 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED,
346 LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED,
347 ScalingType.SCALE_ASPECT_FIT, true);
348 } else {
349 VideoRendererGui.update(localRender,
350 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
351 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
352 }
353 }
354
355 private void startCall() {
356 if (appRtcClient == null) {
357 Log.e(TAG, "AppRTC client is not allocated for a call.");
358 return;
359 }
360 callStartedTimeMs = System.currentTimeMillis();
361
362 // Start room connection.
363 logAndToast(getString(R.string.connecting_to,
364 roomConnectionParameters.roomUrl));
365 appRtcClient.connectToRoom(roomConnectionParameters);
366
367 // Create and audio manager that will take care of audio routing,
368 // audio modes, audio device enumeration etc.
369 audioManager = AppRTCAudioManager.create(this, new Runnable() {
370 // This method will be called each time the audio state (number and
371 // type of devices) has been changed.
372 @Override
373 public void run() {
374 onAudioManagerChangedState();
375 }
376 }
377 );
378 // Store existing audio settings and change audio mode to
379 // MODE_IN_COMMUNICATION for best possible VoIP performance.
380 Log.d(TAG, "Initializing the audio manager...");
381 audioManager.init();
382 }
383
384 // Should be called from UI thread
385 private void callConnected() {
386 final long delta = System.currentTimeMillis() - callStartedTimeMs;
387 Log.i(TAG, "Call connected: delay=" + delta + "ms");
388
389 // Update video view.
390 updateVideoView();
391 // Enable statistics callback.
392 peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
393 }
394
395 private void onAudioManagerChangedState() {
396 // TODO(henrika): disable video if AppRTCAudioManager.AudioDevice.EARPIECE
397 // is active.
398 }
399
400 // Create peer connection factory when EGL context is ready.
401 private void createPeerConnectionFactory() {
402 runOnUiThread(new Runnable() {
403 @Override
404 public void run() {
405 if (peerConnectionClient == null) {
406 final long delta = System.currentTimeMillis() - callStartedTimeMs;
407 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms");
408 peerConnectionClient = PeerConnectionClient.getInstance();
409 peerConnectionClient.createPeerConnectionFactory(CallActivity.this,
410 VideoRendererGui.getEGLContext(), peerConnectionParameters,
411 CallActivity.this);
412 }
413 if (signalingParameters != null) {
414 Log.w(TAG, "EGL context is ready after room connection.");
415 onConnectedToRoomInternal(signalingParameters);
416 }
417 }
418 });
419 }
420
421 // Disconnect from remote resources, dispose of local resources, and exit.
422 private void disconnect() {
423 activityRunning = false;
424 if (appRtcClient != null) {
425 appRtcClient.disconnectFromRoom();
426 appRtcClient = null;
427 }
428 if (peerConnectionClient != null) {
429 peerConnectionClient.close();
430 peerConnectionClient = null;
431 }
432 if (audioManager != null) {
433 audioManager.close();
434 audioManager = null;
435 }
436 if (iceConnected && !isError) {
437 setResult(RESULT_OK);
438 } else {
439 setResult(RESULT_CANCELED);
440 }
441 finish();
442 }
443
444 private void disconnectWithErrorMessage(final String errorMessage) {
445 if (commandLineRun || !activityRunning) {
446 Log.e(TAG, "Critical error: " + errorMessage);
447 disconnect();
448 } else {
449 new AlertDialog.Builder(this)
450 .setTitle(getText(R.string.channel_error_title))
451 .setMessage(errorMessage)
452 .setCancelable(false)
453 .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
454 @Override
455 public void onClick(DialogInterface dialog, int id) {
456 dialog.cancel();
457 disconnect();
458 }
459 }).create().show();
460 }
461 }
462
463 // Log |msg| and Toast about it.
464 private void logAndToast(String msg) {
465 Log.d(TAG, msg);
466 if (logToast != null) {
467 logToast.cancel();
468 }
469 logToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
470 logToast.show();
471 }
472
473 private void reportError(final String description) {
474 runOnUiThread(new Runnable() {
475 @Override
476 public void run() {
477 if (!isError) {
478 isError = true;
479 disconnectWithErrorMessage(description);
480 }
481 }
482 });
483 }
484
485 // -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
486 // All callbacks are invoked from websocket signaling looper thread and
487 // are routed to UI thread.
488 private void onConnectedToRoomInternal(final SignalingParameters params) {
489 final long delta = System.currentTimeMillis() - callStartedTimeMs;
490
491 signalingParameters = params;
492 if (peerConnectionClient == null) {
493 Log.w(TAG, "Room is connected, but EGL context is not ready yet.");
494 return;
495 }
496 logAndToast("Creating peer connection, delay=" + delta + "ms");
497 peerConnectionClient.createPeerConnection(
498 localRender, remoteRender, signalingParameters);
499
500 if (signalingParameters.initiator) {
501 logAndToast("Creating OFFER...");
502 // Create offer. Offer SDP will be sent to answering client in
503 // PeerConnectionEvents.onLocalDescription event.
504 peerConnectionClient.createOffer();
505 } else {
506 if (params.offerSdp != null) {
507 peerConnectionClient.setRemoteDescription(params.offerSdp);
508 logAndToast("Creating ANSWER...");
509 // Create answer. Answer SDP will be sent to offering client in
510 // PeerConnectionEvents.onLocalDescription event.
511 peerConnectionClient.createAnswer();
512 }
513 if (params.iceCandidates != null) {
514 // Add remote ICE candidates from room.
515 for (IceCandidate iceCandidate : params.iceCandidates) {
516 peerConnectionClient.addRemoteIceCandidate(iceCandidate);
517 }
518 }
519 }
520 }
521
522 @Override
523 public void onConnectedToRoom(final SignalingParameters params) {
524 runOnUiThread(new Runnable() {
525 @Override
526 public void run() {
527 onConnectedToRoomInternal(params);
528 }
529 });
530 }
531
532 @Override
533 public void onRemoteDescription(final SessionDescription sdp) {
534 final long delta = System.currentTimeMillis() - callStartedTimeMs;
535 runOnUiThread(new Runnable() {
536 @Override
537 public void run() {
538 if (peerConnectionClient == null) {
539 Log.e(TAG, "Received remote SDP for non-initilized peer connection.");
540 return;
541 }
542 logAndToast("Received remote " + sdp.type + ", delay=" + delta + "ms");
543 peerConnectionClient.setRemoteDescription(sdp);
544 if (!signalingParameters.initiator) {
545 logAndToast("Creating ANSWER...");
546 // Create answer. Answer SDP will be sent to offering client in
547 // PeerConnectionEvents.onLocalDescription event.
548 peerConnectionClient.createAnswer();
549 }
550 }
551 });
552 }
553
554 @Override
555 public void onRemoteIceCandidate(final IceCandidate candidate) {
556 runOnUiThread(new Runnable() {
557 @Override
558 public void run() {
559 if (peerConnectionClient == null) {
560 Log.e(TAG,
561 "Received ICE candidate for non-initilized peer connection.");
562 return;
563 }
564 peerConnectionClient.addRemoteIceCandidate(candidate);
565 }
566 });
567 }
568
569 @Override
570 public void onChannelClose() {
571 runOnUiThread(new Runnable() {
572 @Override
573 public void run() {
574 logAndToast("Remote end hung up; dropping PeerConnection");
575 disconnect();
576 }
577 });
578 }
579
580 @Override
581 public void onChannelError(final String description) {
582 reportError(description);
583 }
584
585 // -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
586 // Send local peer connection SDP and ICE candidates to remote party.
587 // All callbacks are invoked from peer connection client looper thread and
588 // are routed to UI thread.
589 @Override
590 public void onLocalDescription(final SessionDescription sdp) {
591 final long delta = System.currentTimeMillis() - callStartedTimeMs;
592 runOnUiThread(new Runnable() {
593 @Override
594 public void run() {
595 if (appRtcClient != null) {
596 logAndToast("Sending " + sdp.type + ", delay=" + delta + "ms");
597 if (signalingParameters.initiator) {
598 appRtcClient.sendOfferSdp(sdp);
599 } else {
600 appRtcClient.sendAnswerSdp(sdp);
601 }
602 }
603 }
604 });
605 }
606
607 @Override
608 public void onIceCandidate(final IceCandidate candidate) {
609 runOnUiThread(new Runnable() {
610 @Override
611 public void run() {
612 if (appRtcClient != null) {
613 appRtcClient.sendLocalIceCandidate(candidate);
614 }
615 }
616 });
617 }
618
619 @Override
620 public void onIceConnected() {
621 final long delta = System.currentTimeMillis() - callStartedTimeMs;
622 runOnUiThread(new Runnable() {
623 @Override
624 public void run() {
625 logAndToast("ICE connected, delay=" + delta + "ms");
626 iceConnected = true;
627 callConnected();
628 }
629 });
630 }
631
632 @Override
633 public void onIceDisconnected() {
634 runOnUiThread(new Runnable() {
635 @Override
636 public void run() {
637 logAndToast("ICE disconnected");
638 iceConnected = false;
639 disconnect();
640 }
641 });
642 }
643
644 @Override
645 public void onPeerConnectionClosed() {
646 }
647
648 @Override
649 public void onPeerConnectionStatsReady(final StatsReport[] reports) {
650 runOnUiThread(new Runnable() {
651 @Override
652 public void run() {
653 if (!isError && iceConnected) {
654 hudFragment.updateEncoderStatistics(reports);
655 }
656 }
657 });
658 }
659
660 @Override
661 public void onPeerConnectionError(final String description) {
662 reportError(description);
663 }
664 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698