1# 2# Copyright (C) 2016 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import logging 18 19from google.protobuf import text_format 20 21from vts.runners.host import errors 22from vts.proto import AndroidSystemControlMessage_pb2 as ASysCtrlMsg 23from vts.proto import ComponentSpecificationMessage_pb2 as CompSpecMsg 24from vts.runners.host.tcp_client import vts_tcp_client 25from vts.utils.python.mirror import hal_mirror 26from vts.utils.python.mirror import mirror_object 27 28VTS_CALLBACK_SERVER_TARGET_SIDE_PORT = 5010 29 30_DEFAULT_TARGET_BASE_PATHS = ["/system/lib64/hw"] 31 32 33class LibMirror(object): 34 """The class that acts as the mirror to an Android device's Lib layer. 35 36 This class holds and manages the life cycle of multiple mirror objects that 37 map to different lib components. 38 39 One can use this class to create and destroy a lib mirror object. 40 41 Attributes: 42 _host_command_port: int, the host-side port for command-response 43 sessions. 44 _lib_level_mirrors: dict, key is lib handler name, value is HAL 45 mirror object. internally, it uses a legacy_hal 46 mirror. 47 """ 48 def __init__(self, host_command_port): 49 self._lib_level_mirrors = {} 50 self._host_command_port = host_command_port 51 52 def __del__(self): 53 for lib_mirror_name in self._lib_level_mirrors: 54 self.RemoveLib(lib_mirror_name) 55 self._lib_level_mirrors = {} 56 57 def InitSharedLib(self, 58 target_type, 59 target_version, 60 target_basepaths=_DEFAULT_TARGET_BASE_PATHS, 61 target_package="", 62 target_filename=None, 63 handler_name=None, 64 bits=64): 65 """Initiates a handler for a particular lib. 66 67 This will initiate a driver service for a lib on the target side, create 68 the top level mirror object for a lib, and register it in the manager. 69 70 Args: 71 target_type: string, the target type name (e.g., light, camera). 72 target_version: float, the target component version (e.g., 1.0). 73 target_basepaths: list of strings, the paths to look for target 74 files in. Default is _DEFAULT_TARGET_BASE_PATHS. 75 target_package: . separated string (e.g., a.b.c) to denote the 76 package name of target component. 77 target_filename: string, the target file name (e.g., libm.so). 78 handler_name: string, the name of the handler. target_type is used 79 by default. 80 bits: integer, processor architecture indicator: 32 or 64. 81 """ 82 self._CreateMirrorObject("lib_shared", 83 target_type, 84 target_version, 85 target_basepaths=target_basepaths, 86 target_package=target_package, 87 target_filename=target_filename, 88 handler_name=handler_name, 89 bits=bits) 90 91 def RemoveLib(self, handler_name): 92 lib_level_mirror = self._lib_level_mirrors[handler_name] 93 lib_level_mirror.CleanUp() 94 95 def _CreateMirrorObject(self, 96 target_class, 97 target_type, 98 target_version, 99 target_basepaths=_DEFAULT_TARGET_BASE_PATHS, 100 target_package="", 101 target_filename=None, 102 handler_name=None, 103 bits=64): 104 """Initiates the driver for a lib on the target device and creates a top 105 level MirroObject for it. 106 107 Args: 108 target_class: string, the target class name (e.g., lib). 109 target_type: string, the target type name (e.g., light, camera). 110 target_version: float, the target component version (e.g., 1.0). 111 target_basepaths: list of strings, the paths to look for target 112 files in. Default is _DEFAULT_TARGET_BASE_PATHS. 113 target_package: . separated string (e.g., a.b.c) to denote the 114 package name of target component. 115 target_filename: string, the target file name (e.g., libm.so). 116 handler_name: string, the name of the handler. target_type is used 117 by default. 118 bits: integer, processor architecture indicator: 32 or 64. 119 120 Raises: 121 errors.ComponentLoadingError is raised when error occurs trying to 122 create a MirrorObject. 123 """ 124 if bits not in [32, 64]: 125 raise error.ComponentLoadingError("Invalid value for bits: %s" % bits) 126 client = vts_tcp_client.VtsTcpClient() 127 client.Connect(command_port=self._host_command_port) 128 if not handler_name: 129 handler_name = target_type 130 service_name = "vts_driver_%s" % handler_name 131 132 # Get all the libs available on the target. 133 lib_list = client.ListHals(target_basepaths) 134 if not lib_list: 135 raise errors.ComponentLoadingError( 136 "Could not find any lib under path %s" % target_basepaths) 137 logging.debug(lib_list) 138 139 # Find the corresponding filename for Lib target type. 140 if target_filename is not None: 141 for name in lib_list: 142 if name.endswith(target_filename): 143 target_filename = name 144 break 145 else: 146 for name in lib_list: 147 if target_type in name: 148 # TODO: check more exactly (e.g., multiple hits). 149 target_filename = name 150 151 if not target_filename: 152 raise errors.ComponentLoadingError( 153 "No file found for target type %s." % target_type) 154 155 # Check whether the requested binder service is already running. 156 # if client.CheckDriverService(service_name=service_name): 157 # raise errors.ComponentLoadingError("A driver for %s already exists" % 158 # service_name) 159 160 # Launch the corresponding driver of the requested Lib on the target. 161 logging.info("Init the driver service for %s", target_type) 162 target_class_id = hal_mirror.COMPONENT_CLASS_DICT[target_class.lower()] 163 target_type_id = hal_mirror.COMPONENT_TYPE_DICT[target_type.lower()] 164 launched = client.LaunchDriverService( 165 driver_type=ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_CONVENTIONAL, 166 service_name=service_name, 167 bits=bits, 168 file_path=target_filename, 169 target_class=target_class_id, 170 target_type=target_type_id, 171 target_version=target_version, 172 target_package=target_package) 173 174 if not launched: 175 raise errors.ComponentLoadingError( 176 "Failed to launch driver service %s from file path %s" % 177 (target_type, target_filename)) 178 179 # Create API spec message. 180 found_api_spec = client.ListApis() 181 if not found_api_spec: 182 raise errors.ComponentLoadingError("No API found for %s" % 183 service_name) 184 logging.debug("Found %d APIs for %s:\n%s", len(found_api_spec), 185 service_name, found_api_spec) 186 if_spec_msg = CompSpecMsg.ComponentSpecificationMessage() 187 text_format.Merge(found_api_spec, if_spec_msg) 188 189 # Instantiate a MirrorObject and return it. 190 lib_mirror = mirror_object.MirrorObject(client, if_spec_msg, None) 191 self._lib_level_mirrors[handler_name] = lib_mirror 192 193 def __getattr__(self, name): 194 return self._lib_level_mirrors[name] 195