• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2017 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 vts.runners.host import const
20from vts.runners.host import keys
21from vts.utils.python.common import vintf_utils
22
23
24def FindHalDescription(hal_desc, hal_package_name):
25    """Find a HAL description whose name is hal_package_name from hal_desc."""
26    for hal_full_name in hal_desc:
27        if hal_desc[hal_full_name].hal_name == hal_package_name:
28            return hal_desc[hal_full_name]
29    return None
30
31
32def IsHalRegisteredInVintfXml(hal, vintf_xml, bitness):
33    """Checks whether a HAL is registered in a VINTF XML.
34
35    If the given hal is an earlier minor version of what is specified in
36    vintf_xml, it returns True.
37
38    Args:
39        hal: string, the full name of a HAL (e.g., package@version)
40        vintf_xml: string, the VINTF XML content.
41        bitness, string, currently tested ABI bitness (e.g., 32 or 64).
42
43    Returns:
44        True if found or vintf_xml is malformed, False otherwise.
45    """
46    result = True
47    if "@" not in hal:
48        logging.error("HAL full name is invalid, %s", hal)
49        return False
50    hal_package, hal_version = hal.split("@")
51    logging.info("HAL package, version = %s, %s", hal_package, hal_version)
52    hal_version_major, hal_version_minor = vintf_utils.ParseHalVersion(
53        hal_version)
54
55    hwbinder_hals, passthrough_hals = vintf_utils.GetHalDescriptions(
56        vintf_xml)
57    hwbinder_hal_desc = FindHalDescription(hwbinder_hals, hal_package)
58    passthrough_hal_desc = FindHalDescription(passthrough_hals, hal_package)
59    if not hwbinder_hals or not passthrough_hals:
60        logging.error("can't check precondition due to a "
61                  "VINTF XML format error.")
62        # Assume it's satisfied.
63        return True
64    elif (hwbinder_hal_desc is None and passthrough_hal_desc is None):
65        logging.warn(
66            "The required HAL %s not found in VINTF XML.",
67            hal)
68        return False
69    elif (hwbinder_hal_desc is None and passthrough_hal_desc is not None):
70        if bitness:
71            if (bitness not in passthrough_hal_desc.hal_archs):
72                logging.warn(
73                    "The required feature %s found as a "
74                    "passthrough HAL but the client bitness %s "
75                    "unsupported",
76                    hal, bitness)
77                result = False
78        hal_desc = passthrough_hal_desc
79    else:
80        hal_desc = hwbinder_hal_desc
81        logging.info(
82            "The feature %s found in VINTF XML", hal)
83    found_version_major = hal_desc.hal_version_major
84    found_version_minor = hal_desc.hal_version_minor
85    if (hal_version_major != found_version_major or
86        hal_version_minor > found_version_minor):
87        logging.warn(
88            "The found HAL version %s@%s is not relevant for %s",
89            found_version_major, found_version_minor, hal_version)
90        result = False
91    return result
92
93
94def CanRunHidlHalTest(test_instance, dut, shell=None):
95    """Checks HAL precondition of a test instance.
96
97    Args:
98        test_instance: the test instance which inherits BaseTestClass.
99        dut: the AndroidDevice under test.
100        shell: the ShellMirrorObject to execute command on the device.
101               If not specified, the function creates one from dut.
102
103    Returns:
104        True if the precondition is satisfied; False otherwise.
105    """
106    if shell is None:
107        dut.shell.InvokeTerminal("check_hal_preconditions")
108        shell = dut.shell.check_hal_preconditions
109
110    opt_params = [
111        keys.ConfigKeys.IKEY_ABI_BITNESS,
112        keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE,
113        keys.ConfigKeys.IKEY_PRECONDITION_FEATURE,
114        keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX,
115        keys.ConfigKeys.IKEY_PRECONDITION_LSHAL,
116        keys.ConfigKeys.IKEY_PRECONDITION_VINTF,
117    ]
118    test_instance.getUserParams(opt_param_names=opt_params)
119
120    hwbinder_service_name = str(getattr(test_instance,
121        keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE, ""))
122    if hwbinder_service_name:
123        if not hwbinder_service_name.startswith("android.hardware."):
124            logging.error("The given hwbinder service name %s is invalid.",
125                          hwbinder_service_name)
126        else:
127            cmd_results = shell.Execute("ps -A")
128            hwbinder_service_name += "@"
129            if (any(cmd_results[const.EXIT_CODE]) or
130                hwbinder_service_name not in cmd_results[const.STDOUT][0]):
131                logging.warn("The required hwbinder service %s not found.",
132                             hwbinder_service_name)
133                return False
134
135    feature = str(getattr(test_instance,
136        keys.ConfigKeys.IKEY_PRECONDITION_FEATURE, ""))
137    if feature:
138        if not feature.startswith("android.hardware."):
139            logging.error(
140                "The given feature name %s is invalid for HIDL HAL.",
141                feature)
142        else:
143            cmd_results = shell.Execute("pm list features")
144            if (any(cmd_results[const.EXIT_CODE]) or
145                feature not in cmd_results[const.STDOUT][0]):
146                logging.warn("The required feature %s not found.",
147                             feature)
148                return False
149
150    file_path_prefix = str(getattr(test_instance,
151        keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX, ""))
152    if file_path_prefix:
153        cmd_results = shell.Execute("ls %s*" % file_path_prefix)
154        if any(cmd_results[const.EXIT_CODE]):
155            logging.warn("The required file (prefix: %s) not found.",
156                         file_path_prefix)
157            return False
158
159    hal = str(getattr(test_instance,
160        keys.ConfigKeys.IKEY_PRECONDITION_VINTF, ""))
161    vintf_xml = None
162    if hal:
163        use_lshal = False
164        vintf_xml = dut.getVintfXml(use_lshal=use_lshal)
165        logging.debug("precondition-vintf used to retrieve VINTF xml.")
166    else:
167        use_lshal = True
168        hal = str(getattr(test_instance,
169            keys.ConfigKeys.IKEY_PRECONDITION_LSHAL, ""))
170        if hal:
171            vintf_xml = dut.getVintfXml(use_lshal=use_lshal)
172            logging.debug("precondition-lshal used to retrieve VINTF xml.")
173
174    if vintf_xml:
175        result = IsHalRegisteredInVintfXml(hal, vintf_xml,
176                                           test_instance.abi_bitness)
177        if not result and use_lshal:
178            # this is for when a test is configured to use the runtime HAL
179            # service availability (the default mode for HIDL tests).
180            # if a HAL is in vendor/manifest.xml, test is supposed to fail
181            # even though a respective HIDL HAL service is not running.
182            vintf_xml = dut.getVintfXml(use_lshal=False)
183            return IsHalRegisteredInVintfXml(hal, vintf_xml,
184                                             test_instance.abi_bitness)
185        return result
186
187    return True
188