diff --git a/webrtc/examples/BUILD.gn b/webrtc/examples/BUILD.gn index d8e2545816..a33ecc70b0 100644 --- a/webrtc/examples/BUILD.gn +++ b/webrtc/examples/BUILD.gn @@ -129,7 +129,7 @@ if (is_android) { apk_name = "AppRTCMobileTestStubbedVideoIO" android_manifest = "androidtests/AndroidManifest.xml" - java_files = [ "androidtests/src/org/appspot/apprtc/test/ConnectActivityStubbedInputOutputTest.java" ] + java_files = [ "androidtests/src/org/appspot/apprtc/test/CallActivityStubbedInputOutputTest.java" ] apk_under_test = ":AppRTCMobile" diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCClient.java index 72a449bb44..5487fbabf8 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCClient.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCClient.java @@ -27,10 +27,16 @@ public interface AppRTCClient { public final String roomUrl; public final String roomId; public final boolean loopback; - public RoomConnectionParameters(String roomUrl, String roomId, boolean loopback) { + public final String urlParameters; + public RoomConnectionParameters( + String roomUrl, String roomId, boolean loopback, String urlParameters) { this.roomUrl = roomUrl; this.roomId = roomId; this.loopback = loopback; + this.urlParameters = urlParameters; + } + public RoomConnectionParameters(String roomUrl, String roomId, boolean loopback) { + this(roomUrl, roomId, loopback, null /* urlParameters */); } } diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java index 0197bcb322..3869e0b0fa 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java @@ -81,6 +81,7 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven } public static final String EXTRA_ROOMID = "org.appspot.apprtc.ROOMID"; + public static final String EXTRA_URLPARAMETERS = "org.appspot.apprtc.URLPARAMETERS"; public static final String EXTRA_LOOPBACK = "org.appspot.apprtc.LOOPBACK"; public static final String EXTRA_VIDEO_CALL = "org.appspot.apprtc.VIDEO_CALL"; public static final String EXTRA_SCREENCAPTURE = "org.appspot.apprtc.SCREENCAPTURE"; @@ -337,7 +338,9 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven appRtcClient = new DirectRTCClient(this); } // Create connection parameters. - roomConnectionParameters = new RoomConnectionParameters(roomUri.toString(), roomId, loopback); + String urlParameters = intent.getStringExtra(EXTRA_URLPARAMETERS); + roomConnectionParameters = + new RoomConnectionParameters(roomUri.toString(), roomId, loopback, urlParameters); // Create CPU monitor cpuMonitor = new CpuMonitor(this); diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/RoomParametersFetcher.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/RoomParametersFetcher.java index f79154c29f..7d921c0d7d 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/RoomParametersFetcher.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/RoomParametersFetcher.java @@ -139,7 +139,7 @@ public class RoomParametersFetcher { } } // Request TURN servers. - if (!isTurnPresent) { + if (!isTurnPresent && roomJson.has("ice_server_url")) { LinkedList turnServers = requestTurnServers(roomJson.getString("ice_server_url")); for (PeerConnection.IceServer turnServer : turnServers) { diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java index 28eef2e51e..5e8380ae0c 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/WebSocketRTCClient.java @@ -131,7 +131,11 @@ public class WebSocketRTCClient implements AppRTCClient, WebSocketChannelEvents // Helper functions to get connection, post message and leave message URLs private String getConnectionUrl(RoomConnectionParameters connectionParameters) { - return connectionParameters.roomUrl + "/" + ROOM_JOIN + "/" + connectionParameters.roomId; + String url = connectionParameters.roomUrl + "/" + ROOM_JOIN + "/" + connectionParameters.roomId; + if (connectionParameters.urlParameters != null) { + url += "?" + connectionParameters.urlParameters; + } + return url; } private String getMessageUrl( diff --git a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/ConnectActivityStubbedInputOutputTest.java b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/CallActivityStubbedInputOutputTest.java similarity index 51% rename from webrtc/examples/androidtests/src/org/appspot/apprtc/test/ConnectActivityStubbedInputOutputTest.java rename to webrtc/examples/androidtests/src/org/appspot/apprtc/test/CallActivityStubbedInputOutputTest.java index ebb445bc79..2e3a239366 100644 --- a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/ConnectActivityStubbedInputOutputTest.java +++ b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/CallActivityStubbedInputOutputTest.java @@ -38,39 +38,41 @@ import org.junit.runner.RunWith; */ @RunWith(AndroidJUnit4.class) @LargeTest -public class ConnectActivityStubbedInputOutputTest { - private static final String TAG = "ConnectActivityStubbedInputOutputTest"; +public class CallActivityStubbedInputOutputTest { + private static final String TAG = "CallActivityStubbedInputOutputTest"; @Rule - public ActivityTestRule rule = - new ActivityTestRule(ConnectActivity.class) { - @Override - protected Intent getActivityIntent() { - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - Intent intent = new Intent("android.intent.action.VIEW", Uri.parse("https://appr.tc"), - context, ConnectActivity.class); + public ActivityTestRule rule = new ActivityTestRule( + CallActivity.class) { + @Override + protected Intent getActivityIntent() { + Context context = InstrumentationRegistry.getContext(); + Intent intent = new Intent("android.intent.action.VIEW", Uri.parse("http://localhost:9999")); - intent.putExtra(CallActivity.EXTRA_USE_VALUES_FROM_INTENT, true); + intent.putExtra(CallActivity.EXTRA_USE_VALUES_FROM_INTENT, true); - intent.putExtra(CallActivity.EXTRA_LOOPBACK, true); - intent.putExtra(CallActivity.EXTRA_AUDIOCODEC, "OPUS"); - intent.putExtra(CallActivity.EXTRA_VIDEOCODEC, "VP8"); - intent.putExtra(CallActivity.EXTRA_CAPTURETOTEXTURE_ENABLED, false); - intent.putExtra(CallActivity.EXTRA_CAMERA2, false); - intent.putExtra(CallActivity.EXTRA_ROOMID, UUID.randomUUID().toString().substring(0, 8)); + intent.putExtra(CallActivity.EXTRA_LOOPBACK, true); + intent.putExtra(CallActivity.EXTRA_AUDIOCODEC, "OPUS"); + intent.putExtra(CallActivity.EXTRA_VIDEOCODEC, "VP8"); + intent.putExtra(CallActivity.EXTRA_CAPTURETOTEXTURE_ENABLED, false); + intent.putExtra(CallActivity.EXTRA_CAMERA2, false); + intent.putExtra(CallActivity.EXTRA_ROOMID, UUID.randomUUID().toString().substring(0, 8)); + // TODO false for wstls to disable https, should be option later or if URL is http + intent.putExtra(CallActivity.EXTRA_URLPARAMETERS, + "wstls=false?debug=loopback?ts=?wshpp=http://localhost:8089"); - intent.putExtra(CallActivity.EXTRA_VIDEO_FILE_AS_CAMERA, - Environment.getExternalStorageDirectory().getAbsolutePath() - + "/chromium_tests_root/resources/reference_video_640x360_30fps.y4m"); + intent.putExtra(CallActivity.EXTRA_VIDEO_FILE_AS_CAMERA, + Environment.getExternalStorageDirectory().getAbsolutePath() + + "/chromium_tests_root/resources/reference_video_640x360_30fps.y4m"); - intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE, - Environment.getExternalStorageDirectory().getAbsolutePath() + "/output.y4m"); - intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH, 640); - intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT, 360); + intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE, + Environment.getExternalStorageDirectory().getAbsolutePath() + "/output.y4m"); + intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH, 640); + intent.putExtra(CallActivity.EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT, 360); - return intent; - } - }; + return intent; + } + }; @Test public void testLoopback() throws InterruptedException { @@ -78,7 +80,7 @@ public class ConnectActivityStubbedInputOutputTest { IdlingPolicies.setMasterPolicyTimeout(240000, TimeUnit.MILLISECONDS); // During the time we sleep it will record video. - Thread.sleep(10000); + Thread.sleep(8000); // Click on hang-up button. onView(withId(R.id.button_call_disconnect)).perform(click()); diff --git a/webrtc/examples/androidtests/video_quality_loopback_test.py b/webrtc/examples/androidtests/video_quality_loopback_test.py index 7c7ef313f9..a62d31c8b8 100755 --- a/webrtc/examples/androidtests/video_quality_loopback_test.py +++ b/webrtc/examples/androidtests/video_quality_loopback_test.py @@ -19,17 +19,34 @@ It assumes you have a Android device plugged in. """ import argparse +import atexit import logging import os import shutil import subprocess import sys import tempfile +import time SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir, os.pardir)) +WEBRTC_DEPS_INSTRUCTIONS = """Please add a solution to your .gclient file like +this and run gclient sync: +{ + "name": "webrtc.DEPS", + "url": "https://chromium.googlesource.com/chromium/deps/webrtc/webrtc.DEPS", +}, +""" + + +class Error(Exception): + pass + + +class VideoQualityTestError(Error): + pass def _RunCommand(argv, cwd=SRC_DIR, **kwargs): @@ -37,6 +54,22 @@ def _RunCommand(argv, cwd=SRC_DIR, **kwargs): subprocess.check_call(argv, cwd=cwd, **kwargs) +def _RunCommandWithOutput(argv, cwd=SRC_DIR, **kwargs): + logging.info('Running %r', argv) + return subprocess.check_output(argv, cwd=cwd, **kwargs) + + +def _RunBackgroundCommand(argv, cwd=SRC_DIR): + logging.info('Running %r', argv) + process = subprocess.Popen(argv, cwd=cwd) + atexit.register(process.terminate) + time.sleep(0.5) + status = process.poll() + if status: # is not None or 0 + raise subprocess.CalledProcessError(status, argv) + return process + + def _ParseArgs(): parser = argparse.ArgumentParser(description='Start loopback video analysis.') parser.add_argument('build_dir_android', @@ -45,6 +78,7 @@ def _ParseArgs(): help='The path to the build directory for building locally.') parser.add_argument('--temp_dir', help='A temporary directory to put the output.') + parser.add_argument('--adb-path', help='Path to adb binary.', default='adb') args = parser.parse_args() return args @@ -58,6 +92,7 @@ def main(): build_dir_android = args.build_dir_android build_dir_x86 = args.build_dir_x86 temp_dir = args.temp_dir + adb_path = args.adb_path if not temp_dir: temp_dir = tempfile.mkdtemp() else: @@ -76,14 +111,49 @@ def main(): download_script = os.path.join(tools_dir, 'download_tools.py') _RunCommand([sys.executable, download_script, toolchain_dir]) + # Select an Android device in case multiple are connected + for line in _RunCommandWithOutput([adb_path, 'devices']).splitlines(): + if line.endswith('\tdevice'): + android_device = line.split('\t')[0] + break + else: + raise VideoQualityTestError('Cannot find any connected Android device.') + + # Start AppRTC Server + dev_appserver = os.path.join(SRC_DIR, 'out', 'apprtc', 'google_appengine', + 'dev_appserver.py') + if not os.path.isfile(dev_appserver): + raise VideoQualityTestError('Cannot find %s.\n%s' % + (dev_appserver, WEBRTC_DEPS_INSTRUCTIONS)) + appengine_dir = os.path.join(SRC_DIR, 'out', 'apprtc', 'out', 'app_engine') + _RunBackgroundCommand(['python', dev_appserver, appengine_dir, + '--port=9999', '--admin_port=9998', + '--skip_sdk_update_check', '--clear_datastore=yes']) + + # Start Collider + collider_path = os.path.join(SRC_DIR, 'out', 'go-workspace', 'bin', + 'collidermain') + if not os.path.isfile(collider_path): + raise VideoQualityTestError('Cannot find %s.\n%s' % + (collider_path, WEBRTC_DEPS_INSTRUCTIONS)) + _RunBackgroundCommand([collider_path, '-tls=false', + '-port=8089', '-room-server=http://localhost:9999']) + + # Start adb reverse forwarder + reverseforwarder_path = os.path.join( + SRC_DIR, 'build', 'android', 'adb_reverse_forwarder.py') + _RunBackgroundCommand([reverseforwarder_path, '--device', android_device, + '9999', '9999', '8089', '8089']) + # Run the Espresso code. test_script = os.path.join(build_dir_android, 'bin', 'run_AppRTCMobileTestStubbedVideoIO') - _RunCommand([sys.executable, test_script]) + _RunCommand([test_script, '--device', android_device]) # Pull the output video. test_video = os.path.join(temp_dir, 'test_video.y4m') - _RunCommand(['adb', 'pull', '/sdcard/output.y4m', test_video]) + _RunCommand([adb_path, '-s', android_device, + 'pull', '/sdcard/output.y4m', test_video]) test_video_yuv = os.path.join(temp_dir, 'test_video.yuv') @@ -103,8 +173,7 @@ def main(): ConvertVideo(reference_video, reference_video_yuv) # Run compare script. - compare_script = os.path.join(SRC_DIR, 'webrtc', 'tools', - 'compare_videos.py') + compare_script = os.path.join(SRC_DIR, 'webrtc', 'tools', 'compare_videos.py') zxing_path = os.path.join(toolchain_dir, 'linux', 'zxing') # The frame_analyzer binary should be built for local computer and not for