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