OLD | NEW |
---|---|
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; | |
14 import org.appspot.apprtc.AppRTCClient.SignalingParameters; | |
15 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters; | |
16 | |
17 import android.app.Activity; | 13 import android.app.Activity; |
18 import android.app.AlertDialog; | 14 import android.app.AlertDialog; |
19 import android.app.FragmentTransaction; | 15 import android.app.FragmentTransaction; |
16 import android.content.Context; | |
20 import android.content.DialogInterface; | 17 import android.content.DialogInterface; |
21 import android.content.Intent; | 18 import android.content.Intent; |
22 import android.content.pm.PackageManager; | 19 import android.content.pm.PackageManager; |
20 import android.media.projection.MediaProjection; | |
21 import android.media.projection.MediaProjectionManager; | |
23 import android.net.Uri; | 22 import android.net.Uri; |
24 import android.os.Bundle; | 23 import android.os.Bundle; |
25 import android.os.Handler; | 24 import android.os.Handler; |
26 import android.util.Log; | 25 import android.util.Log; |
27 import android.view.View; | 26 import android.view.View; |
28 import android.view.Window; | 27 import android.view.Window; |
29 import android.view.WindowManager.LayoutParams; | 28 import android.view.WindowManager.LayoutParams; |
30 import android.widget.Toast; | 29 import android.widget.Toast; |
31 | |
32 import java.io.IOException; | 30 import java.io.IOException; |
33 import java.lang.RuntimeException; | 31 import java.lang.RuntimeException; |
34 import java.util.ArrayList; | 32 import java.util.ArrayList; |
35 import java.util.List; | 33 import java.util.List; |
36 | 34 import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters; |
35 import org.appspot.apprtc.AppRTCClient.SignalingParameters; | |
36 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters; | |
37 import org.webrtc.Camera1Enumerator; | 37 import org.webrtc.Camera1Enumerator; |
38 import org.webrtc.Camera2Enumerator; | 38 import org.webrtc.Camera2Enumerator; |
39 import org.webrtc.CameraEnumerator; | 39 import org.webrtc.CameraEnumerator; |
40 import org.webrtc.EglBase; | 40 import org.webrtc.EglBase; |
41 import org.webrtc.FileVideoCapturer; | 41 import org.webrtc.FileVideoCapturer; |
42 import org.webrtc.VideoFileRenderer; | |
43 import org.webrtc.IceCandidate; | 42 import org.webrtc.IceCandidate; |
44 import org.webrtc.Logging; | 43 import org.webrtc.Logging; |
45 import org.webrtc.PeerConnectionFactory; | 44 import org.webrtc.PeerConnectionFactory; |
46 import org.webrtc.RendererCommon.ScalingType; | 45 import org.webrtc.RendererCommon.ScalingType; |
46 import org.webrtc.ScreenCapturerAndroid; | |
47 import org.webrtc.SessionDescription; | 47 import org.webrtc.SessionDescription; |
48 import org.webrtc.StatsReport; | 48 import org.webrtc.StatsReport; |
49 import org.webrtc.SurfaceViewRenderer; | 49 import org.webrtc.SurfaceViewRenderer; |
50 import org.webrtc.VideoCapturer; | 50 import org.webrtc.VideoCapturer; |
51 import org.webrtc.VideoFileRenderer; | |
51 import org.webrtc.VideoRenderer; | 52 import org.webrtc.VideoRenderer; |
52 | 53 |
53 /** | 54 /** |
54 * Activity for peer connection call setup, call waiting | 55 * Activity for peer connection call setup, call waiting |
55 * and call view. | 56 * and call view. |
56 */ | 57 */ |
57 public class CallActivity extends Activity implements AppRTCClient.SignalingEven ts, | 58 public class CallActivity extends Activity implements AppRTCClient.SignalingEven ts, |
58 PeerConnectionClient.PeerC onnectionEvents, | 59 PeerConnectionClient.PeerC onnectionEvents, |
59 CallFragment.OnCallEvents { | 60 CallFragment.OnCallEvents { |
60 public static final String EXTRA_ROOMID = "org.appspot.apprtc.ROOMID"; | 61 public static final String EXTRA_ROOMID = "org.appspot.apprtc.ROOMID"; |
61 public static final String EXTRA_LOOPBACK = "org.appspot.apprtc.LOOPBACK"; | 62 public static final String EXTRA_LOOPBACK = "org.appspot.apprtc.LOOPBACK"; |
62 public static final String EXTRA_VIDEO_CALL = "org.appspot.apprtc.VIDEO_CALL"; | 63 public static final String EXTRA_VIDEO_CALL = "org.appspot.apprtc.VIDEO_CALL"; |
64 public static final String EXTRA_SCREENCAPTURE = "org.appspot.apprtc.SCREENCAP TURE"; | |
63 public static final String EXTRA_CAMERA2 = "org.appspot.apprtc.CAMERA2"; | 65 public static final String EXTRA_CAMERA2 = "org.appspot.apprtc.CAMERA2"; |
64 public static final String EXTRA_VIDEO_WIDTH = "org.appspot.apprtc.VIDEO_WIDTH "; | 66 public static final String EXTRA_VIDEO_WIDTH = "org.appspot.apprtc.VIDEO_WIDTH "; |
65 public static final String EXTRA_VIDEO_HEIGHT = "org.appspot.apprtc.VIDEO_HEIG HT"; | 67 public static final String EXTRA_VIDEO_HEIGHT = "org.appspot.apprtc.VIDEO_HEIG HT"; |
66 public static final String EXTRA_VIDEO_FPS = "org.appspot.apprtc.VIDEO_FPS"; | 68 public static final String EXTRA_VIDEO_FPS = "org.appspot.apprtc.VIDEO_FPS"; |
67 public static final String EXTRA_VIDEO_CAPTUREQUALITYSLIDER_ENABLED = | 69 public static final String EXTRA_VIDEO_CAPTUREQUALITYSLIDER_ENABLED = |
68 "org.appsopt.apprtc.VIDEO_CAPTUREQUALITYSLIDER"; | 70 "org.appsopt.apprtc.VIDEO_CAPTUREQUALITYSLIDER"; |
69 public static final String EXTRA_VIDEO_BITRATE = "org.appspot.apprtc.VIDEO_BIT RATE"; | 71 public static final String EXTRA_VIDEO_BITRATE = "org.appspot.apprtc.VIDEO_BIT RATE"; |
70 public static final String EXTRA_VIDEOCODEC = "org.appspot.apprtc.VIDEOCODEC"; | 72 public static final String EXTRA_VIDEOCODEC = "org.appspot.apprtc.VIDEOCODEC"; |
71 public static final String EXTRA_HWCODEC_ENABLED = "org.appspot.apprtc.HWCODEC "; | 73 public static final String EXTRA_HWCODEC_ENABLED = "org.appspot.apprtc.HWCODEC "; |
72 public static final String EXTRA_CAPTURETOTEXTURE_ENABLED = "org.appspot.apprt c.CAPTURETOTEXTURE"; | 74 public static final String EXTRA_CAPTURETOTEXTURE_ENABLED = "org.appspot.apprt c.CAPTURETOTEXTURE"; |
(...skipping 14 matching lines...) Expand all Loading... | |
87 public static final String EXTRA_VIDEO_FILE_AS_CAMERA = "org.appspot.apprtc.VI DEO_FILE_AS_CAMERA"; | 89 public static final String EXTRA_VIDEO_FILE_AS_CAMERA = "org.appspot.apprtc.VI DEO_FILE_AS_CAMERA"; |
88 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE = | 90 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE = |
89 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE"; | 91 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE"; |
90 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH = | 92 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH = |
91 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_WIDTH"; | 93 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_WIDTH"; |
92 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT = | 94 public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT = |
93 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT"; | 95 "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT"; |
94 public static final String EXTRA_USE_VALUES_FROM_INTENT = | 96 public static final String EXTRA_USE_VALUES_FROM_INTENT = |
95 "org.appspot.apprtc.USE_VALUES_FROM_INTENT"; | 97 "org.appspot.apprtc.USE_VALUES_FROM_INTENT"; |
96 private static final String TAG = "CallRTCClient"; | 98 private static final String TAG = "CallRTCClient"; |
99 private static final int CAPTURE_PERMISSION_REQUEST_CODE = 1; | |
97 | 100 |
98 // List of mandatory application permissions. | 101 // List of mandatory application permissions. |
99 private static final String[] MANDATORY_PERMISSIONS = {"android.permission.MOD IFY_AUDIO_SETTINGS", | 102 private static final String[] MANDATORY_PERMISSIONS = {"android.permission.MOD IFY_AUDIO_SETTINGS", |
100 "android.permission.RECORD_AUDIO", "android.permission.INTERNET"}; | 103 "android.permission.RECORD_AUDIO", "android.permission.INTERNET"}; |
101 | 104 |
102 // Peer connection statistics callback period in ms. | 105 // Peer connection statistics callback period in ms. |
103 private static final int STAT_CALLBACK_PERIOD = 1000; | 106 private static final int STAT_CALLBACK_PERIOD = 1000; |
104 // Local preview screen position before call is connected. | 107 // Local preview screen position before call is connected. |
105 private static final int LOCAL_X_CONNECTING = 0; | 108 private static final int LOCAL_X_CONNECTING = 0; |
106 private static final int LOCAL_Y_CONNECTING = 0; | 109 private static final int LOCAL_Y_CONNECTING = 0; |
(...skipping 26 matching lines...) Expand all Loading... | |
133 private boolean commandLineRun; | 136 private boolean commandLineRun; |
134 private int runTimeMs; | 137 private int runTimeMs; |
135 private boolean activityRunning; | 138 private boolean activityRunning; |
136 private RoomConnectionParameters roomConnectionParameters; | 139 private RoomConnectionParameters roomConnectionParameters; |
137 private PeerConnectionParameters peerConnectionParameters; | 140 private PeerConnectionParameters peerConnectionParameters; |
138 private boolean iceConnected; | 141 private boolean iceConnected; |
139 private boolean isError; | 142 private boolean isError; |
140 private boolean callControlFragmentVisible = true; | 143 private boolean callControlFragmentVisible = true; |
141 private long callStartedTimeMs = 0; | 144 private long callStartedTimeMs = 0; |
142 private boolean micEnabled = true; | 145 private boolean micEnabled = true; |
146 private boolean screencaptureEnabled = false; | |
147 private static Intent mediaProjectionPermissionResultData; | |
148 private static int mediaProjectionPermissionResultCode; | |
143 | 149 |
144 // Controls | 150 // Controls |
145 private CallFragment callFragment; | 151 private CallFragment callFragment; |
146 private HudFragment hudFragment; | 152 private HudFragment hudFragment; |
147 private CpuMonitor cpuMonitor; | 153 private CpuMonitor cpuMonitor; |
148 | 154 |
149 @Override | 155 @Override |
150 public void onCreate(Bundle savedInstanceState) { | 156 public void onCreate(Bundle savedInstanceState) { |
151 super.onCreate(savedInstanceState); | 157 super.onCreate(savedInstanceState); |
152 Thread.setDefaultUncaughtExceptionHandler(new UnhandledExceptionHandler(this )); | 158 Thread.setDefaultUncaughtExceptionHandler(new UnhandledExceptionHandler(this )); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 hudFragment.setCpuMonitor(cpuMonitor); | 284 hudFragment.setCpuMonitor(cpuMonitor); |
279 | 285 |
280 // Send intent arguments to fragments. | 286 // Send intent arguments to fragments. |
281 callFragment.setArguments(intent.getExtras()); | 287 callFragment.setArguments(intent.getExtras()); |
282 hudFragment.setArguments(intent.getExtras()); | 288 hudFragment.setArguments(intent.getExtras()); |
283 // Activate call and HUD fragments and start the call. | 289 // Activate call and HUD fragments and start the call. |
284 FragmentTransaction ft = getFragmentManager().beginTransaction(); | 290 FragmentTransaction ft = getFragmentManager().beginTransaction(); |
285 ft.add(R.id.call_fragment_container, callFragment); | 291 ft.add(R.id.call_fragment_container, callFragment); |
286 ft.add(R.id.hud_fragment_container, hudFragment); | 292 ft.add(R.id.hud_fragment_container, hudFragment); |
287 ft.commit(); | 293 ft.commit(); |
288 startCall(); | |
289 | 294 |
290 // For command line execution run connection for <runTimeMs> and exit. | 295 // For command line execution run connection for <runTimeMs> and exit. |
291 if (commandLineRun && runTimeMs > 0) { | 296 if (commandLineRun && runTimeMs > 0) { |
292 (new Handler()).postDelayed(new Runnable() { | 297 (new Handler()).postDelayed(new Runnable() { |
293 @Override | 298 @Override |
294 public void run() { | 299 public void run() { |
295 disconnect(); | 300 disconnect(); |
296 } | 301 } |
297 }, runTimeMs); | 302 }, runTimeMs); |
298 } | 303 } |
299 | 304 |
300 peerConnectionClient = PeerConnectionClient.getInstance(); | 305 peerConnectionClient = PeerConnectionClient.getInstance(); |
301 if (loopback) { | 306 if (loopback) { |
302 PeerConnectionFactory.Options options = new PeerConnectionFactory.Options( ); | 307 PeerConnectionFactory.Options options = new PeerConnectionFactory.Options( ); |
303 options.networkIgnoreMask = 0; | 308 options.networkIgnoreMask = 0; |
304 peerConnectionClient.setPeerConnectionFactoryOptions(options); | 309 peerConnectionClient.setPeerConnectionFactoryOptions(options); |
305 } | 310 } |
306 peerConnectionClient.createPeerConnectionFactory( | 311 peerConnectionClient.createPeerConnectionFactory( |
307 CallActivity.this, peerConnectionParameters, CallActivity.this); | 312 CallActivity.this, peerConnectionParameters, CallActivity.this); |
313 | |
314 screencaptureEnabled = intent.getBooleanExtra(EXTRA_SCREENCAPTURE, false); | |
315 if (screencaptureEnabled) { | |
316 MediaProjectionManager mediaProjectionManager = | |
317 (MediaProjectionManager) getApplication().getSystemService( | |
318 Context.MEDIA_PROJECTION_SERVICE); | |
319 startActivityForResult( | |
320 mediaProjectionManager.createScreenCaptureIntent(), CAPTURE_PERMISSION _REQUEST_CODE); | |
321 } else { | |
322 startCall(); | |
323 } | |
324 } | |
325 | |
326 @Override | |
327 public void onActivityResult(int requestCode, int resultCode, Intent data) { | |
328 if (requestCode != CAPTURE_PERMISSION_REQUEST_CODE) | |
329 return; | |
330 mediaProjectionPermissionResultCode = resultCode; | |
331 mediaProjectionPermissionResultData = data; | |
332 startCall(); | |
308 } | 333 } |
309 | 334 |
310 private boolean useCamera2() { | 335 private boolean useCamera2() { |
311 return Camera2Enumerator.isSupported(this) && getIntent().getBooleanExtra(EX TRA_CAMERA2, true); | 336 return Camera2Enumerator.isSupported(this) && getIntent().getBooleanExtra(EX TRA_CAMERA2, true); |
312 } | 337 } |
313 | 338 |
314 private boolean captureToTexture() { | 339 private boolean captureToTexture() { |
315 return getIntent().getBooleanExtra(EXTRA_CAPTURETOTEXTURE_ENABLED, false); | 340 return getIntent().getBooleanExtra(EXTRA_CAPTURETOTEXTURE_ENABLED, false); |
316 } | 341 } |
317 | 342 |
(...skipping 27 matching lines...) Expand all Loading... | |
345 } | 370 } |
346 | 371 |
347 return null; | 372 return null; |
348 } | 373 } |
349 | 374 |
350 // Activity interfaces | 375 // Activity interfaces |
351 @Override | 376 @Override |
352 public void onPause() { | 377 public void onPause() { |
353 super.onPause(); | 378 super.onPause(); |
354 activityRunning = false; | 379 activityRunning = false; |
355 if (peerConnectionClient != null) { | 380 if (peerConnectionClient != null && !screencaptureEnabled) { |
magjed_webrtc
2016/11/09 09:07:53
Comment why we do this, e.g. to allow the user to
sakal
2016/11/09 14:56:00
Done.
| |
356 peerConnectionClient.stopVideoSource(); | 381 peerConnectionClient.stopVideoSource(); |
357 } | 382 } |
358 cpuMonitor.pause(); | 383 cpuMonitor.pause(); |
359 } | 384 } |
360 | 385 |
361 @Override | 386 @Override |
362 public void onResume() { | 387 public void onResume() { |
363 super.onResume(); | 388 super.onResume(); |
364 activityRunning = true; | 389 activityRunning = true; |
365 if (peerConnectionClient != null) { | 390 if (peerConnectionClient != null && !screencaptureEnabled) { |
366 peerConnectionClient.startVideoSource(); | 391 peerConnectionClient.startVideoSource(); |
367 } | 392 } |
368 cpuMonitor.resume(); | 393 cpuMonitor.resume(); |
369 } | 394 } |
370 | 395 |
371 @Override | 396 @Override |
372 protected void onDestroy() { | 397 protected void onDestroy() { |
373 disconnect(); | 398 disconnect(); |
374 if (logToast != null) { | 399 if (logToast != null) { |
375 logToast.cancel(); | 400 logToast.cancel(); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 private VideoCapturer createVideoCapturer() { | 606 private VideoCapturer createVideoCapturer() { |
582 VideoCapturer videoCapturer = null; | 607 VideoCapturer videoCapturer = null; |
583 String videoFileAsCamera = getIntent().getStringExtra(EXTRA_VIDEO_FILE_AS_CA MERA); | 608 String videoFileAsCamera = getIntent().getStringExtra(EXTRA_VIDEO_FILE_AS_CA MERA); |
584 if (videoFileAsCamera != null) { | 609 if (videoFileAsCamera != null) { |
585 try { | 610 try { |
586 videoCapturer = new FileVideoCapturer(videoFileAsCamera); | 611 videoCapturer = new FileVideoCapturer(videoFileAsCamera); |
587 } catch (IOException e) { | 612 } catch (IOException e) { |
588 reportError("Failed to open video file for emulated camera"); | 613 reportError("Failed to open video file for emulated camera"); |
589 return null; | 614 return null; |
590 } | 615 } |
616 } else if (screencaptureEnabled) { | |
617 if (mediaProjectionPermissionResultCode != Activity.RESULT_OK) { | |
618 reportError("User didn't give permission to capture the screen."); | |
619 return null; | |
620 } | |
621 return new ScreenCapturerAndroid( | |
622 mediaProjectionPermissionResultData, new MediaProjection.Callback() { | |
623 @Override | |
624 public void onStop() { | |
625 reportError("User revoked permission to capture the screen."); | |
626 } | |
627 }); | |
591 } else if (useCamera2()) { | 628 } else if (useCamera2()) { |
592 if (!captureToTexture()) { | 629 if (!captureToTexture()) { |
593 reportError(getString(R.string.camera2_texture_only_error)); | 630 reportError(getString(R.string.camera2_texture_only_error)); |
594 return null; | 631 return null; |
595 } | 632 } |
596 | 633 |
597 Logging.d(TAG, "Creating capturer using camera2 API."); | 634 Logging.d(TAG, "Creating capturer using camera2 API."); |
598 videoCapturer = createCameraCapturer(new Camera2Enumerator(this)); | 635 videoCapturer = createCameraCapturer(new Camera2Enumerator(this)); |
599 } else { | 636 } else { |
600 Logging.d(TAG, "Creating capturer using camera1 API."); | 637 Logging.d(TAG, "Creating capturer using camera1 API."); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
808 } | 845 } |
809 } | 846 } |
810 }); | 847 }); |
811 } | 848 } |
812 | 849 |
813 @Override | 850 @Override |
814 public void onPeerConnectionError(final String description) { | 851 public void onPeerConnectionError(final String description) { |
815 reportError(description); | 852 reportError(description); |
816 } | 853 } |
817 } | 854 } |
OLD | NEW |