187 lines
7.3 KiB
Python
187 lines
7.3 KiB
Python
#
|
|
# Copyright (C) 2017 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
import logging
|
|
|
|
from vts.runners.host import const
|
|
from vts.runners.host import keys
|
|
from vts.utils.python.common import vintf_utils
|
|
|
|
|
|
def FindHalDescription(hal_desc, hal_package_name):
|
|
"""Find a HAL description whose name is hal_package_name from hal_desc."""
|
|
for hal_full_name in hal_desc:
|
|
if hal_desc[hal_full_name].hal_name == hal_package_name:
|
|
return hal_desc[hal_full_name]
|
|
return None
|
|
|
|
|
|
def IsHalRegisteredInVintfXml(hal, vintf_xml, bitness):
|
|
"""Checks whether a HAL is registered in a VINTF XML.
|
|
|
|
If the given hal is an earlier minor version of what is specified in
|
|
vintf_xml, it returns True.
|
|
|
|
Args:
|
|
hal: string, the full name of a HAL (e.g., package@version)
|
|
vintf_xml: string, the VINTF XML content.
|
|
bitness, string, currently tested ABI bitness (e.g., 32 or 64).
|
|
|
|
Returns:
|
|
True if found or vintf_xml is malformed, False otherwise.
|
|
"""
|
|
result = True
|
|
if "@" not in hal:
|
|
logging.error("HAL full name is invalid, %s", hal)
|
|
return False
|
|
hal_package, hal_version = hal.split("@")
|
|
logging.info("HAL package, version = %s, %s", hal_package, hal_version)
|
|
hal_version_major, hal_version_minor = vintf_utils.ParseHalVersion(
|
|
hal_version)
|
|
|
|
hwbinder_hals, passthrough_hals = vintf_utils.GetHalDescriptions(
|
|
vintf_xml)
|
|
hwbinder_hal_desc = FindHalDescription(hwbinder_hals, hal_package)
|
|
passthrough_hal_desc = FindHalDescription(passthrough_hals, hal_package)
|
|
if not hwbinder_hals or not passthrough_hals:
|
|
logging.error("can't check precondition due to a "
|
|
"VINTF XML format error.")
|
|
# Assume it's satisfied.
|
|
return True
|
|
elif (hwbinder_hal_desc is None and passthrough_hal_desc is None):
|
|
logging.warn(
|
|
"The required HAL %s not found in VINTF XML.",
|
|
hal)
|
|
return False
|
|
elif (hwbinder_hal_desc is None and passthrough_hal_desc is not None):
|
|
if bitness:
|
|
if (bitness not in passthrough_hal_desc.hal_archs):
|
|
logging.warn(
|
|
"The required feature %s found as a "
|
|
"passthrough HAL but the client bitness %s "
|
|
"unsupported",
|
|
hal, bitness)
|
|
result = False
|
|
hal_desc = passthrough_hal_desc
|
|
else:
|
|
hal_desc = hwbinder_hal_desc
|
|
logging.info(
|
|
"The feature %s found in VINTF XML", hal)
|
|
found_version_major = hal_desc.hal_version_major
|
|
found_version_minor = hal_desc.hal_version_minor
|
|
if (hal_version_major != found_version_major or
|
|
hal_version_minor > found_version_minor):
|
|
logging.warn(
|
|
"The found HAL version %s@%s is not relevant for %s",
|
|
found_version_major, found_version_minor, hal_version)
|
|
result = False
|
|
return result
|
|
|
|
|
|
def CanRunHidlHalTest(test_instance, dut, shell=None):
|
|
"""Checks HAL precondition of a test instance.
|
|
|
|
Args:
|
|
test_instance: the test instance which inherits BaseTestClass.
|
|
dut: the AndroidDevice under test.
|
|
shell: the ShellMirrorObject to execute command on the device.
|
|
If not specified, the function creates one from dut.
|
|
|
|
Returns:
|
|
True if the precondition is satisfied; False otherwise.
|
|
"""
|
|
if shell is None:
|
|
dut.shell.InvokeTerminal("check_hal_preconditions")
|
|
shell = dut.shell.check_hal_preconditions
|
|
|
|
opt_params = [
|
|
keys.ConfigKeys.IKEY_ABI_BITNESS,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_FEATURE,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_LSHAL,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_VINTF,
|
|
]
|
|
test_instance.getUserParams(opt_param_names=opt_params)
|
|
|
|
hwbinder_service_name = str(getattr(test_instance,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE, ""))
|
|
if hwbinder_service_name:
|
|
if not hwbinder_service_name.startswith("android.hardware."):
|
|
logging.error("The given hwbinder service name %s is invalid.",
|
|
hwbinder_service_name)
|
|
else:
|
|
cmd_results = shell.Execute("ps -A")
|
|
hwbinder_service_name += "@"
|
|
if (any(cmd_results[const.EXIT_CODE]) or
|
|
hwbinder_service_name not in cmd_results[const.STDOUT][0]):
|
|
logging.warn("The required hwbinder service %s not found.",
|
|
hwbinder_service_name)
|
|
return False
|
|
|
|
feature = str(getattr(test_instance,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_FEATURE, ""))
|
|
if feature:
|
|
if not feature.startswith("android.hardware."):
|
|
logging.error(
|
|
"The given feature name %s is invalid for HIDL HAL.",
|
|
feature)
|
|
else:
|
|
cmd_results = shell.Execute("pm list features")
|
|
if (any(cmd_results[const.EXIT_CODE]) or
|
|
feature not in cmd_results[const.STDOUT][0]):
|
|
logging.warn("The required feature %s not found.",
|
|
feature)
|
|
return False
|
|
|
|
file_path_prefix = str(getattr(test_instance,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX, ""))
|
|
if file_path_prefix:
|
|
cmd_results = shell.Execute("ls %s*" % file_path_prefix)
|
|
if any(cmd_results[const.EXIT_CODE]):
|
|
logging.warn("The required file (prefix: %s) not found.",
|
|
file_path_prefix)
|
|
return False
|
|
|
|
hal = str(getattr(test_instance,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_VINTF, ""))
|
|
vintf_xml = None
|
|
if hal:
|
|
use_lshal = False
|
|
vintf_xml = dut.getVintfXml(use_lshal=use_lshal)
|
|
logging.debug("precondition-vintf used to retrieve VINTF xml.")
|
|
else:
|
|
use_lshal = True
|
|
hal = str(getattr(test_instance,
|
|
keys.ConfigKeys.IKEY_PRECONDITION_LSHAL, ""))
|
|
if hal:
|
|
vintf_xml = dut.getVintfXml(use_lshal=use_lshal)
|
|
logging.debug("precondition-lshal used to retrieve VINTF xml.")
|
|
|
|
if vintf_xml:
|
|
result = IsHalRegisteredInVintfXml(hal, vintf_xml,
|
|
test_instance.abi_bitness)
|
|
if not result and use_lshal:
|
|
# this is for when a test is configured to use the runtime HAL
|
|
# service availability (the default mode for HIDL tests).
|
|
# if a HAL is in vendor/manifest.xml, test is supposed to fail
|
|
# even though a respective HIDL HAL service is not running.
|
|
vintf_xml = dut.getVintfXml(use_lshal=False)
|
|
return IsHalRegisteredInVintfXml(hal, vintf_xml,
|
|
test_instance.abi_bitness)
|
|
return result
|
|
|
|
return True
|