OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 import android.app.Activity; | 35 import android.app.Activity; |
36 import android.app.AlertDialog; | 36 import android.app.AlertDialog; |
37 import android.app.FragmentTransaction; | 37 import android.app.FragmentTransaction; |
38 import android.content.DialogInterface; | 38 import android.content.DialogInterface; |
39 import android.content.Intent; | 39 import android.content.Intent; |
40 import android.content.pm.PackageManager; | 40 import android.content.pm.PackageManager; |
41 import android.net.Uri; | 41 import android.net.Uri; |
42 import android.opengl.GLSurfaceView; | 42 import android.opengl.GLSurfaceView; |
43 import android.os.Bundle; | 43 import android.os.Bundle; |
| 44 import android.os.Handler; |
44 import android.util.Log; | 45 import android.util.Log; |
45 import android.view.View; | 46 import android.view.View; |
46 import android.view.Window; | 47 import android.view.Window; |
47 import android.view.WindowManager.LayoutParams; | 48 import android.view.WindowManager.LayoutParams; |
48 import android.widget.Toast; | 49 import android.widget.Toast; |
49 | 50 |
| 51 import org.webrtc.EglBase; |
50 import org.webrtc.IceCandidate; | 52 import org.webrtc.IceCandidate; |
51 import org.webrtc.SessionDescription; | 53 import org.webrtc.SessionDescription; |
52 import org.webrtc.StatsReport; | 54 import org.webrtc.StatsReport; |
53 import org.webrtc.VideoRenderer; | 55 import org.webrtc.SurfaceViewRenderer; |
54 import org.webrtc.VideoRendererGui; | |
55 import org.webrtc.VideoRendererGui.ScalingType; | 56 import org.webrtc.VideoRendererGui.ScalingType; |
56 | 57 |
57 /** | 58 /** |
58 * Activity for peer connection call setup, call waiting | 59 * Activity for peer connection call setup, call waiting |
59 * and call view. | 60 * and call view. |
60 */ | 61 */ |
61 public class CallActivity extends Activity | 62 public class CallActivity extends Activity |
62 implements AppRTCClient.SignalingEvents, | 63 implements AppRTCClient.SignalingEvents, |
63 PeerConnectionClient.PeerConnectionEvents, | 64 PeerConnectionClient.PeerConnectionEvents, |
64 CallFragment.OnCallEvents { | 65 CallFragment.OnCallEvents { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // Remote video screen position | 120 // Remote video screen position |
120 private static final int REMOTE_X = 0; | 121 private static final int REMOTE_X = 0; |
121 private static final int REMOTE_Y = 0; | 122 private static final int REMOTE_Y = 0; |
122 private static final int REMOTE_WIDTH = 100; | 123 private static final int REMOTE_WIDTH = 100; |
123 private static final int REMOTE_HEIGHT = 100; | 124 private static final int REMOTE_HEIGHT = 100; |
124 | 125 |
125 private PeerConnectionClient peerConnectionClient = null; | 126 private PeerConnectionClient peerConnectionClient = null; |
126 private AppRTCClient appRtcClient; | 127 private AppRTCClient appRtcClient; |
127 private SignalingParameters signalingParameters; | 128 private SignalingParameters signalingParameters; |
128 private AppRTCAudioManager audioManager = null; | 129 private AppRTCAudioManager audioManager = null; |
129 private VideoRenderer.Callbacks localRender; | 130 private EglBase rootEglBase; |
130 private VideoRenderer.Callbacks remoteRender; | 131 private SurfaceViewRenderer localRender; |
| 132 private SurfaceViewRenderer remoteRender; |
| 133 private PercentFrameLayout localRenderLayout; |
| 134 private PercentFrameLayout remoteRenderLayout; |
131 private ScalingType scalingType; | 135 private ScalingType scalingType; |
132 private Toast logToast; | 136 private Toast logToast; |
133 private boolean commandLineRun; | 137 private boolean commandLineRun; |
134 private int runTimeMs; | 138 private int runTimeMs; |
135 private boolean activityRunning; | 139 private boolean activityRunning; |
136 private RoomConnectionParameters roomConnectionParameters; | 140 private RoomConnectionParameters roomConnectionParameters; |
137 private PeerConnectionParameters peerConnectionParameters; | 141 private PeerConnectionParameters peerConnectionParameters; |
138 private boolean iceConnected; | 142 private boolean iceConnected; |
139 private boolean isError; | 143 private boolean isError; |
140 private boolean callControlFragmentVisible = true; | 144 private boolean callControlFragmentVisible = true; |
141 private long callStartedTimeMs = 0; | 145 private long callStartedTimeMs = 0; |
142 | 146 |
143 // Controls | 147 // Controls |
144 private GLSurfaceView videoView; | |
145 CallFragment callFragment; | 148 CallFragment callFragment; |
146 HudFragment hudFragment; | 149 HudFragment hudFragment; |
147 | 150 |
148 @Override | 151 @Override |
149 public void onCreate(Bundle savedInstanceState) { | 152 public void onCreate(Bundle savedInstanceState) { |
150 super.onCreate(savedInstanceState); | 153 super.onCreate(savedInstanceState); |
151 Thread.setDefaultUncaughtExceptionHandler( | 154 Thread.setDefaultUncaughtExceptionHandler( |
152 new UnhandledExceptionHandler(this)); | 155 new UnhandledExceptionHandler(this)); |
153 | 156 |
154 // Set window styles for fullscreen-window size. Needs to be done before | 157 // Set window styles for fullscreen-window size. Needs to be done before |
155 // adding content. | 158 // adding content. |
156 requestWindowFeature(Window.FEATURE_NO_TITLE); | 159 requestWindowFeature(Window.FEATURE_NO_TITLE); |
157 getWindow().addFlags( | 160 getWindow().addFlags( |
158 LayoutParams.FLAG_FULLSCREEN | 161 LayoutParams.FLAG_FULLSCREEN |
159 | LayoutParams.FLAG_KEEP_SCREEN_ON | 162 | LayoutParams.FLAG_KEEP_SCREEN_ON |
160 | LayoutParams.FLAG_DISMISS_KEYGUARD | 163 | LayoutParams.FLAG_DISMISS_KEYGUARD |
161 | LayoutParams.FLAG_SHOW_WHEN_LOCKED | 164 | LayoutParams.FLAG_SHOW_WHEN_LOCKED |
162 | LayoutParams.FLAG_TURN_SCREEN_ON); | 165 | LayoutParams.FLAG_TURN_SCREEN_ON); |
163 getWindow().getDecorView().setSystemUiVisibility( | 166 getWindow().getDecorView().setSystemUiVisibility( |
164 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 167 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
165 | View.SYSTEM_UI_FLAG_FULLSCREEN | 168 | View.SYSTEM_UI_FLAG_FULLSCREEN |
166 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); | 169 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); |
167 setContentView(R.layout.activity_call); | 170 setContentView(R.layout.activity_call); |
168 | 171 |
169 iceConnected = false; | 172 iceConnected = false; |
170 signalingParameters = null; | 173 signalingParameters = null; |
171 scalingType = ScalingType.SCALE_ASPECT_FILL; | 174 scalingType = ScalingType.SCALE_ASPECT_FILL; |
172 | 175 |
173 // Create UI controls. | 176 // Create UI controls. |
174 videoView = (GLSurfaceView) findViewById(R.id.glview_call); | 177 localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view); |
| 178 remoteRender = (SurfaceViewRenderer) findViewById(R.id.remote_video_view); |
| 179 localRenderLayout = (PercentFrameLayout) findViewById(R.id.local_video_layou
t); |
| 180 remoteRenderLayout = (PercentFrameLayout) findViewById(R.id.remote_video_lay
out); |
175 callFragment = new CallFragment(); | 181 callFragment = new CallFragment(); |
176 hudFragment = new HudFragment(); | 182 hudFragment = new HudFragment(); |
177 | 183 |
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. | 184 // Show/hide call control fragment on view click. |
193 videoView.setOnClickListener(new View.OnClickListener() { | 185 View.OnClickListener listener = new View.OnClickListener() { |
194 @Override | 186 @Override |
195 public void onClick(View view) { | 187 public void onClick(View view) { |
196 toggleCallControlFragmentVisibility(); | 188 toggleCallControlFragmentVisibility(); |
197 } | 189 } |
198 }); | 190 }; |
| 191 localRender.setOnClickListener(listener); |
| 192 remoteRender.setOnClickListener(listener); |
| 193 |
| 194 // Create video renderers. |
| 195 rootEglBase = new EglBase(); |
| 196 localRender.init(rootEglBase.getContext()); |
| 197 remoteRender.init(rootEglBase.getContext()); |
| 198 localRender.setZOrderMediaOverlay(true); |
| 199 updateVideoView(); |
199 | 200 |
200 // Check for mandatory permissions. | 201 // Check for mandatory permissions. |
201 for (String permission : MANDATORY_PERMISSIONS) { | 202 for (String permission : MANDATORY_PERMISSIONS) { |
202 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_
GRANTED) { | 203 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_
GRANTED) { |
203 logAndToast("Permission " + permission + " is not granted"); | 204 logAndToast("Permission " + permission + " is not granted"); |
204 setResult(RESULT_CANCELED); | 205 setResult(RESULT_CANCELED); |
205 finish(); | 206 finish(); |
206 return; | 207 return; |
207 } | 208 } |
208 } | 209 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 hudFragment.setArguments(intent.getExtras()); | 253 hudFragment.setArguments(intent.getExtras()); |
253 // Activate call and HUD fragments and start the call. | 254 // Activate call and HUD fragments and start the call. |
254 FragmentTransaction ft = getFragmentManager().beginTransaction(); | 255 FragmentTransaction ft = getFragmentManager().beginTransaction(); |
255 ft.add(R.id.call_fragment_container, callFragment); | 256 ft.add(R.id.call_fragment_container, callFragment); |
256 ft.add(R.id.hud_fragment_container, hudFragment); | 257 ft.add(R.id.hud_fragment_container, hudFragment); |
257 ft.commit(); | 258 ft.commit(); |
258 startCall(); | 259 startCall(); |
259 | 260 |
260 // For command line execution run connection for <runTimeMs> and exit. | 261 // For command line execution run connection for <runTimeMs> and exit. |
261 if (commandLineRun && runTimeMs > 0) { | 262 if (commandLineRun && runTimeMs > 0) { |
262 videoView.postDelayed(new Runnable() { | 263 (new Handler()).postDelayed(new Runnable() { |
263 public void run() { | 264 public void run() { |
264 disconnect(); | 265 disconnect(); |
265 } | 266 } |
266 }, runTimeMs); | 267 }, runTimeMs); |
267 } | 268 } |
| 269 createPeerConnectionFactory(); |
268 } | 270 } |
269 | 271 |
270 // Activity interfaces | 272 // Activity interfaces |
271 @Override | 273 @Override |
272 public void onPause() { | 274 public void onPause() { |
273 super.onPause(); | 275 super.onPause(); |
274 videoView.onPause(); | |
275 activityRunning = false; | 276 activityRunning = false; |
276 if (peerConnectionClient != null) { | 277 if (peerConnectionClient != null) { |
277 peerConnectionClient.stopVideoSource(); | 278 peerConnectionClient.stopVideoSource(); |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
281 @Override | 282 @Override |
282 public void onResume() { | 283 public void onResume() { |
283 super.onResume(); | 284 super.onResume(); |
284 videoView.onResume(); | |
285 activityRunning = true; | 285 activityRunning = true; |
286 if (peerConnectionClient != null) { | 286 if (peerConnectionClient != null) { |
287 peerConnectionClient.startVideoSource(); | 287 peerConnectionClient.startVideoSource(); |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 @Override | 291 @Override |
292 protected void onDestroy() { | 292 protected void onDestroy() { |
293 disconnect(); | 293 disconnect(); |
294 super.onDestroy(); | 294 super.onDestroy(); |
295 if (logToast != null) { | 295 if (logToast != null) { |
296 logToast.cancel(); | 296 logToast.cancel(); |
297 } | 297 } |
298 activityRunning = false; | 298 activityRunning = false; |
| 299 localRender.release(); |
| 300 localRender = null; |
| 301 remoteRender.release(); |
| 302 remoteRender = null; |
| 303 rootEglBase.release(); |
| 304 rootEglBase = null; |
299 } | 305 } |
300 | 306 |
301 // CallFragment.OnCallEvents interface implementation. | 307 // CallFragment.OnCallEvents interface implementation. |
302 @Override | 308 @Override |
303 public void onCallHangUp() { | 309 public void onCallHangUp() { |
304 disconnect(); | 310 disconnect(); |
305 } | 311 } |
306 | 312 |
307 @Override | 313 @Override |
308 public void onCameraSwitch() { | 314 public void onCameraSwitch() { |
(...skipping 21 matching lines...) Expand all Loading... |
330 ft.show(hudFragment); | 336 ft.show(hudFragment); |
331 } else { | 337 } else { |
332 ft.hide(callFragment); | 338 ft.hide(callFragment); |
333 ft.hide(hudFragment); | 339 ft.hide(hudFragment); |
334 } | 340 } |
335 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); | 341 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); |
336 ft.commit(); | 342 ft.commit(); |
337 } | 343 } |
338 | 344 |
339 private void updateVideoView() { | 345 private void updateVideoView() { |
340 VideoRendererGui.update(remoteRender, | 346 remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIG
HT); |
341 REMOTE_X, REMOTE_Y, | 347 remoteRender.setScalingType(scalingType); |
342 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false); | 348 remoteRender.setMirror(false); |
| 349 |
343 if (iceConnected) { | 350 if (iceConnected) { |
344 VideoRendererGui.update(localRender, | 351 localRenderLayout.setPosition( |
345 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, | 352 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEI
GHT_CONNECTED); |
346 LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, | 353 localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT); |
347 ScalingType.SCALE_ASPECT_FIT, true); | |
348 } else { | 354 } else { |
349 VideoRendererGui.update(localRender, | 355 localRenderLayout.setPosition( |
350 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, | 356 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_
HEIGHT_CONNECTING); |
351 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true); | 357 localRender.setScalingType(scalingType); |
352 } | 358 } |
| 359 localRender.setMirror(true); |
| 360 |
| 361 localRender.requestLayout(); |
| 362 remoteRender.requestLayout(); |
353 } | 363 } |
354 | 364 |
355 private void startCall() { | 365 private void startCall() { |
356 if (appRtcClient == null) { | 366 if (appRtcClient == null) { |
357 Log.e(TAG, "AppRTC client is not allocated for a call."); | 367 Log.e(TAG, "AppRTC client is not allocated for a call."); |
358 return; | 368 return; |
359 } | 369 } |
360 callStartedTimeMs = System.currentTimeMillis(); | 370 callStartedTimeMs = System.currentTimeMillis(); |
361 | 371 |
362 // Start room connection. | 372 // Start room connection. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 // Create peer connection factory when EGL context is ready. | 410 // Create peer connection factory when EGL context is ready. |
401 private void createPeerConnectionFactory() { | 411 private void createPeerConnectionFactory() { |
402 runOnUiThread(new Runnable() { | 412 runOnUiThread(new Runnable() { |
403 @Override | 413 @Override |
404 public void run() { | 414 public void run() { |
405 if (peerConnectionClient == null) { | 415 if (peerConnectionClient == null) { |
406 final long delta = System.currentTimeMillis() - callStartedTimeMs; | 416 final long delta = System.currentTimeMillis() - callStartedTimeMs; |
407 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms"); | 417 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms"); |
408 peerConnectionClient = PeerConnectionClient.getInstance(); | 418 peerConnectionClient = PeerConnectionClient.getInstance(); |
409 peerConnectionClient.createPeerConnectionFactory(CallActivity.this, | 419 peerConnectionClient.createPeerConnectionFactory(CallActivity.this, |
410 VideoRendererGui.getEGLContext(), peerConnectionParameters, | 420 rootEglBase.getContext(), peerConnectionParameters, |
411 CallActivity.this); | 421 CallActivity.this); |
412 } | 422 } |
413 if (signalingParameters != null) { | 423 if (signalingParameters != null) { |
414 Log.w(TAG, "EGL context is ready after room connection."); | 424 Log.w(TAG, "EGL context is ready after room connection."); |
415 onConnectedToRoomInternal(signalingParameters); | 425 onConnectedToRoomInternal(signalingParameters); |
416 } | 426 } |
417 } | 427 } |
418 }); | 428 }); |
419 } | 429 } |
420 | 430 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 } | 665 } |
656 } | 666 } |
657 }); | 667 }); |
658 } | 668 } |
659 | 669 |
660 @Override | 670 @Override |
661 public void onPeerConnectionError(final String description) { | 671 public void onPeerConnectionError(final String description) { |
662 reportError(description); | 672 reportError(description); |
663 } | 673 } |
664 } | 674 } |
OLD | NEW |