From e9cf7f5cbe1c41c45f041fb00a16680c8debf43e Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Thu, 21 Dec 2017 17:08:11 +0000 Subject: [PATCH] target: Adds initial support for ChromeOs targets Adds initial support for ChromeOs Targets. If the device does not support running android apps the target will behave like a `LinuxTarget` however if android is supported, the chromeos target opens 2 connections, one via shh to the linux target, as normal, and one via adb to the android container. By default all calls will be made to the linux target and if not present, will attempt to use the android container instead. The android container is also exposed via a `android_container` attribute so can be accessed directly. In order to detect whether the target supports running android apps the existance of '/opt/google/containers/android/' will be queried upon connection to the linux target. --- devlib/__init__.py | 2 +- devlib/target.py | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/devlib/__init__.py b/devlib/__init__.py index 2b3f3b6..f23b3ba 100644 --- a/devlib/__init__.py +++ b/devlib/__init__.py @@ -1,4 +1,4 @@ -from devlib.target import Target, LinuxTarget, AndroidTarget, LocalLinuxTarget +from devlib.target import Target, LinuxTarget, AndroidTarget, LocalLinuxTarget, ChromeOsTarget from devlib.host import PACKAGE_BIN_DIRECTORY from devlib.exception import DevlibError, TargetError, HostError, TargetNotRespondingError diff --git a/devlib/target.py b/devlib/target.py index 9653ed3..7a6922e 100644 --- a/devlib/target.py +++ b/devlib/target.py @@ -1696,3 +1696,101 @@ def _build_path_tree(path_map, basepath, sep=os.path.sep, dictcls=dict): process_node(result, path, value) return result + + +class ChromeOsTarget(LinuxTarget): + + os = 'chromeos' + + def __init__(self, + connection_settings=None, + platform=None, + working_directory=None, + executables_directory=None, + android_working_directory=None, + android_executables_directory=None, + connect=True, + modules=None, + load_default_modules=True, + shell_prompt=DEFAULT_SHELL_PROMPT, + package_data_directory="/data/data", + ): + + self.supports_android = None + self.android_container = None + + # Pull out ssh connection settings + ssh_conn_params = ['host', 'username', 'password', 'keyfile', + 'port', 'password_prompt', 'timeout', 'sudo_cmd'] + self.ssh_connection_settings = {} + for setting in ssh_conn_params: + if connection_settings.get(setting, None): + self.ssh_connection_settings[setting] = connection_settings[setting] + + super(ChromeOsTarget, self).__init__(connection_settings=self.ssh_connection_settings, + platform=platform, + working_directory=working_directory, + executables_directory=executables_directory, + connect=False, + modules=modules, + load_default_modules=load_default_modules, + shell_prompt=shell_prompt, + conn_cls=SshConnection) + + # We can't determine if the target supports android until connected to the linux host so + # create unconditionally. + # Pull out adb connection settings + adb_conn_params = ['device', 'adb_server', 'timeout'] + self.android_connection_settings = {} + for setting in adb_conn_params: + if connection_settings.get(setting, None): + self.android_connection_settings[setting] = connection_settings[setting] + + # If adb device is not explicitly specified use same as ssh host + if not connection_settings.get('device', None): + self.android_connection_settings['device'] = connection_settings.get('host', None) + + self.android_container = AndroidTarget(connection_settings=self.android_connection_settings, + platform=platform, + working_directory=android_working_directory, + executables_directory=android_executables_directory, + connect=False, + modules=[], # Only use modules with linux target + load_default_modules=False, + shell_prompt=shell_prompt, + conn_cls=AdbConnection, + package_data_directory=package_data_directory) + if connect: + self.connect() + + def __getattr__(self, attr): + """ + By default use the linux target methods and attributes however, + if not present, use android implementation if available. + """ + try: + return super(ChromeOsTarget, self).__getattribute__(attr) + except AttributeError: + if hasattr(self.android_container, attr): + return getattr(self.android_container, attr) + else: + raise + + def connect(self, timeout=30): + super(ChromeOsTarget, self).connect(timeout) + + # Assume device supports android apps if container directory is present + if self.supports_android is None: + self.supports_android = self.directory_exists('/opt/google/containers/android/') + + if self.supports_android: + self.android_container.connect(timeout) + else: + self.android_container = None + + def _resolve_paths(self): + if self.working_directory is None: + self.working_directory = '/mnt/stateful_partition/devlib-target' + self._file_transfer_cache = self.path.join(self.working_directory, '.file-cache') + if self.executables_directory is None: + self.executables_directory = self.path.join(self.working_directory, 'bin')