예제 #1
0
 def GetAttribute(self, attribute_name):
     """Returns the Message.
     """
     logging.debug("GetAttribute %s for %s", attribute_name,
                   self._if_spec_msg)
     if self._if_spec_msg.attribute:
         for attribute in self._if_spec_msg.attribute:
             if attribute.name == attribute_name:
                 func_msg = CompSpecMsg.FunctionSpecificationMessage()
                 func_msg.name = attribute.name
                 func_msg.return_type.type = attribute.type
                 if func_msg.return_type.type == CompSpecMsg.TYPE_SCALAR:
                     func_msg.return_type.scalar_type = attribute.scalar_type
                 else:
                     func_msg.return_type.predefined_type = attribute.predefined_type
                 logging.info("GetAttribute attribute: %s", attribute)
                 logging.info("GetAttribute request: %s", func_msg)
                 return copy.copy(func_msg)
     if (self._if_spec_msg.interface
             and self._if_spec_msg.interface.attribute):
         for attribute in self._if_spec_msg.interface.attribute:
             if attribute.name == attribute_name:
                 func_msg = CompSpecMsg.FunctionSpecificationMessage()
                 func_msg.name = attribute.name
                 func_msg.return_type.type = attribute.type
                 if func_msg.return_type.type == CompSpecMsg.TYPE_SCALAR:
                     func_msg.return_type.scalar_type = attribute.scalar_type
                 else:
                     func_msg.return_type.predefined_type = attribute.predefined_type
                 logging.info("GetAttribute attribute: %s", attribute)
                 logging.info("GetAttribute request: %s", func_msg)
                 return copy.copy(func_msg)
     return None
예제 #2
0
    def GetHidlCallbackInterface(self, interface_name, **kwargs):
        var_msg = CompSpecMsg.VariableSpecificationMessage()
        var_msg.name = interface_name
        var_msg.type = CompSpecMsg.TYPE_FUNCTION_POINTER
        var_msg.is_callback = True

        msg = self._if_spec_msg
        specification = self._client.ReadSpecification(
            interface_name, msg.component_class, msg.component_type,
            msg.component_type_version, msg.package)
        logging.info("specification: %s", specification)
        interface = getattr(specification, INTERFACE, None)
        apis = getattr(interface, API, [])
        for api in apis:
            function_pointer = None
            if api.name in kwargs:
                function_pointer = kwargs[api.name]
            else:

                def dummy(*args):
                    """Dummy implementation for any callback function."""
                    logging.info(
                        "Entering dummy implementation"
                        " for callback function: %s", api.name)
                    for arg_index in range(len(args)):
                        logging.info("arg%s: %s", arg_index, args[arg_index])

                function_pointer = dummy
            func_pt_msg = var_msg.function_pointer.add()
            func_pt_msg.function_name = api.name
            func_pt_msg.id = self.GetFunctionPointerID(function_pointer)

        return var_msg
예제 #3
0
    def VtsSpecProto(self, hal_name, hal_version, vts_spec_name=''):
        """Returns list of .vts protos for given hal name and version.

        Args:
            hal_name: string, name of the hal, e.g. 'vibrator'.
            hal_version: string, version of the hal, e.g '7.4'
            vts_spec:

        Returns:
            list with all vts spec protos for a given hal and version if
            vts_spec_name is not given. If vts_spec_name is not empty, then
            returns ComponentSpecificationMessage matching vts_spec_name.
            If no such vts_spec_name, return None.
        """
        if not vts_spec_name:
            vts_spec_protos = []
            for vts_spec in self.VtsSpecNames(hal_name, hal_version):
                vts_spec_proto = self.VtsSpecProto(hal_name, hal_version,
                                                   vts_spec)
                vts_spec_protos.append(vts_spec_proto)
            return vts_spec_protos
        else:
            if vts_spec_name in self.VtsSpecNames(hal_name, hal_version):
                vts_spec_proto = CompSpecMsg.ComponentSpecificationMessage()
                vts_spec_path = os.path.join(
                    self._VtsSpecDir(hal_name, hal_version), vts_spec_name)
                with open(vts_spec_path, 'r') as vts_spec_file:
                    vts_spec_string = vts_spec_file.read()
                    text_format.Merge(vts_spec_string, vts_spec_proto)
                return vts_spec_proto
예제 #4
0
    def GetApi(self, api_name):
        """Gets the ProtoBuf message for given api.

        Args:
            api_name: string, the name of the target function API.

        Returns:
            FunctionSpecificationMessage if found, None otherwise
        """
        logging.debug("GetAPI %s for %s", api_name, self._if_spec_msg)
        # handle reserved methods first.
        if api_name == "notifySyspropsChanged":
            func_msg = CompSpecMsg.FunctionSpecificationMessage()
            func_msg.name = api_name
            return func_msg
        if isinstance(self._if_spec_msg,
                      CompSpecMsg.ComponentSpecificationMessage):
            if len(self._if_spec_msg.interface.api) > 0:
                for api in self._if_spec_msg.interface.api:
                    if api.name == api_name:
                        return copy.copy(api)
        else:
            logging.error("unknown spec type %s", type(self._if_spec_msg))
            sys.exit(1)
        return None
예제 #5
0
    def _GetTotalApis(self, package_name, version, interface_name):
        """Parse the specified vts spec and get all APIs defined in the spec.

        Args:
            package_name: string, HAL package name.
            version: string, HAL version.
            interface_name: string, HAL interface name.

        Returns:
            A set of strings, each string represents an API defined in the spec.
        """
        total_apis = set()
        spec_proto = CompSpecMsg.ComponentSpecificationMessage()
        # TODO: support general package that does not start with android.hardware.
        if not package_name.startswith(DEFAULT_HAL_ROOT):
            logging.warning("Unsupported hal package: %s", package_name)
            return total_apis

        hal_package_path = package_name[len(DEFAULT_HAL_ROOT):].replace(
            ".", "/")
        vts_spec_path = os.path.join(
            self.data_file_path, "spec/hardware/interfaces", hal_package_path,
            version, "vts", interface_name[1:] + ".vts")
        logging.debug("vts_spec_path: %s", vts_spec_path)
        with open(vts_spec_path, 'r') as spec_file:
            spec_string = spec_file.read()
            text_format.Merge(spec_string, spec_proto)
        for api in spec_proto.interface.api:
            if not api.is_inherited:
                total_apis.add(api.name)
        return total_apis
예제 #6
0
    def OpenConventionalHal(self, module_name=None):
        """Opens the target conventional HAL component.

        This is only needed for conventional HAL.

        Args:
            module_name: string, the name of a module to load.
        """
        call_msg = CompSpecMsg.FunctionCallMessage()
        if self._hal_driver_id is not None:
            call_msg.hal_driver_id = self._hal_driver_id
        call_msg.component_class = CompSpecMsg.HAL_CONVENTIONAL
        call_msg.api.name = "#Open"
        if module_name:
            arg = call_msg.api.arg.add()
            arg.type = CompSpecMsg.TYPE_STRING
            arg.string_value.message = module_name

            call_msg.api.return_type.type == CompSpecMsg.TYPE_SCALAR
            call_msg.api.return_type.scalar_type = "int32_t"
        logging.debug("final msg %s", call_msg)

        result = self._client.CallApi(text_format.MessageToString(call_msg),
                                      self.__caller_uid)
        logging.debug(result)
        return result
예제 #7
0
def Convert(pb_spec, py_value):
    """Converts Python native data structure to VTS VariableSecificationMessage.

    Args:
        pb_spec: VariableSpecificationMessage which captures the
                 specification of a target attribute.
        py_value: Python value provided by a test case.

    Returns:
        Converted VariableSpecificationMessage if found, None otherwise
    """
    if not pb_spec:
        logging.error("py2pb.Convert: ProtoBuf spec is None", pb_spec)
        return None

    message = CompSpecMsg.VariableSpecificationMessage()
    message.name = pb_spec.name

    if isinstance(py_value, CompSpecMsg.VariableSpecificationMessage):
        message.CopyFrom(py_value)
    elif pb_spec.type == CompSpecMsg.TYPE_STRUCT:
        PyDict2PbStruct(message, pb_spec, py_value)
    elif pb_spec.type == CompSpecMsg.TYPE_ENUM:
        PyValue2PbEnum(message, pb_spec, py_value)
    elif pb_spec.type == CompSpecMsg.TYPE_SCALAR:
        PyValue2PbScalar(message, pb_spec, py_value)
    elif pb_spec.type == CompSpecMsg.TYPE_STRING:
        PyString2PbString(message, pb_spec, py_value)
    elif pb_spec.type == CompSpecMsg.TYPE_VECTOR:
        PyList2PbVector(message, pb_spec, py_value)
    else:
        logging.error("py2pb.Convert: unsupported type %s", pb_spec.type)
        sys.exit(-1)

    return message
예제 #8
0
 def GetAttribute(self, arg):
     """RPC to VTS_AGENT_COMMAND_GET_ATTRIBUTE."""
     self.SendCommand(SysMsg_pb2.VTS_AGENT_COMMAND_GET_ATTRIBUTE, arg=arg)
     resp = self.RecvResponse()
     resp_code = resp.response_code
     if (resp_code == SysMsg_pb2.SUCCESS):
         result = CompSpecMsg_pb2.FunctionSpecificationMessage()
         if resp.result == "error":
             raise errors.VtsTcpCommunicationError(
                 "Get attribute request failed on target.")
         try:
             text_format.Merge(resp.result, result)
         except text_format.ParseError as e:
             logging.exception(e)
             logging.error("Paring error\n%s", resp.result)
         if result.return_type.type == CompSpecMsg_pb2.TYPE_SUBMODULE:
             logging.debug("returned a submodule spec")
             logging.debug("spec: %s", result.return_type_submodule_spec)
             return mirror_object.MirrorObject(
                 self, result.return_type_submodule_spec, None)
         elif result.return_type.type == CompSpecMsg_pb2.TYPE_SCALAR:
             return getattr(result.return_type.scalar_value,
                            result.return_type.scalar_type)
         return result
     logging.error("NOTICE - Likely a crash discovery!")
     logging.error("SysMsg_pb2.SUCCESS is %s", SysMsg_pb2.SUCCESS)
     raise errors.VtsTcpCommunicationError(
         "RPC Error, response code for %s is %s" % (arg, resp_code))
예제 #9
0
        def RemoteCall(*args, **kwargs):
            """Dynamically calls a remote API and returns the result value."""
            func_msg = self.GetApi(api_name)
            if not func_msg:
                raise MirrorObjectError("api %s unknown", func_msg)

            logging.info("remote call %s%s", api_name, args)
            if args:
                for arg_msg, value_msg in zip(func_msg.arg, args):
                    logging.debug("arg msg %s", arg_msg)
                    logging.debug("value %s", value_msg)
                    if value_msg is not None:
                        converted_msg = py2pb.Convert(arg_msg, value_msg)
                        logging.debug("converted_message: %s", converted_msg)
                        arg_msg.CopyFrom(converted_msg)
            else:
                # TODO: use kwargs
                for arg in func_msg.arg:
                    # TODO: handle other
                    if (arg.type == CompSpecMsg.TYPE_SCALAR and
                            arg.scalar_type == "pointer"):
                        arg.scalar_value.pointer = 0
                logging.debug(func_msg)

            call_msg = CompSpecMsg.FunctionCallMessage()
            if self._if_spec_msg.component_class:
                call_msg.component_class = self._if_spec_msg.component_class
            call_msg.hal_driver_id = self._driver_id
            call_msg.api.CopyFrom(func_msg)
            logging.info("final msg %s", call_msg)
            results = self._client.CallApi(
                text_format.MessageToString(call_msg), self._caller_uid)
            if (isinstance(results, tuple) and len(results) == 2
                    and isinstance(results[1], dict)
                    and "coverage" in results[1]):
                self._last_raw_code_coverage_data = results[1]["coverage"]
                results = results[0]

            if isinstance(results, list):  # Non-HIDL HAL does not return list.
              # Translate TYPE_HIDL_INTERFACE to halMirror.
              for i, _ in enumerate(results):
                  result = results[i]
                  if (result and isinstance(result,
                                          CompSpecMsg.VariableSpecificationMessage)
                        and result.type == CompSpecMsg.TYPE_HIDL_INTERFACE):
                    if result.hidl_interface_id <= -1:
                      results[i] = None
                    driver_id = result.hidl_interface_id
                    nested_interface_name = result.predefined_type.split("::")[-1]
                    logging.debug("Nested interface name: %s",
                                  nested_interface_name)
                    nested_interface = self.GetHalMirrorForInterface(
                        nested_interface_name, driver_id)
                    results[i] = nested_interface
              if len(results) == 1: # singe return result, return the value direcly.
                  return results[0]
            return results
예제 #10
0
    def ReadSpecification(self,
                          interface_name,
                          target_class,
                          target_type,
                          target_version,
                          target_package,
                          recursive=False):
        """RPC to VTS_AGENT_COMMAND_READ_SPECIFICATION.

        Args:
            other args: see SendCommand
            recursive: boolean, set to recursively read the imported
                       specification(s) and return the merged one.
        """
        self.SendCommand(SysMsg_pb2.VTS_AGENT_COMMAND_READ_SPECIFICATION,
                         service_name=interface_name,
                         target_class=target_class,
                         target_type=target_type,
                         target_version=target_version,
                         target_package=target_package)
        resp = self.RecvResponse(retries=2)
        logging.info("resp for VTS_AGENT_COMMAND_EXECUTE_READ_INTERFACE: %s",
                     resp)
        logging.info("proto: %s", resp.result)
        result = CompSpecMsg_pb2.ComponentSpecificationMessage()
        if resp.result == "error":
            raise errors.VtsTcpCommunicationError(
                "API call error by the VTS driver.")
        try:
            text_format.Merge(resp.result, result)
        except text_format.ParseError as e:
            logging.exception(e)
            logging.error("Paring error\n%s", resp.result)

        if recursive and hasattr(result, "import"):
            for imported_interface in getattr(result, "import"):
                if imported_interface == "[email protected]::types":
                    logging.warn("import [email protected]::types skipped")
                    continue
                imported_result = self.ReadSpecification(
                    imported_interface.split("::")[1],
                    # TODO(yim): derive target_class and
                    # target_type from package path or remove them
                    msg.component_class
                    if target_class is None else target_class,
                    msg.component_type if target_type is None else target_type,
                    float(imported_interface.split("@")[1].split("::")[0]),
                    imported_interface.split("@")[0])
                # Merge the attributes from imported interface.
                for attribute in imported_result.attribute:
                    imported_attribute = result.attribute.add()
                    imported_attribute.CopyFrom(attribute)

        return result
예제 #11
0
    def InitHalDriver(self, target_type, target_version_major,
                      target_version_minor, target_package,
                      target_component_name, hw_binder_service_name,
                      handler_name, bits, is_test_hal):
        """Initiates the driver for a HIDL HAL on the target device and loads
        the interface specification message.

        Args:
            target_type: string, the target type name (e.g., light, camera).
            target_version_major:
              int, the target component major version (e.g., 1.0 -> 1).
            target_version_minor:
              int, the target component minor version (e.g., 1.0 -> 0).
            target_package: . separated string (e.g., a.b.c) to denote the
                            package name of target component.
            target_component_name: string, the target componet name (e.g., INfc).
            hw_binder_service_name: string, name of the HAL service instance
                                    (e.g. default)
            handler_name: string, the name of the handler. target_type is used
                          by default.
            bits: integer, processor architecture indicator: 32 or 64.
            is_test_hal: bool, whether the HAL service is a test HAL
                         (e.g. msgq).

        Raises:
            errors.ComponentLoadingError is raised when error occurs trying to
            create a MirrorObject.
        """
        driver_id = self.LaunchMirrorDriver(
            ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_HIDL,
            "hal_hidl",
            target_type,
            target_version_major,
            target_version_minor,
            target_package=target_package,
            target_component_name=target_component_name,
            handler_name=handler_name,
            hw_binder_service_name=hw_binder_service_name,
            bits=bits,
            is_test_hal=is_test_hal)
        self._driver_id = driver_id

        #TODO: ListApis assumes only one HAL is loaded at a time, need to
        #      figure out a way to get the api_spec when we want to test
        #      multiple HALs together.
        found_api_spec = self._client.ListApis()
        if not found_api_spec:
            raise errors.ComponentLoadingError(
                "No API found for %s" % target_type)
        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
        text_format.Merge(found_api_spec, if_spec_msg)

        self._if_spec_msg = if_spec_msg
예제 #12
0
    def GetHidlNestedInterface(self,
                               interface_name,
                               interface_id,
                               target_class=None,
                               target_type=None,
                               version=None,
                               package=None):
        """Gets HIDL type interface's host-side mirror.

        Args:
            interface_name: string, the name of a target interface to read.
            interface_id: integer, the ID of a target interface to
                          control.
            target_class: integer, optional used to override the loaded HAL's
                          component_class.
            target_type: integer, optional used to override the loaded HAL's
                         component_type.
            version: integer, optional used to override the loaded HAL's
                     component_type_version.
            package: integer, optional used to override the loaded HAL's
                              package.

        Returns:
            a host-side mirror of a HIDL interface
        """
        msg = self._if_spec_msg
        found_api_spec = self._client.ReadSpecification(
            interface_name,
            msg.component_class if target_class is None else target_class,
            msg.component_type if target_type is None else target_type,
            msg.component_type_version if version is None else version,
            msg.package if package is None else package,
            recursive=True)

        found_api_spec = str(found_api_spec)
        logging.debug("found_api_spec %s", found_api_spec)

        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
        text_format.Merge(found_api_spec, if_spec_msg)

        # Instantiate a MirrorObject and return it.
        hal_mirror = MirrorObject(self._client,
                                  if_spec_msg,
                                  None,
                                  interface_id=interface_id)
        return hal_mirror
예제 #13
0
    def CallApi(self, arg, caller_uid=None):
        """RPC to CALL_API."""
        self.SendCommand(SysMsg_pb2.CALL_API, arg=arg, caller_uid=caller_uid)
        resp = self.RecvResponse()
        resp_code = resp.response_code
        if (resp_code == SysMsg_pb2.SUCCESS):
            result = CompSpecMsg_pb2.FunctionSpecificationMessage()
            if resp.result == "error":
                raise errors.VtsTcpCommunicationError(
                    "API call error by the VTS driver.")
            try:
                text_format.Merge(resp.result, result)
            except text_format.ParseError as e:
                logging.exception(e)
                logging.error("Paring error\n%s", resp.result)
            if result.return_type.type == CompSpecMsg_pb2.TYPE_SUBMODULE:
                logging.info("returned a submodule spec")
                logging.info("spec: %s", result.return_type_submodule_spec)
                return mirror_object.MirrorObject(
                    self, result.return_type_submodule_spec, None)

            logging.info("result: %s", result.return_type_hidl)
            if len(result.return_type_hidl) == 1:
                result_value = self.GetPythonDataOfVariableSpecMsg(
                    result.return_type_hidl[0])
            elif len(result.return_type_hidl) > 1:
                result_value = []
                for return_type_hidl in result.return_type_hidl:
                    result_value.append(
                        self.GetPythonDataOfVariableSpecMsg(return_type_hidl))
            else:  # For non-HIDL return value
                if hasattr(result, "return_type"):
                    result_value = result
                else:
                    result_value = None

            if hasattr(result, "raw_coverage_data"):
                return result_value, {"coverage": result.raw_coverage_data}
            else:
                return result_value

        logging.error("NOTICE - Likely a crash discovery!")
        logging.error("SysMsg_pb2.SUCCESS is %s", SysMsg_pb2.SUCCESS)
        raise errors.VtsTcpCommunicationError(
            "RPC Error, response code for %s is %s" % (arg, resp_code))
예제 #14
0
    def GetHidlCallbackInterface(self, interface_name, **kwargs):
        """Gets the ProtoBuf message for a callback interface based on args.

        Args:
            interface_name: string, the callback interface name.
            **kwargs: a dict for the arg name and value pairs

        Returns:
            VariableSpecificationMessage that contains the callback interface
            description.
        """
        var_msg = CompSpecMsg.VariableSpecificationMessage()
        var_msg.name = interface_name
        var_msg.type = CompSpecMsg.TYPE_FUNCTION_POINTER
        var_msg.is_callback = True

        msg = self._if_spec_msg
        specification = self._client.ReadSpecification(
            interface_name, msg.component_class, msg.component_type,
            msg.component_type_version_major, msg.component_type_version_minor,
            msg.package)
        logging.debug("specification: %s", specification)
        interface = getattr(specification, INTERFACE, None)
        apis = getattr(interface, API, [])
        for api in apis:
            function_pointer = None
            if api.name in kwargs:
                function_pointer = kwargs[api.name]
            else:

                def dummy(*args):
                    """Dummy implementation for any callback function."""
                    logging.debug(
                        "Entering dummy implementation"
                        " for callback function: %s", api.name)
                    for arg_index in range(len(args)):
                        logging.debug("arg%s: %s", arg_index, args[arg_index])

                function_pointer = dummy
            func_pt_msg = var_msg.function_pointer.add()
            func_pt_msg.function_name = api.name
            func_pt_msg.id = self.GetCallbackFunctionID(function_pointer)

        return var_msg
예제 #15
0
    def testHidlHandleArgument(self):
        """Test calling APIs in dumpstate HAL server.

        Host side specifies a handle object in resource_manager, ans pass
        it to dumpstate HAL server to write debug message into it.
        Host side then reads part of the debug message.
        """
        # Prepare a VariableSpecificationMessage to specify the handle object
        # that will be passed into the HAL service.
        var_msg = CompSpecMsg.VariableSpecificationMessage()
        var_msg.type = CompSpecMsg.TYPE_HANDLE
        var_msg.handle_value.handle_id = self._writer.handleId

        self._dumpstate.dumpstateBoard(var_msg)
        # Read 1000 bytes to retrieve part of debug message.
        debug_msg = self._reader.readFile(1000)
        logging.info("Below are part of result from dumpstate: ")
        logging.info(debug_msg)
        asserts.assertNotEqual(debug_msg, "")
예제 #16
0
    def setUp(self):
        # Initialize a FMQ on the target-side driver.
        self._sync_client = self.dut.resource.InitFmq(
            data_type="uint16_t",
            sync=True,
            queue_size=self.MAX_NUM_MSG,
            blocking=True,
            client=self.dut.hal.GetTcpClient("tests_msgq"))
        asserts.assertNotEqual(self._sync_client.queueId, -1)

        # Prepare a VariableSpecificationMessage to specify the FMQ that will be
        # passed into the HAL service.
        var_msg = CompSpecMsg.VariableSpecificationMessage()
        var_msg.type = CompSpecMsg.TYPE_FMQ_SYNC
        fmq_val = var_msg.fmq_value.add()
        fmq_val.fmq_id = self._sync_client.queueId
        fmq_val.scalar_type = "uint16_t"
        fmq_val.type = CompSpecMsg.TYPE_SCALAR

        # Call API in the HAL server.
        sync_init_result = self._tests_msgq.configureFmqSyncReadWrite(var_msg)
        asserts.assertTrue(
            sync_init_result,
            "Hal should configure a synchronized queue without error.")

        # Initialize an unsynchronized queue on the server.
        [success,
         self._unsync_client1] = self._tests_msgq.getFmqUnsyncWrite(True)
        asserts.assertTrue(
            success,
            "Hal should configure an unsynchronized queue without error.")
        # An unsynchronized queue is registered successfully on the target driver.
        asserts.assertNotEqual(self._unsync_client1, None)
        asserts.assertNotEqual(self._unsync_client1.queueId, -1)
        # Register another reader.
        self._unsync_client2 = self.dut.resource.InitFmq(
            existing_queue=self._unsync_client1,
            client=self.dut.hal.GetTcpClient("tests_msgq"))
        asserts.assertNotEqual(self._unsync_client2.queueId, -1)
예제 #17
0
    def OpenConventionalHal(self, module_name=None):
        """Opens the target conventional HAL component.

        This is only needed for conventional HAL.

        Args:
            module_name: string, the name of a module to load.
        """
        func_msg = CompSpecMsg.FunctionSpecificationMessage()
        func_msg.name = "#Open"
        logging.debug("remote call %s", func_msg.name)
        if module_name:
            arg = func_msg.arg.add()
            arg.type = CompSpecMsg.TYPE_STRING
            arg.string_value.message = module_name

            func_msg.return_type.type == CompSpecMsg.TYPE_SCALAR
            func_msg.return_type.scalar_type = "int32_t"
        logging.debug("final msg %s", func_msg)

        result = self._client.CallApi(text_format.MessageToString(func_msg),
                                      self.__caller_uid)
        logging.debug(result)
        return result
예제 #18
0
        def RemoteCall(*args, **kwargs):
            """Dynamically calls a remote API and returns the result value."""
            func_msg = self.GetApi(api_name)
            if not func_msg:
                raise MirrorObjectError("api %s unknown", func_msg)

            logging.debug("remote call %s.%s", self._parent_path, api_name)
            logging.info("remote call %s%s", api_name, args)
            if args:
                for arg_msg, value_msg in zip(func_msg.arg, args):
                    logging.debug("arg msg %s", arg_msg)
                    logging.debug("value %s", value_msg)
                    if value_msg is not None:
                        self.ArgToPb(arg_msg, value_msg)

                logging.debug("final msg %s", func_msg)
            else:
                # TODO: use kwargs
                for arg in func_msg.arg:
                    # TODO: handle other
                    if (arg.type == CompSpecMsg.TYPE_SCALAR
                            and arg.scalar_type == "pointer"):
                        arg.scalar_value.pointer = 0
                logging.debug(func_msg)

            if self._parent_path:
                func_msg.parent_path = self._parent_path

            call_msg = CompSpecMsg.FunctionCallMessage()
            if isinstance(self._if_spec_msg,
                          CompSpecMsg.ComponentSpecificationMessage):
                if self._if_spec_msg.component_class:
                    logging.info("component_class %s",
                                 self._if_spec_msg.component_class)
                    call_msg.component_class = self._if_spec_msg.component_class
                    if self._if_spec_msg.component_class == CompSpecMsg.HAL_CONVENTIONAL_SUBMODULE:
                        submodule_name = self._if_spec_msg.original_data_structure_name
                        if submodule_name.endswith("*"):
                            submodule_name = submodule_name[:-1]
                        func_msg.submodule_name = submodule_name
            if self._hal_driver_id is not None:
                call_msg.hal_driver_id = self._hal_driver_id
            call_msg.api.CopyFrom(func_msg)
            result = self._client.CallApi(
                text_format.MessageToString(call_msg), self.__caller_uid)
            logging.debug(result)
            if (isinstance(result, tuple) and len(result) == 2
                    and isinstance(result[1], dict)
                    and "coverage" in result[1]):
                self._last_raw_code_coverage_data = result[1]["coverage"]
                result = result[0]

            if (result and isinstance(result,
                                      CompSpecMsg.VariableSpecificationMessage)
                    and result.type == CompSpecMsg.TYPE_HIDL_INTERFACE):
                if result.hidl_interface_id <= -1:
                    return None
                hal_driver_id = result.hidl_interface_id
                nested_interface_name = result.predefined_type.split("::")[-1]
                logging.debug("Nested interface name: %s",
                              nested_interface_name)
                nested_interface = self.GetHidlNestedInterface(
                    nested_interface_name, hal_driver_id)
                return nested_interface
            return result
예제 #19
0
    def _CreateMirrorObject(self,
                            target_class,
                            target_type,
                            target_version,
                            target_basepaths=_DEFAULT_TARGET_BASE_PATHS,
                            target_package="",
                            target_filename=None,
                            handler_name=None,
                            bits=64):
        """Initiates the driver for a lib on the target device and creates a top
        level MirroObject for it.

        Args:
            target_class: string, the target class name (e.g., lib).
            target_type: string, the target type name (e.g., light, camera).
            target_version: float, the target component version (e.g., 1.0).
            target_basepaths: list of strings, the paths to look for target
                             files in. Default is _DEFAULT_TARGET_BASE_PATHS.
            target_package: . separated string (e.g., a.b.c) to denote the
                            package name of target component.
            target_filename: string, the target file name (e.g., libm.so).
            handler_name: string, the name of the handler. target_type is used
                          by default.
            bits: integer, processor architecture indicator: 32 or 64.

        Raises:
            errors.ComponentLoadingError is raised when error occurs trying to
            create a MirrorObject.
        """
        if bits not in [32, 64]:
            raise error.ComponentLoadingError("Invalid value for bits: %s" % bits)
        client = vts_tcp_client.VtsTcpClient()
        client.Connect(command_port=self._host_command_port)
        if not handler_name:
            handler_name = target_type
        service_name = "vts_driver_%s" % handler_name

        # Get all the libs available on the target.
        lib_list = client.ListHals(target_basepaths)
        if not lib_list:
            raise errors.ComponentLoadingError(
                "Could not find any lib under path %s" % target_basepaths)
        logging.debug(lib_list)

        # Find the corresponding filename for Lib target type.
        if target_filename is not None:
            for name in lib_list:
                if name.endswith(target_filename):
                    target_filename = name
                    break
        else:
          for name in lib_list:
              if target_type in name:
                  # TODO: check more exactly (e.g., multiple hits).
                  target_filename = name

        if not target_filename:
            raise errors.ComponentLoadingError(
                "No file found for target type %s." % target_type)

        # Check whether the requested binder service is already running.
        # if client.CheckDriverService(service_name=service_name):
        #     raise errors.ComponentLoadingError("A driver for %s already exists" %
        #                                        service_name)

        # Launch the corresponding driver of the requested Lib on the target.
        logging.info("Init the driver service for %s", target_type)
        target_class_id = hal_mirror.COMPONENT_CLASS_DICT[target_class.lower()]
        target_type_id = hal_mirror.COMPONENT_TYPE_DICT[target_type.lower()]
        launched = client.LaunchDriverService(
            driver_type=ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_CONVENTIONAL,
            service_name=service_name,
            bits=bits,
            file_path=target_filename,
            target_class=target_class_id,
            target_type=target_type_id,
            target_version=target_version,
            target_package=target_package)

        if not launched:
            raise errors.ComponentLoadingError(
                "Failed to launch driver service %s from file path %s" %
                (target_type, target_filename))

        # Create API spec message.
        found_api_spec = client.ListApis()
        if not found_api_spec:
            raise errors.ComponentLoadingError("No API found for %s" %
                                               service_name)
        logging.debug("Found %d APIs for %s:\n%s", len(found_api_spec),
                      service_name, found_api_spec)
        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
        text_format.Merge(found_api_spec, if_spec_msg)

        # Instantiate a MirrorObject and return it.
        lib_mirror = mirror_object.MirrorObject(client, if_spec_msg, None)
        self._lib_level_mirrors[handler_name] = lib_mirror
    def _CreateMirrorObject(self,
                            target_class,
                            target_type,
                            target_version,
                            target_package=None,
                            target_component_name=None,
                            target_basepaths=_DEFAULT_TARGET_BASE_PATHS,
                            handler_name=None,
                            hw_binder_service_name=None,
                            bits=64):
        """Initiates the driver for a HAL on the target device and creates a top
        level MirroObject for it.

        Also starts the callback server to listen for callback invocations.

        Args:
            target_class: string, the target class name (e.g., hal).
            target_type: string, the target type name (e.g., light, camera).
            target_version: float, the target component version (e.g., 1.0).
            target_package: string, the package name of a HIDL HAL.
            target_component_name: string, the name of a target component.
            target_basepaths: list of strings, the paths to look for target
                             files in. Default is _DEFAULT_TARGET_BASE_PATHS.
            handler_name: string, the name of the handler. target_type is used
                          by default.
            hw_binder_service_name: string, the name of a HW binder service.
            bits: integer, processor architecture indicator: 32 or 64.

        Raises:
            errors.ComponentLoadingError is raised when error occurs trying to
            create a MirrorObject.
        """
        if bits not in [32, 64]:
            raise error.ComponentLoadingError("Invalid value for bits: %s" %
                                              bits)
        self._StartCallbackServer()
        self._client = vts_tcp_client.VtsTcpClient()
        self._client.Connect(command_port=self._host_command_port,
                             callback_port=self._host_callback_port)
        if not handler_name:
            handler_name = target_type
        service_name = "vts_driver_%s" % handler_name

        target_filename = None
        if target_class == "hal_conventional" or target_class == "hal_legacy":
            # Get all the HALs available on the target.
            hal_list = self._client.ListHals(target_basepaths)
            if not hal_list:
                raise errors.ComponentLoadingError(
                    "Could not find any HAL under path %s" % target_basepaths)
            logging.debug(hal_list)

            # Find the corresponding filename for HAL target type.
            for name in hal_list:
                if target_type in name:
                    # TODO: check more exactly (e.g., multiple hits).
                    target_filename = name
            if not target_filename:
                raise errors.ComponentLoadingError(
                    "No file found for HAL target type %s." % target_type)

            # Check whether the requested binder service is already running.
            # if client.CheckDriverService(service_name=service_name):
            #     raise errors.ComponentLoadingError("A driver for %s already exists" %
            #                                        service_name)
        elif target_class == "hal_hidl":
            # TODO: either user the default hw-binder service or start a new
            # service (e.g., if an instrumented binary is used).
            pass

        # Launch the corresponding driver of the requested HAL on the target.
        logging.info("Init the driver service for %s", target_type)
        target_class_id = COMPONENT_CLASS_DICT[target_class.lower()]
        target_type_id = COMPONENT_TYPE_DICT[target_type.lower()]
        driver_type = {
            "hal_conventional": ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_CONVENTIONAL,
            "hal_legacy": ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_LEGACY,
            "hal_hidl": ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_HIDL
        }.get(target_class)

        launched = self._client.LaunchDriverService(
            driver_type=driver_type,
            service_name=service_name,
            bits=bits,
            file_path=target_filename,
            target_class=target_class_id,
            target_type=target_type_id,
            target_version=target_version,
            target_package=target_package,
            target_component_name=target_component_name,
            hw_binder_service_name=hw_binder_service_name)

        if not launched:
            raise errors.ComponentLoadingError(
                "Failed to launch driver service %s from file path %s" %
                (target_type, target_filename))

        # Create API spec message.
        found_api_spec = self._client.ListApis()
        if not found_api_spec:
            raise errors.ComponentLoadingError("No API found for %s" %
                                               service_name)
        logging.debug("Found %d APIs for %s:\n%s", len(found_api_spec),
                      service_name, found_api_spec)
        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
        text_format.Merge(found_api_spec, if_spec_msg)

        # Instantiate a MirrorObject and return it.
        hal_mirror = mirror_object.MirrorObject(self._client, if_spec_msg,
                                                self._callback_server)
        self._hal_level_mirrors[handler_name] = hal_mirror
예제 #21
0
        def RemoteCall(*args, **kwargs):
            """Dynamically calls a remote API and returns the result value."""
            func_msg = self.GetApi(api_name)
            if not func_msg:
                raise MirrorObjectError("api %s unknown", func_msg)

            logging.debug("remote call %s%s", api_name, args)
            if args:
                for arg_msg, value_msg in zip(func_msg.arg, args):
                    logging.debug("arg msg %s", arg_msg)
                    logging.debug("value %s", value_msg)
                    if value_msg is not None:
                        converted_msg = py2pb.Convert(arg_msg, value_msg)
                        if converted_msg is None:
                            raise MirrorObjectError("Failed to convert arg %s",
                                                    value_msg)
                        logging.debug("converted_message: %s", converted_msg)
                        arg_msg.CopyFrom(converted_msg)
            else:
                # TODO: use kwargs
                for arg in func_msg.arg:
                    # TODO: handle other
                    if (arg.type == CompSpecMsg.TYPE_SCALAR
                            and arg.scalar_type == "pointer"):
                        arg.scalar_value.pointer = 0
                logging.debug(func_msg)

            call_msg = CompSpecMsg.FunctionCallMessage()
            if self._if_spec_msg.component_class:
                call_msg.component_class = self._if_spec_msg.component_class
            call_msg.hal_driver_id = self._driver_id
            call_msg.api.CopyFrom(func_msg)
            logging.debug("final msg %s", call_msg)
            results = self._client.CallApi(
                text_format.MessageToString(call_msg), self._caller_uid)
            if (isinstance(results, tuple) and len(results) == 2
                    and isinstance(results[1], dict)
                    and "coverage" in results[1]):
                self._last_raw_code_coverage_data = results[1]["coverage"]
                results = results[0]

            if isinstance(results, list):  # Non-HIDL HAL does not return list.
                # Translate TYPE_HIDL_INTERFACE to halMirror.
                for i, _ in enumerate(results):
                    result = results[i]
                    if (not result or not isinstance(
                            result, CompSpecMsg.VariableSpecificationMessage)):
                        # no need to process the return values.
                        continue

                    if result.type == CompSpecMsg.TYPE_HIDL_INTERFACE:
                        if result.hidl_interface_id <= -1:
                            results[i] = None
                        driver_id = result.hidl_interface_id
                        nested_interface_name = \
                            result.predefined_type.split("::")[-1]
                        logging.debug("Nested interface name: %s",
                                      nested_interface_name)
                        nested_interface = self.GetHalMirrorForInterface(
                            nested_interface_name, driver_id)
                        results[i] = nested_interface
                    elif (result.type == CompSpecMsg.TYPE_FMQ_SYNC
                          or result.type == CompSpecMsg.TYPE_FMQ_UNSYNC):
                        if (result.fmq_value[0].fmq_id == -1):
                            logging.error("Invalid new queue_id.")
                            results[i] = None
                        else:
                            # Retrieve type of data in this FMQ.
                            data_type = None
                            # For scalar, read scalar_type field.
                            if result.fmq_value[0].type == \
                                    CompSpecMsg.TYPE_SCALAR:
                                data_type = result.fmq_value[0].scalar_type
                            # For enum, struct, and union, read predefined_type
                            # field.
                            elif (result.fmq_value[0].type
                                  == CompSpecMsg.TYPE_ENUM
                                  or result.fmq_value[0].type
                                  == CompSpecMsg.TYPE_STRUCT
                                  or result.fmq_value[0].type
                                  == CompSpecMsg.TYPE_UNION):
                                data_type = result.fmq_value[0].predefined_type

                            # Encounter an unknown type in FMQ.
                            if data_type == None:
                                logging.error(
                                    "Unknown type %d in the new FMQ.",
                                    result.fmq_value[0].type)
                                results[i] = None
                                continue
                            sync = result.type == CompSpecMsg.TYPE_FMQ_SYNC
                            fmq_mirror = resource_mirror.ResourceFmqMirror(
                                data_type, sync, self._client,
                                result.fmq_value[0].fmq_id)
                            results[i] = fmq_mirror
                    elif result.type == CompSpecMsg.TYPE_HIDL_MEMORY:
                        if result.hidl_memory_value.mem_id == -1:
                            logging.error("Invalid new mem_id.")
                            results[i] = None
                        else:
                            mem_mirror = resource_mirror.ResourceHidlMemoryMirror(
                                self._client, result.hidl_memory_value.mem_id)
                            results[i] = mem_mirror
                    elif result.type == CompSpecMsg.TYPE_HANDLE:
                        if result.handle_value.handle_id == -1:
                            logging.error("Invalid new handle_id.")
                            results[i] = None
                        else:
                            handle_mirror = resource_mirror.ResourceHidlHandleMirror(
                                self._client, result.handle_value.handle_id)
                            results[i] = handle_mirror
                if len(results) == 1:
                    # single return result, return the value directly.
                    return results[0]
            return results
예제 #22
0
파일: lib_mirror.py 프로젝트: MIPS/test-vts
    def InitLibDriver(self, target_type, target_version, target_package,
                      target_filename, target_basepaths, handler_name, bits):
        """Initiates the driver for a lib on the target device and loads
        the interface specification message.

        Args:
            target_type: string, the target type name (e.g., light, camera).
            target_version: float, the target component version (e.g., 1.0).
            target_package: . separated string (e.g., a.b.c) to denote the
                            package name of target component.
            target_filename: string, the target file name (e.g., libm.so).
            target_basepaths: list of strings, the paths to look for target
                             files in.
            handler_name: string, the name of the handler. target_type is used
                          by default.
            bits: integer, processor architecture indicator: 32 or 64.
        """
        # Get all the libs available on the target.
        lib_list = self._client.ListHals(target_basepaths)
        if not lib_list:
            raise errors.ComponentLoadingError(
                "Could not find any lib under path %s" % target_basepaths)
        logging.debug(lib_list)

        # Find the corresponding filename for Lib target type.
        if target_filename is not None:
            for name in lib_list:
                if name.endswith(target_filename):
                    target_filename = name
                    break
        else:
            for name in lib_list:
                if target_type in name:
                    # TODO: check more exactly (e.g., multiple hits).
                    target_filename = name

        if not target_filename:
            raise errors.ComponentLoadingError(
                "No file found for target type %s." % target_type)

        driver_id = self.LaunchMirrorDriver(
            ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_CONVENTIONAL,
            "lib_shared",
            target_type,
            target_version,
            target_package=target_package,
            target_filename=target_filename,
            handler_name=handler_name,
            bits=bits)

        self._driver_id = driver_id

        #TODO: ListApis assumes only one lib is loaded at a time, need to
        #      figure out a way to get the api_spec when we want to test
        #      multiple libs together.
        found_api_spec = self._client.ListApis()
        if not found_api_spec:
            raise errors.ComponentLoadingError("No API found for %s" %
                                               target_type)
        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
        text_format.Merge(found_api_spec, if_spec_msg)

        self._if_spec_msg = if_spec_msg