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 json 18import logging 19 20from vts.runners.host import const 21from vts.runners.host import errors 22from vts.runners.host import keys 23from vts.utils.python.file import target_file_utils 24from vts.utils.python.hal import hal_service_name_utils 25 26 27def CanRunHidlHalTest(test_instance, 28 dut, 29 shell=None, 30 run_as_compliance_test=False): 31 """Checks HAL precondition of a test instance. 32 33 Args: 34 test_instance: the test instance which inherits BaseTestClass. 35 dut: the AndroidDevice under test. 36 shell: the ShellMirrorObject to execute command on the device. 37 If not specified, the function creates one from dut. 38 run_as_compliance_test: boolean, whether it is a compliance test. 39 40 Returns: 41 True if the precondition is satisfied; False otherwise. 42 """ 43 if shell is None: 44 dut.shell.InvokeTerminal("check_hal_preconditions") 45 shell = dut.shell.check_hal_preconditions 46 47 opt_params = [ 48 keys.ConfigKeys.IKEY_ABI_BITNESS, 49 keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE, 50 keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX, 51 keys.ConfigKeys.IKEY_PRECONDITION_LSHAL, 52 ] 53 test_instance.getUserParams(opt_param_names=opt_params) 54 55 bitness = str(getattr(test_instance, keys.ConfigKeys.IKEY_ABI_BITNESS, "")) 56 57 hwbinder_service_name = str( 58 getattr(test_instance, 59 keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE, "")) 60 if hwbinder_service_name: 61 if not hwbinder_service_name.startswith("android.hardware."): 62 logging.error("The given hwbinder service name %s is invalid.", 63 hwbinder_service_name) 64 else: 65 cmd_results = shell.Execute("ps -A") 66 hwbinder_service_name += "@" 67 if (any(cmd_results[const.EXIT_CODE]) or 68 hwbinder_service_name not in cmd_results[const.STDOUT][0]): 69 logging.warn("The required hwbinder service %s not found.", 70 hwbinder_service_name) 71 return False 72 73 file_path_prefix = getattr(test_instance, "file_path_prefix", "") 74 if file_path_prefix and bitness: 75 logging.debug("FILE_PATH_PREFIX: %s", file_path_prefix) 76 logging.debug("Test bitness: %s", bitness) 77 tag = "_" + bitness + "bit" 78 if tag in file_path_prefix: 79 for path_prefix in file_path_prefix[tag]: 80 if not target_file_utils.Exists(path_prefix, shell): 81 msg = ( 82 "The required file (prefix: {}) for {}-bit testcase " 83 "not found.").format(path_prefix, bitness) 84 logging.warn(msg) 85 return False 86 87 hal = str( 88 getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_LSHAL, "")) 89 if hal: 90 testable, _ = hal_service_name_utils.GetHalServiceName( 91 shell, hal, bitness, run_as_compliance_test) 92 return testable 93 94 logging.debug("Precondition check pass.") 95 return True 96 97def CheckFeaturePrecondition(test_instance, dut, shell=None): 98 """Checks feature precondition of a test instance. 99 100 Args: 101 test_instance: the test instance which inherits BaseTestClass. 102 dut: the AndroidDevice under test. 103 shell: the ShellMirrorObject to execute command on the device. 104 If not specified, the function creates one from dut. 105 106 Returns: 107 True if the devise has the required feature; False otherwise. 108 """ 109 opt_params = [ 110 keys.ConfigKeys.IKEY_PRECONDITION_FEATURE, 111 ] 112 test_instance.getUserParams(opt_param_names=opt_params) 113 114 feature = str( 115 getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_FEATURE, "")) 116 if feature: 117 # If system is not running, needs to start the framework first. 118 if not dut.isFrameworkRunning(): 119 if not dut.start(): 120 logging.warn("Failed to start Android framework.") 121 return False 122 123 if shell is None: 124 dut.shell.InvokeTerminal("check_feature_precondition") 125 shell = dut.shell.check_feature_precondition 126 127 cmd_results = shell.Execute("LD_LIBRARY_PATH= pm list features") 128 if (any(cmd_results[const.EXIT_CODE]) 129 or feature not in cmd_results[const.STDOUT][0]): 130 logging.warn("The required feature %s not found.", feature) 131 return False 132 logging.debug("Feature precondition check pass.") 133 return True 134 135def MeetFirstApiLevelPrecondition(test_instance, dut=None): 136 """Checks first API level precondition of a test instance. 137 138 If the device's ro.product.first_api_level is 0, this function checks 139 ro.build.version.sdk. 140 141 Args: 142 test_instance: the test instance which inherits BaseTestClass. 143 dut: the AndroidDevice under test. 144 145 Returns: 146 True if the device's first API level is greater than or equal to the 147 value of the precondition; False otherwise. 148 """ 149 opt_params = [keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL] 150 test_instance.getUserParams(opt_param_names=opt_params) 151 if not hasattr(test_instance, 152 keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL): 153 return True 154 155 precond_level_attr = getattr( 156 test_instance, keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL, 0) 157 try: 158 precond_level = int(precond_level_attr) 159 except ValueError: 160 logging.error("Cannot parse first API level precondition: %s", 161 precond_level_attr) 162 return True 163 164 if not dut: 165 logging.debug("Read first API level from the first device.") 166 dut = test_instance.android_devices[0] 167 device_level = dut.getLaunchApiLevel(strict=False) 168 if not device_level: 169 logging.error("Cannot read first API level from device. " 170 "Assume it meets the precondition.") 171 return True 172 173 logging.debug("Device's first API level=%d; precondition=%d", device_level, 174 precond_level) 175 return device_level >= precond_level 176 177 178def CheckSysPropPrecondition(test_instance, dut, shell=None): 179 """Checks sysprop precondition of a test instance. 180 181 Args: 182 test_instance: the test instance which inherits BaseTestClass. 183 dut: the AndroidDevice under test. 184 shell: the ShellMirrorObject to execute command on the device. 185 If not specified, the function creates one from dut. 186 187 Returns: 188 False if precondition is not met (i.e., to skip tests), 189 True otherwise (e.g., when no sysprop precondition is set; 190 the precondition is satisfied; 191 there is an error in retrieving the target sysprop; or 192 the specified sysprop is undefined) 193 """ 194 if not hasattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_SYSPROP): 195 return True 196 197 precond_sysprop = str( 198 getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_SYSPROP, '')) 199 if "=" not in precond_sysprop: 200 logging.error("precondition-sysprop value is invalid.") 201 return True 202 203 if shell is None: 204 dut.shell.InvokeTerminal("check_sysprop_precondition") 205 shell = dut.shell.check_sysprop_precondition 206 207 sysprop_key, sysprop_value = precond_sysprop.split('=') 208 cmd_results = shell.Execute('getprop %s' % sysprop_key) 209 if any(cmd_results[const.EXIT_CODE]): 210 logging.error('Failed to read sysprop:\n%s', sysprop_key) 211 return True 212 else: 213 value = cmd_results[const.STDOUT][0].strip() 214 if len(value) == 0: 215 return True 216 elif value != sysprop_value: 217 return False 218 return True 219