mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-10-30 14:44:09 +00:00
Merge pull request #307 from marcbonnici/exact_abi
Modified how apks containing native code are matched to a target devices supported abi(s).
This commit is contained in:
@@ -30,7 +30,7 @@ from wlauto.common.resources import Executable
|
||||
from wlauto.core.resource import NO_ONE
|
||||
from wlauto.common.linux.device import BaseLinuxDevice, PsEntry
|
||||
from wlauto.exceptions import DeviceError, WorkerThreadError, TimeoutError, DeviceNotRespondingError
|
||||
from wlauto.utils.misc import convert_new_lines
|
||||
from wlauto.utils.misc import convert_new_lines, ABI_MAP
|
||||
from wlauto.utils.types import boolean, regex
|
||||
from wlauto.utils.android import (adb_shell, adb_background_shell, adb_list_devices,
|
||||
adb_command, AndroidProperties, ANDROID_VERSION_MAP)
|
||||
@@ -108,19 +108,34 @@ class AndroidDevice(BaseLinuxDevice): # pylint: disable=W0223
|
||||
|
||||
@property
|
||||
def abi(self):
|
||||
return self.getprop()['ro.product.cpu.abi'].split('-')[0]
|
||||
val = self.getprop()['ro.product.cpu.abi'].split('-')[0]
|
||||
for abi, architectures in ABI_MAP.iteritems():
|
||||
if val in architectures:
|
||||
return abi
|
||||
return val
|
||||
|
||||
@property
|
||||
def supported_eabi(self):
|
||||
def supported_abi(self):
|
||||
props = self.getprop()
|
||||
result = [props['ro.product.cpu.abi']]
|
||||
if 'ro.product.cpu.abi2' in props:
|
||||
result.append(props['ro.product.cpu.abi2'])
|
||||
if 'ro.product.cpu.abilist' in props:
|
||||
for eabi in props['ro.product.cpu.abilist'].split(','):
|
||||
if eabi not in result:
|
||||
result.append(eabi)
|
||||
return result
|
||||
for abi in props['ro.product.cpu.abilist'].split(','):
|
||||
if abi not in result:
|
||||
result.append(abi)
|
||||
|
||||
mapped_result = []
|
||||
for supported_abi in result:
|
||||
for abi, architectures in ABI_MAP.iteritems():
|
||||
found = False
|
||||
if supported_abi in architectures and abi not in mapped_result:
|
||||
mapped_result.append(abi)
|
||||
found = True
|
||||
break
|
||||
if not found and supported_abi not in mapped_result:
|
||||
mapped_result.append(supported_abi)
|
||||
return mapped_result
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AndroidDevice, self).__init__(**kwargs)
|
||||
@@ -262,6 +277,24 @@ class AndroidDevice(BaseLinuxDevice): # pylint: disable=W0223
|
||||
return line.split('=', 1)[1]
|
||||
return None
|
||||
|
||||
def get_installed_package_abi(self, package):
|
||||
"""
|
||||
Returns the primary abi of the specified package if it is installed
|
||||
on the device, or ``None`` otherwise.
|
||||
"""
|
||||
output = self.execute('dumpsys package {}'.format(package))
|
||||
val = None
|
||||
for line in convert_new_lines(output).split('\n'):
|
||||
if 'primaryCpuAbi' in line:
|
||||
val = line.split('=', 1)[1]
|
||||
break
|
||||
if val == 'null':
|
||||
return None
|
||||
for abi, architectures in ABI_MAP.iteritems():
|
||||
if val in architectures:
|
||||
return abi
|
||||
return val
|
||||
|
||||
def list_packages(self):
|
||||
"""
|
||||
List packages installed on the device.
|
||||
|
||||
@@ -186,7 +186,7 @@ class ApkWorkload(Workload):
|
||||
'''),
|
||||
Parameter('uninstall_apk', kind=boolean, default=False,
|
||||
description='If ``True``, will uninstall workload\'s APK as part of teardown.'),
|
||||
Parameter('check_abi', kind=bool, default=False,
|
||||
Parameter('exact_abi', kind=bool, default=False,
|
||||
description='''
|
||||
If ``True``, workload will check that the APK matches the target
|
||||
device ABI, otherwise any APK found will be used.
|
||||
@@ -200,8 +200,9 @@ class ApkWorkload(Workload):
|
||||
self.apk_version = None
|
||||
self.logcat_log = None
|
||||
self.exact_apk_version = None
|
||||
self.exact_abi = kwargs.get('exact_abi')
|
||||
|
||||
def setup(self, context):
|
||||
def setup(self, context): # pylint: disable=too-many-branches
|
||||
Workload.setup(self, context)
|
||||
|
||||
# Get target version
|
||||
@@ -213,9 +214,25 @@ class ApkWorkload(Workload):
|
||||
# Get host version
|
||||
self.apk_file = context.resolver.get(ApkFile(self, self.device.abi),
|
||||
version=getattr(self, 'version', None),
|
||||
check_abi=getattr(self, 'check_abi', False),
|
||||
variant_name=getattr(self, 'variant_name', None),
|
||||
strict=False)
|
||||
|
||||
# Get target abi
|
||||
target_abi = self.device.get_installed_package_abi(self.package)
|
||||
if target_abi:
|
||||
self.logger.debug("Found apk with primary abi '{}' on target device".format(target_abi))
|
||||
|
||||
# Get host version, primary abi is first, and then try to find supported.
|
||||
for abi in self.device.supported_abi:
|
||||
self.apk_file = context.resolver.get(ApkFile(self, abi),
|
||||
version=getattr(self, 'version', None),
|
||||
variant_name=getattr(self, 'variant_name', None),
|
||||
strict=False)
|
||||
|
||||
# Stop if apk found, or if exact_abi is set only look for primary abi.
|
||||
if self.apk_file or self.exact_abi:
|
||||
break
|
||||
|
||||
host_version = None
|
||||
if self.apk_file is not None:
|
||||
host_version = ApkInfo(self.apk_file).version_name
|
||||
@@ -233,6 +250,12 @@ class ApkWorkload(Workload):
|
||||
msg = "APK version '{}' not found on the host '{}' or target '{}'"
|
||||
raise ResourceError(msg.format(self.exact_apk_version, host_version, target_version))
|
||||
|
||||
# Error if exact_abi and suitable apk not found on host and incorrect version on device
|
||||
if self.exact_abi and host_version is None:
|
||||
if target_abi != self.device.abi:
|
||||
msg = "APK abi '{}' not found on the host and target is '{}'"
|
||||
raise ResourceError(msg.format(self.device.abi, target_abi))
|
||||
|
||||
# Ensure the apk is setup on the device
|
||||
if self.force_install:
|
||||
self.force_install_apk(context, host_version)
|
||||
|
||||
@@ -136,6 +136,10 @@ class BaseLinuxDevice(Device): # pylint: disable=abstract-method
|
||||
self._abi = val
|
||||
return self._abi
|
||||
|
||||
@property
|
||||
def supported_abi(self):
|
||||
return [self.abi]
|
||||
|
||||
@property
|
||||
def online_cpus(self):
|
||||
val = self.get_sysfile_value('/sys/devices/system/cpu/online')
|
||||
|
||||
Reference in New Issue
Block a user