Home | History | Annotate | Download | only in mirror
      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 
     17 import copy
     18 import logging
     19 import random
     20 import sys
     21 
     22 from google.protobuf import text_format
     23 
     24 from vts.proto import AndroidSystemControlMessage_pb2 as ASysCtrlMsg
     25 from vts.proto import ComponentSpecificationMessage_pb2 as CompSpecMsg
     26 from vts.utils.python.fuzzer import FuzzerUtils
     27 from vts.utils.python.mirror import native_entity_mirror
     28 from vts.utils.python.mirror import py2pb
     29 
     30 _DEFAULT_TARGET_BASE_PATHS = ["/system/lib64/hw"]
     31 _DEFAULT_HWBINDER_SERVICE = "default"
     32 
     33 INTERFACE = "interface"
     34 API = "api"
     35 
     36 
     37 class MirrorObjectError(Exception):
     38     """Raised when there is a general error in manipulating a mirror object."""
     39     pass
     40 
     41 
     42 class HalMirror(native_entity_mirror.NativeEntityMirror):
     43     """The class that acts as the mirror to an Android device's HAL layer.
     44 
     45     This class exists on the host and can be used to communicate to a
     46     particular HIDL HAL on the target side.
     47 
     48     Attributes:
     49         _callback_server: the instance of a callback server.
     50     """
     51 
     52     def __init__(self,
     53                  client,
     54                  callback_server,
     55                  hal_driver_id=None,
     56                  if_spec_message=None,
     57                  caller_uid=None):
     58         super(HalMirror, self).__init__(client, hal_driver_id, if_spec_message,
     59                                         caller_uid)
     60         self._callback_server = callback_server
     61 
     62     def InitHalDriver(self, target_type, target_version, target_package,
     63                       target_component_name, hw_binder_service_name,
     64                       handler_name, bits):
     65         """Initiates the driver for a HIDL HAL on the target device and loads
     66         the interface specification message.
     67 
     68         Args:
     69             target_type: string, the target type name (e.g., light, camera).
     70             target_version: float, the target component version (e.g., 1.0).
     71             target_package: . separated string (e.g., a.b.c) to denote the
     72                             package name of target component.
     73             target_component_name: string, the target componet name (e.g., INfc).
     74             hw_binder_service_name: string, name of the HAL service instance
     75                                     (e.g. default)
     76             handler_name: string, the name of the handler. target_type is used
     77                           by default.
     78             bits: integer, processor architecture indicator: 32 or 64.
     79 
     80         Raises:
     81             errors.ComponentLoadingError is raised when error occurs trying to
     82             create a MirrorObject.
     83         """
     84         driver_id = self.LaunchMirrorDriver(
     85             ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_HIDL,
     86             "hal_hidl",
     87             target_type,
     88             target_version,
     89             target_package=target_package,
     90             target_component_name=target_component_name,
     91             handler_name=handler_name,
     92             hw_binder_service_name=hw_binder_service_name,
     93             bits=bits)
     94         self._driver_id = driver_id
     95 
     96         #TODO: ListApis assumes only one HAL is loaded at a time, need to
     97         #      figure out a way to get the api_spec when we want to test
     98         #      multiple HALs together.
     99         found_api_spec = self._client.ListApis()
    100         if not found_api_spec:
    101             raise errors.ComponentLoadingError("No API found for %s" %
    102                                                target_type)
    103         if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
    104         text_format.Merge(found_api_spec, if_spec_msg)
    105 
    106         self._if_spec_msg = if_spec_msg
    107 
    108     def GetCallbackFunctionID(self, function_pointer):
    109         """Gets registsred callback function id for the given function_pointer.
    110 
    111         Args:
    112             function_pointer: the callback function pointer.
    113 
    114         Returns:
    115             Id for the call back function registered with callback server.
    116         """
    117         if self._callback_server:
    118             id = self._callback_server.GetCallbackId(function_pointer)
    119             if id is None:
    120                 id = self._callback_server.RegisterCallback(function_pointer)
    121             return str(id)
    122         else:
    123             raise MirrorObjectError("callback server is not started.")
    124 
    125     def GetHidlCallbackInterface(self, interface_name, **kwargs):
    126         """Gets the ProtoBuf message for a callback interface based on args.
    127 
    128         Args:
    129             interface_name: string, the callback interface name.
    130             **kwargs: a dict for the arg name and value pairs
    131 
    132         Returns:
    133             VariableSpecificationMessage that contains the callback interface
    134             description.
    135         """
    136         var_msg = CompSpecMsg.VariableSpecificationMessage()
    137         var_msg.name = interface_name
    138         var_msg.type = CompSpecMsg.TYPE_FUNCTION_POINTER
    139         var_msg.is_callback = True
    140 
    141         msg = self._if_spec_msg
    142         specification = self._client.ReadSpecification(
    143             interface_name, msg.component_class, msg.component_type,
    144             msg.component_type_version, msg.package)
    145         logging.info("specification: %s", specification)
    146         interface = getattr(specification, INTERFACE, None)
    147         apis = getattr(interface, API, [])
    148         for api in apis:
    149             function_pointer = None
    150             if api.name in kwargs:
    151                 function_pointer = kwargs[api.name]
    152             else:
    153 
    154                 def dummy(*args):
    155                     """Dummy implementation for any callback function."""
    156                     logging.info("Entering dummy implementation"
    157                                  " for callback function: %s", api.name)
    158                     for arg_index in range(len(args)):
    159                         logging.info("arg%s: %s", arg_index, args[arg_index])
    160 
    161                 function_pointer = dummy
    162             func_pt_msg = var_msg.function_pointer.add()
    163             func_pt_msg.function_name = api.name
    164             func_pt_msg.id = self.GetCallbackFunctionID(function_pointer)
    165 
    166         return var_msg
    167 
    168     def GetHidlTypeInterface(self, interface_name):
    169         """Gets a HalMirror for HIDL HAL types specification. """
    170         return self.GetHalMirrorForInterface(interface_name)
    171 
    172     def GetHalMirrorForInterface(self, interface_name, driver_id=None):
    173         """Gets a HalMirror for a HIDL HAL interface.
    174 
    175         Args:
    176             interface_name: string, the name of a target interface to read.
    177             driver_id: int, driver is of the corresponding HIDL HAL interface.
    178 
    179         Returns:
    180             a host-side mirror of a HIDL HAL interface.
    181         """
    182         if not self._if_spec_msg:
    183             raise MirrorObjectError("spcification is not loaded")
    184         msg = self._if_spec_msg
    185         found_api_spec = self._client.ReadSpecification(
    186             interface_name,
    187             msg.component_class,
    188             msg.component_type,
    189             msg.component_type_version,
    190             msg.package,
    191             recursive=True)
    192 
    193         logging.info("found_api_spec %s", found_api_spec)
    194         if not driver_id:
    195             driver_id = self._driver_id
    196         # Instantiate a MirrorObject and return it.
    197         return HalMirror(self._client, self._callback_server, driver_id,
    198                          found_api_spec)
    199