mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00:00
android: Fix tool detections
Module-level __getattr__ is not called on the global variable lookup path, rendering it useless for what we want to do here. Instead, use the _AndroidEnvironment class and make it lazy so that we will not raise an exception by just importing the module.
This commit is contained in:
parent
f30fb0b3fd
commit
3f9ce8ba73
@ -19,6 +19,7 @@ Utility functions for working with Android devices through adb.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# pylint: disable=E1103
|
# pylint: disable=E1103
|
||||||
|
import functools
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -88,18 +89,6 @@ INTENT_FLAGS = {
|
|||||||
'ACTIVITY_CLEAR_TASK' : 0x00008000
|
'ACTIVITY_CLEAR_TASK' : 0x00008000
|
||||||
}
|
}
|
||||||
|
|
||||||
# Lazy init of some globals
|
|
||||||
def __getattr__(attr):
|
|
||||||
env = _AndroidEnvironment()
|
|
||||||
|
|
||||||
glob = globals()
|
|
||||||
glob.update(env.paths)
|
|
||||||
try:
|
|
||||||
return glob[attr]
|
|
||||||
except KeyError:
|
|
||||||
raise AttributeError(f"Module '{__name__}' has no attribute '{attr}'")
|
|
||||||
|
|
||||||
|
|
||||||
class AndroidProperties(object):
|
class AndroidProperties(object):
|
||||||
|
|
||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
@ -162,9 +151,12 @@ class ApkInfo(object):
|
|||||||
if path:
|
if path:
|
||||||
self.parse(path)
|
self.parse(path)
|
||||||
|
|
||||||
|
self._aapt = _ANDROID_ENV.get_env('aapt')
|
||||||
|
self._aapt_version = _ANDROID_ENV.get_env('aapt_version')
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
def parse(self, apk_path):
|
def parse(self, apk_path):
|
||||||
output = self._run([aapt, 'dump', 'badging', apk_path])
|
output = self._run([self.aapt, 'dump', 'badging', apk_path])
|
||||||
for line in output.split('\n'):
|
for line in output.split('\n'):
|
||||||
if line.startswith('application-label:'):
|
if line.startswith('application-label:'):
|
||||||
self.label = line.split(':')[1].strip().replace('\'', '')
|
self.label = line.split(':')[1].strip().replace('\'', '')
|
||||||
@ -204,8 +196,8 @@ class ApkInfo(object):
|
|||||||
@property
|
@property
|
||||||
def activities(self):
|
def activities(self):
|
||||||
if self._activities is None:
|
if self._activities is None:
|
||||||
cmd = [aapt, 'dump', 'xmltree', self._apk_path]
|
cmd = [self.aapt, 'dump', 'xmltree', self._apk_path]
|
||||||
if aapt_version == 2:
|
if self._aapt_version == 2:
|
||||||
cmd += ['--file']
|
cmd += ['--file']
|
||||||
cmd += ['AndroidManifest.xml']
|
cmd += ['AndroidManifest.xml']
|
||||||
matched_activities = self.activity_regex.finditer(self._run(cmd))
|
matched_activities = self.activity_regex.finditer(self._run(cmd))
|
||||||
@ -223,7 +215,7 @@ class ApkInfo(object):
|
|||||||
extracted = z.extract('classes.dex', tmp_dir)
|
extracted = z.extract('classes.dex', tmp_dir)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
dexdump = os.path.join(os.path.dirname(aapt), 'dexdump')
|
dexdump = os.path.join(os.path.dirname(self.aapt), 'dexdump')
|
||||||
command = [dexdump, '-l', 'xml', extracted]
|
command = [dexdump, '-l', 'xml', extracted]
|
||||||
dump = self._run(command)
|
dump = self._run(command)
|
||||||
|
|
||||||
@ -725,7 +717,7 @@ def adb_list_devices(adb_server=None, adb_port=None):
|
|||||||
def _get_adb_parts(command, device=None, adb_server=None, adb_port=None, quote_adb=True):
|
def _get_adb_parts(command, device=None, adb_server=None, adb_port=None, quote_adb=True):
|
||||||
_quote = quote if quote_adb else lambda x: x
|
_quote = quote if quote_adb else lambda x: x
|
||||||
parts = (
|
parts = (
|
||||||
adb,
|
_ANDROID_ENV.get_env('adb'),
|
||||||
*(('-H', _quote(adb_server)) if adb_server is not None else ()),
|
*(('-H', _quote(adb_server)) if adb_server is not None else ()),
|
||||||
*(('-P', _quote(str(adb_port))) if adb_port is not None else ()),
|
*(('-P', _quote(str(adb_port))) if adb_port is not None else ()),
|
||||||
*(('-s', _quote(device)) if device is not None else ()),
|
*(('-s', _quote(device)) if device is not None else ()),
|
||||||
@ -778,16 +770,23 @@ def grant_app_permissions(target, package):
|
|||||||
|
|
||||||
|
|
||||||
# Messy environment initialisation stuff...
|
# Messy environment initialisation stuff...
|
||||||
|
|
||||||
class _AndroidEnvironment:
|
class _AndroidEnvironment:
|
||||||
def __init__(self):
|
# Make the initialization lazy so that we don't trigger an exception if the
|
||||||
|
# user imports the module (directly or indirectly) without actually using
|
||||||
|
# anything from it
|
||||||
|
@property
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def env(self):
|
||||||
android_home = os.getenv('ANDROID_HOME')
|
android_home = os.getenv('ANDROID_HOME')
|
||||||
if android_home:
|
if android_home:
|
||||||
paths = self._from_android_home(android_home)
|
env = self._from_android_home(android_home)
|
||||||
else:
|
else:
|
||||||
paths = self._from_adb()
|
env = self._from_adb()
|
||||||
|
|
||||||
self.paths = paths
|
return env
|
||||||
|
|
||||||
|
def get_env(self, name):
|
||||||
|
return self.env[name]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _from_android_home(cls, android_home):
|
def _from_android_home(cls, android_home):
|
||||||
@ -801,7 +800,6 @@ class _AndroidEnvironment:
|
|||||||
'fastboot': os.path.join(platform_tools, 'fastboot'),
|
'fastboot': os.path.join(platform_tools, 'fastboot'),
|
||||||
**cls._init_common(android_home)
|
**cls._init_common(android_home)
|
||||||
}
|
}
|
||||||
return paths
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _from_adb(cls):
|
def _from_adb(cls):
|
||||||
@ -1055,3 +1053,6 @@ class LogcatMonitor(object):
|
|||||||
|
|
||||||
return [line for line in self.get_log()[next_line_num:]
|
return [line for line in self.get_log()[next_line_num:]
|
||||||
if re.match(regexp, line)]
|
if re.match(regexp, line)]
|
||||||
|
|
||||||
|
_ANDROID_ENV = _AndroidEnvironment()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user