aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-12 02:39:33 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-12 02:39:33 +0000
commitaf8351087040097d7f8f8f4b20d0d9de3fd6d17a (patch)
treec9ac6eaadcfa4a78698262cb2d8b941d5a8d48f7
parent52a6668421a6a85e1c3a79fc4977d591d96a088d (diff)
parent4e2d9224ec4dacbfbd88ccdd03c8091da99bf27e (diff)
downloadacloud-af8351087040097d7f8f8f4b20d0d9de3fd6d17a.tar.gz
acloud: [WebRTC] Provide a webrtc parameter am: 4e2d9224ec
Change-Id: Iabab779f42a33e459cc5f1c98cc200253548d755
-rw-r--r--create/avd_spec.py10
-rw-r--r--create/avd_spec_test.py17
-rw-r--r--create/create_args.py20
-rw-r--r--create/create_args_test.py79
-rw-r--r--create/local_image_remote_instance.py4
-rw-r--r--create/remote_image_remote_instance.py3
-rwxr-xr-xinternal/constants.py1
-rw-r--r--internal/lib/cvd_compute_client_multi_stage.py13
-rw-r--r--internal/lib/cvd_compute_client_multi_stage_test.py6
-rwxr-xr-xinternal/lib/utils.py23
10 files changed, 160 insertions, 16 deletions
diff --git a/create/avd_spec.py b/create/avd_spec.py
index 78e8462e..fed31a5a 100644
--- a/create/avd_spec.py
+++ b/create/avd_spec.py
@@ -662,13 +662,21 @@ class AVDSpec(object):
@property
def connect_vnc(self):
- """launch vnc.
+ """Launch vnc.
Return: Boolean, True if self._autoconnect is 'vnc'.
"""
return self._autoconnect == constants.INS_KEY_VNC
@property
+ def connect_webrtc(self):
+ """Auto-launch webRTC AVD on the browser.
+
+ Return: Boolean, True if args.autoconnect is "webrtc".
+ """
+ return self._autoconnect == constants.INS_KEY_WEBRTC
+
+ @property
def unlock_screen(self):
"""Return unlock_screen."""
return self._unlock_screen
diff --git a/create/avd_spec_test.py b/create/avd_spec_test.py
index 26756c2b..0c323f55 100644
--- a/create/avd_spec_test.py
+++ b/create/avd_spec_test.py
@@ -354,21 +354,30 @@ class AvdSpecTest(driver_test_lib.BaseDriverTest):
self.AvdSpec._ProcessMiscArgs(self.args)
self.assertEqual(self.AvdSpec._instance_type, constants.INSTANCE_TYPE_HOST)
- # Test avd_spec.autoconnect and avd_spec.connect_vnc
+ # Test avd_spec.autoconnect
+ self.args.autoconnect = False
+ self.AvdSpec._ProcessMiscArgs(self.args)
+ self.assertEqual(self.AvdSpec.autoconnect, False)
+ self.assertEqual(self.AvdSpec.connect_vnc, False)
+ self.assertEqual(self.AvdSpec.connect_webrtc, False)
+
self.args.autoconnect = constants.INS_KEY_VNC
self.AvdSpec._ProcessMiscArgs(self.args)
self.assertEqual(self.AvdSpec.autoconnect, True)
self.assertEqual(self.AvdSpec.connect_vnc, True)
+ self.assertEqual(self.AvdSpec.connect_webrtc, False)
- self.args.autoconnect = False
+ self.args.autoconnect = constants.INS_KEY_ADB
self.AvdSpec._ProcessMiscArgs(self.args)
- self.assertEqual(self.AvdSpec.autoconnect, False)
+ self.assertEqual(self.AvdSpec.autoconnect, True)
self.assertEqual(self.AvdSpec.connect_vnc, False)
+ self.assertEqual(self.AvdSpec.connect_webrtc, False)
- self.args.autoconnect = constants.INS_KEY_ADB
+ self.args.autoconnect = constants.INS_KEY_WEBRTC
self.AvdSpec._ProcessMiscArgs(self.args)
self.assertEqual(self.AvdSpec.autoconnect, True)
self.assertEqual(self.AvdSpec.connect_vnc, False)
+ self.assertEqual(self.AvdSpec.connect_webrtc, True)
if __name__ == "__main__":
diff --git a/create/create_args.py b/create/create_args.py
index 06aaaf6b..5bbab572 100644
--- a/create/create_args.py
+++ b/create/create_args.py
@@ -56,12 +56,15 @@ def AddCommonCreateArgs(parser):
const=constants.INS_KEY_VNC,
dest="autoconnect",
required=False,
- choices=[constants.INS_KEY_VNC, constants.INS_KEY_ADB],
- help="For each remote instance, automatically create 2 ssh tunnels "
- "forwarding both adb & vnc, and then add the device to adb. "
- "For local cuttlefish instance, create a vnc connection. "
- "For local goldfish instance, create a window."
- "If need adb only, you can pass in 'adb' here.")
+ choices=[constants.INS_KEY_VNC, constants.INS_KEY_ADB,
+ constants.INS_KEY_WEBRTC],
+ help="Determines to establish a tunnel forwarding adb/vnc and "
+ "launch VNC/webrtc. Establish a tunnel forwarding adb and vnc "
+ "then launch vnc if --autoconnect vnc is provided. Establish a "
+ "tunnel forwarding adb if --autoconnect adb is provided. "
+ "Establish a tunnel forwarding adb and auto-launch on the browser "
+ "if --autoconnect webrtc is provided. For local goldfish "
+ "instance, create a window.")
parser.add_argument(
"--no-autoconnect",
action="store_false",
@@ -486,6 +489,11 @@ def _VerifyLocalArgs(args):
raise errors.CheckPathError(
"Specified path doesn't exist: %s" % tool_dir)
+ if args.autoconnect == constants.INS_KEY_WEBRTC:
+ if args.avd_type != constants.TYPE_CF:
+ raise errors.UnsupportedCreateArgs(
+ "'--autoconnect webrtc' only support cuttlefish.")
+
def _VerifyHostArgs(args):
"""Verify args starting with --host.
diff --git a/create/create_args_test.py b/create/create_args_test.py
new file mode 100644
index 00000000..8cca9ee2
--- /dev/null
+++ b/create/create_args_test.py
@@ -0,0 +1,79 @@
+# Copyright 2020 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for create."""
+
+import unittest
+import mock
+
+from acloud import errors
+from acloud.create import create_args
+from acloud.internal import constants
+from acloud.internal.lib import driver_test_lib
+
+
+def _CreateArgs():
+ """set default pass in arguments."""
+ mock_args = mock.MagicMock(
+ flavor=None,
+ num=None,
+ adb_port=None,
+ hw_property=None,
+ stable_cheeps_host_image_name=None,
+ stable_cheeps_host_image_project=None,
+ username=None,
+ password=None,
+ local_image="",
+ local_system_image="",
+ system_branch=None,
+ system_build_id=None,
+ system_build_target=None,
+ local_instance=None,
+ remote_host=None,
+ host_user=constants.GCE_USER,
+ host_ssh_private_key_path=None,
+ avd_type=constants.TYPE_CF,
+ autoconnect=constants.INS_KEY_VNC)
+ return mock_args
+
+
+# pylint: disable=invalid-name,protected-access
+class CreateArgsTest(driver_test_lib.BaseDriverTest):
+ """Test create_args functions."""
+
+ def testVerifyArgs(self):
+ """test VerifyArgs."""
+ mock_args = _CreateArgs()
+ # Test args default setting shouldn't raise error.
+ self.assertEqual(None, create_args.VerifyArgs(mock_args))
+
+ def testVerifyArgs_ConnectWebRTC(self):
+ """test VerifyArgs args.autconnect webrtc.
+
+ WebRTC only apply to remote cuttlefish instance
+
+ """
+ mock_args = _CreateArgs()
+ mock_args.autoconnect = constants.INS_KEY_WEBRTC
+ # Test remote instance and avd_type cuttlefish(default)
+ # Test args.autoconnect webrtc shouldn't raise error.
+ self.assertEqual(None, create_args.VerifyArgs(mock_args))
+
+ # Test pass in none-cuttlefish avd_type should raise error.
+ mock_args.avd_type = constants.TYPE_GF
+ self.assertRaises(errors.UnsupportedCreateArgs,
+ create_args.VerifyArgs, mock_args)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/create/local_image_remote_instance.py b/create/local_image_remote_instance.py
index 510073de..8177f716 100644
--- a/create/local_image_remote_instance.py
+++ b/create/local_image_remote_instance.py
@@ -18,7 +18,6 @@ r"""LocalImageRemoteInstance class.
Create class that is responsible for creating a remote instance AVD with a
local image.
"""
-
from acloud.create import create_common
from acloud.create import base_avd_create
from acloud.internal import constants
@@ -57,4 +56,7 @@ class LocalImageRemoteInstance(base_avd_create.BaseAVDCreate):
# Launch vnc client if we're auto-connecting.
if avd_spec.connect_vnc:
utils.LaunchVNCFromReport(report, avd_spec, no_prompts)
+ if avd_spec.connect_webrtc:
+ utils.LaunchBrowserFromReport(report)
+
return report
diff --git a/create/remote_image_remote_instance.py b/create/remote_image_remote_instance.py
index 13d24ad9..633d32ec 100644
--- a/create/remote_image_remote_instance.py
+++ b/create/remote_image_remote_instance.py
@@ -18,7 +18,6 @@ r"""RemoteImageRemoteInstance class.
Create class that is responsible for creating a remote instance AVD with a
remote image.
"""
-
from acloud.create import base_avd_create
from acloud.internal.lib import utils
from acloud.public.actions import common_operations
@@ -54,5 +53,7 @@ class RemoteImageRemoteInstance(base_avd_create.BaseAVDCreate):
# Launch vnc client if we're auto-connecting.
if avd_spec.connect_vnc:
utils.LaunchVNCFromReport(report, avd_spec, no_prompts)
+ if avd_spec.connect_webrtc:
+ utils.LaunchBrowserFromReport(report)
return report
diff --git a/internal/constants.py b/internal/constants.py
index deffde5f..fb95d44b 100755
--- a/internal/constants.py
+++ b/internal/constants.py
@@ -141,6 +141,7 @@ INS_KEY_DISPLAY = "display"
INS_KEY_IP = "ip"
INS_KEY_ADB = "adb"
INS_KEY_VNC = "vnc"
+INS_KEY_WEBRTC = "webrtc"
INS_KEY_CREATETIME = "creationTimestamp"
INS_KEY_AVD_TYPE = "avd_type"
INS_KEY_AVD_FLAVOR = "flavor"
diff --git a/internal/lib/cvd_compute_client_multi_stage.py b/internal/lib/cvd_compute_client_multi_stage.py
index 01d4c0ed..e833ad9b 100644
--- a/internal/lib/cvd_compute_client_multi_stage.py
+++ b/internal/lib/cvd_compute_client_multi_stage.py
@@ -62,6 +62,12 @@ _FETCHER_NAME = "fetch_cvd"
_FETCH_ARTIFACT = "fetch_artifact_time"
_GCE_CREATE = "gce_create_time"
_LAUNCH_CVD = "launch_cvd_time"
+# WebRTC args for launching AVD
+_GUEST_ENFORCE_SECURITY_FALSE = "--guest_enforce_security=false"
+_START_WEBRTC = "--start_webrtc"
+_VM_MANAGER = "--vm_manager=crosvm"
+_WEBRTC_ARGS = [_GUEST_ENFORCE_SECURITY_FALSE, _START_WEBRTC, _VM_MANAGER]
+_WEBRTC_PUBLIC_IP = "--webrtc_public_ip=%s"
def _ProcessBuild(build_id=None, branch=None, build_target=None):
@@ -266,6 +272,9 @@ class CvdComputeClient(android_compute_client.AndroidComputeClient):
if constants.HW_ALIAS_MEMORY in avd_spec.hw_property:
launch_cvd_args.append(
"-memory_mb=%s" % avd_spec.hw_property[constants.HW_ALIAS_MEMORY])
+ if avd_spec.connect_webrtc:
+ launch_cvd_args.append(_WEBRTC_PUBLIC_IP % self._ip.external)
+ launch_cvd_args.extend(_WEBRTC_ARGS)
else:
resolution = self._resolution.split("x")
launch_cvd_args.append("-x_res=" + resolution[0])
@@ -447,7 +456,9 @@ class CvdComputeClient(android_compute_client.AndroidComputeClient):
network=self._network,
zone=self._zone,
gpu=self._gpu,
- extra_scopes=extra_scopes)
+ extra_scopes=extra_scopes,
+ tags=["appstreaming"] if (
+ avd_spec and avd_spec.connect_webrtc) else None)
ip = gcompute_client.ComputeClient.GetInstanceIP(
self, instance=instance, zone=self._zone)
logger.debug("'instance_ip': %s", ip.internal
diff --git a/internal/lib/cvd_compute_client_multi_stage_test.py b/internal/lib/cvd_compute_client_multi_stage_test.py
index feb2bdf1..b83bafb5 100644
--- a/internal/lib/cvd_compute_client_multi_stage_test.py
+++ b/internal/lib/cvd_compute_client_multi_stage_test.py
@@ -182,7 +182,8 @@ class CvdComputeClientTest(driver_test_lib.BaseDriverTest):
network=self.NETWORK,
zone=self.ZONE,
extra_scopes=self.EXTRA_SCOPES,
- gpu=self.GPU)
+ gpu=self.GPU,
+ tags=None)
mock_check_img.return_value = True
#test use local image in the remote instance.
@@ -215,7 +216,8 @@ class CvdComputeClientTest(driver_test_lib.BaseDriverTest):
network=self.NETWORK,
zone=self.ZONE,
extra_scopes=self.EXTRA_SCOPES,
- gpu=self.GPU)
+ gpu=self.GPU,
+ tags=None)
if __name__ == "__main__":
diff --git a/internal/lib/utils.py b/internal/lib/utils.py
index 1342cbf4..e6790d33 100755
--- a/internal/lib/utils.py
+++ b/internal/lib/utils.py
@@ -36,6 +36,7 @@ import tarfile
import tempfile
import time
import uuid
+import webbrowser
import zipfile
import six
@@ -86,6 +87,10 @@ _SSVNC_ENV_VARS = {"SSVNC_NO_ENC_WARN": "1", "SSVNC_SCALE": "auto", "VNCVIEWER_X
_DEFAULT_DISPLAY_SCALE = 1.0
_DIST_DIR = "DIST_DIR"
+# For webrtc
+_WEBRTC_URL = "https://"
+_WEBRTC_PORT = "8443"
+
_CONFIRM_CONTINUE = ("In order to display the screen to the AVD, we'll need to "
"install a vnc client (ssvnc). \nWould you like acloud to "
"install it for you? (%s) \nPress 'y' to continue or "
@@ -796,6 +801,7 @@ def _ExecuteCommand(cmd, args):
subprocess.check_call(command, stderr=dev_null, stdout=dev_null)
+# TODO(147337696): create ssh tunnels tear down as adb and vnc.
# pylint: disable=too-many-locals
def AutoConnect(ip_addr, rsa_key_file, target_vnc_port, target_adb_port,
ssh_user, client_adb_port=None, extra_args_ssh_tunnel=None):
@@ -905,6 +911,23 @@ def LaunchVNCFromReport(report, avd_spec, no_prompts=False):
PrintColorString("No VNC port specified, skipping VNC startup.",
TextColors.FAIL)
+def LaunchBrowserFromReport(report):
+ """Open browser when autoconnect to webrtc according to the instances report.
+
+ Args:
+ report: Report object, that stores and generates report.
+ """
+ for device in report.data.get("devices", []):
+ if device.get("ip"):
+ PrintColorString("(This is an experimental project for webrtc, and "
+ "since the certificate is self-signed, Chrome will "
+ "mark it as an insecure website. keep going.)",
+ TextColors.WARNING)
+ webbrowser.open_new_tab("%s%s:%s" % (
+ _WEBRTC_URL, device.get("ip"), _WEBRTC_PORT))
+ else:
+ PrintColorString("Auto-launch devices webrtc in browser failed!",
+ TextColors.FAIL)
def LaunchVncClient(port, avd_width=None, avd_height=None, no_prompts=False):
"""Launch ssvnc.