mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-10-31 07:04:17 +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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user