• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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