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

Side by Side Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java

Issue 1356603004: Enable SurfaceViewRenderer for AppRTCDemo (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressing Alex's comments Created 5 years, 2 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
1 /* 1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2015 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.AppRTCClient.RoomConnectionParameters; 13 import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
14 import org.appspot.apprtc.AppRTCClient.SignalingParameters; 14 import org.appspot.apprtc.AppRTCClient.SignalingParameters;
15 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters; 15 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
16 import org.appspot.apprtc.util.LooperExecutor; 16 import org.appspot.apprtc.util.LooperExecutor;
17 17
18 import android.app.Activity; 18 import android.app.Activity;
19 import android.app.AlertDialog; 19 import android.app.AlertDialog;
20 import android.app.FragmentTransaction; 20 import android.app.FragmentTransaction;
21 import android.content.DialogInterface; 21 import android.content.DialogInterface;
22 import android.content.Intent; 22 import android.content.Intent;
23 import android.content.pm.PackageManager; 23 import android.content.pm.PackageManager;
24 import android.net.Uri; 24 import android.net.Uri;
25 import android.opengl.GLSurfaceView; 25 import android.opengl.GLSurfaceView;
26 import android.os.Bundle; 26 import android.os.Bundle;
27 import android.os.Handler;
27 import android.util.Log; 28 import android.util.Log;
28 import android.view.View; 29 import android.view.View;
29 import android.view.Window; 30 import android.view.Window;
30 import android.view.WindowManager.LayoutParams; 31 import android.view.WindowManager.LayoutParams;
31 import android.widget.Toast; 32 import android.widget.Toast;
32 33
34 import org.webrtc.EglBase;
33 import org.webrtc.IceCandidate; 35 import org.webrtc.IceCandidate;
34 import org.webrtc.SessionDescription; 36 import org.webrtc.SessionDescription;
35 import org.webrtc.StatsReport; 37 import org.webrtc.StatsReport;
36 import org.webrtc.RendererCommon.ScalingType; 38 import org.webrtc.RendererCommon.ScalingType;
37 import org.webrtc.VideoRenderer; 39 import org.webrtc.SurfaceViewRenderer;
38 import org.webrtc.VideoRendererGui;
39 40
40 /** 41 /**
41 * Activity for peer connection call setup, call waiting 42 * Activity for peer connection call setup, call waiting
42 * and call view. 43 * and call view.
43 */ 44 */
44 public class CallActivity extends Activity 45 public class CallActivity extends Activity
45 implements AppRTCClient.SignalingEvents, 46 implements AppRTCClient.SignalingEvents,
46 PeerConnectionClient.PeerConnectionEvents, 47 PeerConnectionClient.PeerConnectionEvents,
47 CallFragment.OnCallEvents { 48 CallFragment.OnCallEvents {
48 49
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 // Local preview screen position after call is connected. 98 // Local preview screen position after call is connected.
98 private static final int LOCAL_X_CONNECTED = 72; 99 private static final int LOCAL_X_CONNECTED = 72;
99 private static final int LOCAL_Y_CONNECTED = 72; 100 private static final int LOCAL_Y_CONNECTED = 72;
100 private static final int LOCAL_WIDTH_CONNECTED = 25; 101 private static final int LOCAL_WIDTH_CONNECTED = 25;
101 private static final int LOCAL_HEIGHT_CONNECTED = 25; 102 private static final int LOCAL_HEIGHT_CONNECTED = 25;
102 // Remote video screen position 103 // Remote video screen position
103 private static final int REMOTE_X = 0; 104 private static final int REMOTE_X = 0;
104 private static final int REMOTE_Y = 0; 105 private static final int REMOTE_Y = 0;
105 private static final int REMOTE_WIDTH = 100; 106 private static final int REMOTE_WIDTH = 100;
106 private static final int REMOTE_HEIGHT = 100; 107 private static final int REMOTE_HEIGHT = 100;
107
108 private PeerConnectionClient peerConnectionClient = null; 108 private PeerConnectionClient peerConnectionClient = null;
109 private AppRTCClient appRtcClient; 109 private AppRTCClient appRtcClient;
110 private SignalingParameters signalingParameters; 110 private SignalingParameters signalingParameters;
111 private AppRTCAudioManager audioManager = null; 111 private AppRTCAudioManager audioManager = null;
112 private VideoRenderer.Callbacks localRender; 112 private EglBase rootEglBase;
113 private VideoRenderer.Callbacks remoteRender; 113 private SurfaceViewRenderer localRender;
114 private SurfaceViewRenderer remoteRender;
115 private PercentFrameLayout localRenderLayout;
116 private PercentFrameLayout remoteRenderLayout;
114 private ScalingType scalingType; 117 private ScalingType scalingType;
115 private Toast logToast; 118 private Toast logToast;
116 private boolean commandLineRun; 119 private boolean commandLineRun;
117 private int runTimeMs; 120 private int runTimeMs;
118 private boolean activityRunning; 121 private boolean activityRunning;
119 private RoomConnectionParameters roomConnectionParameters; 122 private RoomConnectionParameters roomConnectionParameters;
120 private PeerConnectionParameters peerConnectionParameters; 123 private PeerConnectionParameters peerConnectionParameters;
121 private boolean iceConnected; 124 private boolean iceConnected;
122 private boolean isError; 125 private boolean isError;
123 private boolean callControlFragmentVisible = true; 126 private boolean callControlFragmentVisible = true;
124 private long callStartedTimeMs = 0; 127 private long callStartedTimeMs = 0;
125 128
126 // Controls 129 // Controls
127 private GLSurfaceView videoView;
128 CallFragment callFragment; 130 CallFragment callFragment;
129 HudFragment hudFragment; 131 HudFragment hudFragment;
130 132
131 @Override 133 @Override
132 public void onCreate(Bundle savedInstanceState) { 134 public void onCreate(Bundle savedInstanceState) {
133 super.onCreate(savedInstanceState); 135 super.onCreate(savedInstanceState);
134 Thread.setDefaultUncaughtExceptionHandler( 136 Thread.setDefaultUncaughtExceptionHandler(
135 new UnhandledExceptionHandler(this)); 137 new UnhandledExceptionHandler(this));
136 138
137 // Set window styles for fullscreen-window size. Needs to be done before 139 // Set window styles for fullscreen-window size. Needs to be done before
138 // adding content. 140 // adding content.
139 requestWindowFeature(Window.FEATURE_NO_TITLE); 141 requestWindowFeature(Window.FEATURE_NO_TITLE);
140 getWindow().addFlags( 142 getWindow().addFlags(
141 LayoutParams.FLAG_FULLSCREEN 143 LayoutParams.FLAG_FULLSCREEN
142 | LayoutParams.FLAG_KEEP_SCREEN_ON 144 | LayoutParams.FLAG_KEEP_SCREEN_ON
143 | LayoutParams.FLAG_DISMISS_KEYGUARD 145 | LayoutParams.FLAG_DISMISS_KEYGUARD
144 | LayoutParams.FLAG_SHOW_WHEN_LOCKED 146 | LayoutParams.FLAG_SHOW_WHEN_LOCKED
145 | LayoutParams.FLAG_TURN_SCREEN_ON); 147 | LayoutParams.FLAG_TURN_SCREEN_ON);
146 getWindow().getDecorView().setSystemUiVisibility( 148 getWindow().getDecorView().setSystemUiVisibility(
147 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 149 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
148 | View.SYSTEM_UI_FLAG_FULLSCREEN 150 | View.SYSTEM_UI_FLAG_FULLSCREEN
149 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 151 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
150 setContentView(R.layout.activity_call); 152 setContentView(R.layout.activity_call);
151 153
152 iceConnected = false; 154 iceConnected = false;
153 signalingParameters = null; 155 signalingParameters = null;
154 scalingType = ScalingType.SCALE_ASPECT_FILL; 156 scalingType = ScalingType.SCALE_ASPECT_FILL;
155 157
156 // Create UI controls. 158 // Create UI controls.
157 videoView = (GLSurfaceView) findViewById(R.id.glview_call); 159 localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view);
160 remoteRender = (SurfaceViewRenderer) findViewById(R.id.remote_video_view);
161 localRenderLayout = (PercentFrameLayout) findViewById(R.id.local_video_layou t);
162 remoteRenderLayout = (PercentFrameLayout) findViewById(R.id.remote_video_lay out);
158 callFragment = new CallFragment(); 163 callFragment = new CallFragment();
159 hudFragment = new HudFragment(); 164 hudFragment = new HudFragment();
160 165
161 // Create video renderers.
162 VideoRendererGui.setView(videoView, new Runnable() {
163 @Override
164 public void run() {
165 createPeerConnectionFactory();
166 }
167 });
168 remoteRender = VideoRendererGui.create(
169 REMOTE_X, REMOTE_Y,
170 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
171 localRender = VideoRendererGui.create(
172 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
173 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
174
175 // Show/hide call control fragment on view click. 166 // Show/hide call control fragment on view click.
176 videoView.setOnClickListener(new View.OnClickListener() { 167 View.OnClickListener listener = new View.OnClickListener() {
177 @Override 168 @Override
178 public void onClick(View view) { 169 public void onClick(View view) {
179 toggleCallControlFragmentVisibility(); 170 toggleCallControlFragmentVisibility();
180 } 171 }
181 }); 172 };
173
174 localRender.setOnClickListener(listener);
175 remoteRender.setOnClickListener(listener);
176
177 // Create video renderers.
178 rootEglBase = new EglBase();
179 localRender.init(rootEglBase.getContext(), null);
180 remoteRender.init(rootEglBase.getContext(), null);
181 localRender.setZOrderMediaOverlay(true);
182 updateVideoView();
182 183
183 // Check for mandatory permissions. 184 // Check for mandatory permissions.
184 for (String permission : MANDATORY_PERMISSIONS) { 185 for (String permission : MANDATORY_PERMISSIONS) {
185 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_ GRANTED) { 186 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_ GRANTED) {
186 logAndToast("Permission " + permission + " is not granted"); 187 logAndToast("Permission " + permission + " is not granted");
187 setResult(RESULT_CANCELED); 188 setResult(RESULT_CANCELED);
188 finish(); 189 finish();
189 return; 190 return;
190 } 191 }
191 } 192 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 hudFragment.setArguments(intent.getExtras()); 236 hudFragment.setArguments(intent.getExtras());
236 // Activate call and HUD fragments and start the call. 237 // Activate call and HUD fragments and start the call.
237 FragmentTransaction ft = getFragmentManager().beginTransaction(); 238 FragmentTransaction ft = getFragmentManager().beginTransaction();
238 ft.add(R.id.call_fragment_container, callFragment); 239 ft.add(R.id.call_fragment_container, callFragment);
239 ft.add(R.id.hud_fragment_container, hudFragment); 240 ft.add(R.id.hud_fragment_container, hudFragment);
240 ft.commit(); 241 ft.commit();
241 startCall(); 242 startCall();
242 243
243 // For command line execution run connection for <runTimeMs> and exit. 244 // For command line execution run connection for <runTimeMs> and exit.
244 if (commandLineRun && runTimeMs > 0) { 245 if (commandLineRun && runTimeMs > 0) {
245 videoView.postDelayed(new Runnable() { 246 (new Handler()).postDelayed(new Runnable() {
246 public void run() { 247 public void run() {
247 disconnect(); 248 disconnect();
248 } 249 }
249 }, runTimeMs); 250 }, runTimeMs);
250 } 251 }
252
253 peerConnectionClient = PeerConnectionClient.getInstance();
254 peerConnectionClient.createPeerConnectionFactory(
255 CallActivity.this, peerConnectionParameters, CallActivity.this);
251 } 256 }
252 257
253 // Activity interfaces 258 // Activity interfaces
254 @Override 259 @Override
255 public void onPause() { 260 public void onPause() {
256 super.onPause(); 261 super.onPause();
257 videoView.onPause();
258 activityRunning = false; 262 activityRunning = false;
259 if (peerConnectionClient != null) { 263 if (peerConnectionClient != null) {
260 peerConnectionClient.stopVideoSource(); 264 peerConnectionClient.stopVideoSource();
261 } 265 }
262 } 266 }
263 267
264 @Override 268 @Override
265 public void onResume() { 269 public void onResume() {
266 super.onResume(); 270 super.onResume();
267 videoView.onResume();
268 activityRunning = true; 271 activityRunning = true;
269 if (peerConnectionClient != null) { 272 if (peerConnectionClient != null) {
270 peerConnectionClient.startVideoSource(); 273 peerConnectionClient.startVideoSource();
271 } 274 }
272 } 275 }
273 276
274 @Override 277 @Override
275 protected void onDestroy() { 278 protected void onDestroy() {
276 disconnect(); 279 disconnect();
277 super.onDestroy();
278 if (logToast != null) { 280 if (logToast != null) {
279 logToast.cancel(); 281 logToast.cancel();
280 } 282 }
281 activityRunning = false; 283 activityRunning = false;
282 VideoRendererGui.dispose(); 284 rootEglBase.release();
285 super.onDestroy();
283 } 286 }
284 287
285 // CallFragment.OnCallEvents interface implementation. 288 // CallFragment.OnCallEvents interface implementation.
286 @Override 289 @Override
287 public void onCallHangUp() { 290 public void onCallHangUp() {
288 disconnect(); 291 disconnect();
289 } 292 }
290 293
291 @Override 294 @Override
292 public void onCameraSwitch() { 295 public void onCameraSwitch() {
(...skipping 21 matching lines...) Expand all
314 ft.show(hudFragment); 317 ft.show(hudFragment);
315 } else { 318 } else {
316 ft.hide(callFragment); 319 ft.hide(callFragment);
317 ft.hide(hudFragment); 320 ft.hide(hudFragment);
318 } 321 }
319 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 322 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
320 ft.commit(); 323 ft.commit();
321 } 324 }
322 325
323 private void updateVideoView() { 326 private void updateVideoView() {
324 VideoRendererGui.update(remoteRender, 327 remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIG HT);
325 REMOTE_X, REMOTE_Y, 328 remoteRender.setScalingType(scalingType);
326 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false); 329 remoteRender.setMirror(false);
330
327 if (iceConnected) { 331 if (iceConnected) {
328 VideoRendererGui.update(localRender, 332 localRenderLayout.setPosition(
329 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, 333 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEI GHT_CONNECTED);
330 LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, 334 localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT);
331 ScalingType.SCALE_ASPECT_FIT, true);
332 } else { 335 } else {
333 VideoRendererGui.update(localRender, 336 localRenderLayout.setPosition(
334 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, 337 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_ HEIGHT_CONNECTING);
335 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true); 338 localRender.setScalingType(scalingType);
336 } 339 }
340 localRender.setMirror(true);
341
342 localRender.requestLayout();
343 remoteRender.requestLayout();
337 } 344 }
338 345
339 private void startCall() { 346 private void startCall() {
340 if (appRtcClient == null) { 347 if (appRtcClient == null) {
341 Log.e(TAG, "AppRTC client is not allocated for a call."); 348 Log.e(TAG, "AppRTC client is not allocated for a call.");
342 return; 349 return;
343 } 350 }
344 callStartedTimeMs = System.currentTimeMillis(); 351 callStartedTimeMs = System.currentTimeMillis();
345 352
346 // Start room connection. 353 // Start room connection.
(...skipping 30 matching lines...) Expand all
377 updateVideoView(); 384 updateVideoView();
378 // Enable statistics callback. 385 // Enable statistics callback.
379 peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD); 386 peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
380 } 387 }
381 388
382 private void onAudioManagerChangedState() { 389 private void onAudioManagerChangedState() {
383 // TODO(henrika): disable video if AppRTCAudioManager.AudioDevice.EARPIECE 390 // TODO(henrika): disable video if AppRTCAudioManager.AudioDevice.EARPIECE
384 // is active. 391 // is active.
385 } 392 }
386 393
387 // Create peer connection factory when EGL context is ready.
388 private void createPeerConnectionFactory() {
389 runOnUiThread(new Runnable() {
390 @Override
391 public void run() {
392 if (peerConnectionClient == null) {
393 final long delta = System.currentTimeMillis() - callStartedTimeMs;
394 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms");
395 peerConnectionClient = PeerConnectionClient.getInstance();
396 peerConnectionClient.createPeerConnectionFactory(CallActivity.this,
397 peerConnectionParameters, CallActivity.this);
398 }
399 if (signalingParameters != null) {
400 Log.w(TAG, "EGL context is ready after room connection.");
401 onConnectedToRoomInternal(signalingParameters);
402 }
403 }
404 });
405 }
406
407 // Disconnect from remote resources, dispose of local resources, and exit. 394 // Disconnect from remote resources, dispose of local resources, and exit.
408 private void disconnect() { 395 private void disconnect() {
409 activityRunning = false; 396 activityRunning = false;
410 if (appRtcClient != null) { 397 if (appRtcClient != null) {
411 appRtcClient.disconnectFromRoom(); 398 appRtcClient.disconnectFromRoom();
412 appRtcClient = null; 399 appRtcClient = null;
413 } 400 }
414 if (peerConnectionClient != null) { 401 if (peerConnectionClient != null) {
415 peerConnectionClient.close(); 402 peerConnectionClient.close();
416 peerConnectionClient = null; 403 peerConnectionClient = null;
417 } 404 }
405 if (localRender != null) {
406 localRender.release();
407 localRender = null;
408 }
409 if (remoteRender != null) {
410 remoteRender.release();
411 remoteRender = null;
412 }
418 if (audioManager != null) { 413 if (audioManager != null) {
419 audioManager.close(); 414 audioManager.close();
420 audioManager = null; 415 audioManager = null;
421 } 416 }
422 if (iceConnected && !isError) { 417 if (iceConnected && !isError) {
423 setResult(RESULT_OK); 418 setResult(RESULT_OK);
424 } else { 419 } else {
425 setResult(RESULT_CANCELED); 420 setResult(RESULT_CANCELED);
426 } 421 }
427 finish(); 422 finish();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 }); 463 });
469 } 464 }
470 465
471 // -----Implementation of AppRTCClient.AppRTCSignalingEvents --------------- 466 // -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
472 // All callbacks are invoked from websocket signaling looper thread and 467 // All callbacks are invoked from websocket signaling looper thread and
473 // are routed to UI thread. 468 // are routed to UI thread.
474 private void onConnectedToRoomInternal(final SignalingParameters params) { 469 private void onConnectedToRoomInternal(final SignalingParameters params) {
475 final long delta = System.currentTimeMillis() - callStartedTimeMs; 470 final long delta = System.currentTimeMillis() - callStartedTimeMs;
476 471
477 signalingParameters = params; 472 signalingParameters = params;
478 if (peerConnectionClient == null) {
479 Log.w(TAG, "Room is connected, but EGL context is not ready yet.");
480 return;
481 }
482 logAndToast("Creating peer connection, delay=" + delta + "ms"); 473 logAndToast("Creating peer connection, delay=" + delta + "ms");
483 peerConnectionClient.createPeerConnection(VideoRendererGui.getEGLContext(), 474 peerConnectionClient.createPeerConnection(rootEglBase.getContext(),
484 localRender, remoteRender, signalingParameters); 475 localRender, remoteRender, signalingParameters);
485 476
486 if (signalingParameters.initiator) { 477 if (signalingParameters.initiator) {
487 logAndToast("Creating OFFER..."); 478 logAndToast("Creating OFFER...");
488 // Create offer. Offer SDP will be sent to answering client in 479 // Create offer. Offer SDP will be sent to answering client in
489 // PeerConnectionEvents.onLocalDescription event. 480 // PeerConnectionEvents.onLocalDescription event.
490 peerConnectionClient.createOffer(); 481 peerConnectionClient.createOffer();
491 } else { 482 } else {
492 if (params.offerSdp != null) { 483 if (params.offerSdp != null) {
493 peerConnectionClient.setRemoteDescription(params.offerSdp); 484 peerConnectionClient.setRemoteDescription(params.offerSdp);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 } 632 }
642 } 633 }
643 }); 634 });
644 } 635 }
645 636
646 @Override 637 @Override
647 public void onPeerConnectionError(final String description) { 638 public void onPeerConnectionError(final String description) {
648 reportError(description); 639 reportError(description);
649 } 640 }
650 } 641 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698