From e8e945a700fd4edeca201ecadc5186820a3a859a Mon Sep 17 00:00:00 2001 From: Chris Redpath Date: Fri, 14 Oct 2016 14:35:58 +0100 Subject: [PATCH] Fix adb pull with wildcard on Android v7+ Similarly to other uses of ls, the change to multi-column default output format has confused this API. Add in a similar routine to other objects which use ls, so that we can try to figure out if we have a multi-column default and control the output if so, or just use the plain command if that doesn't work and hope it is still single column output. Signed-off-by: Chris Redpath --- devlib/utils/android.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/devlib/utils/android.py b/devlib/utils/android.py index 93c1fda..a009456 100644 --- a/devlib/utils/android.py +++ b/devlib/utils/android.py @@ -153,6 +153,7 @@ class AdbConnection(object): # adb disconnect is not invoked untill all connections are closed active_connections = defaultdict(int) default_timeout = 10 + ls_command = 'ls' @property def name(self): @@ -161,7 +162,8 @@ class AdbConnection(object): @property @memoized def newline_separator(self): - output = adb_command(self.device, "shell '(ls); echo \"\n$?\"'") + output = adb_command(self.device, + "shell '({}); echo \"\n$?\"'".format(self.ls_command)) if output.endswith('\r\n'): return '\r\n' elif output.endswith('\n'): @@ -169,6 +171,21 @@ class AdbConnection(object): else: raise DevlibError("Unknown line ending") + # Again, we need to handle boards where the default output format from ls is + # single column *and* boards where the default output is multi-column. + # We need to do this purely because the '-1' option causes errors on older + # versions of the ls tool in Android pre-v7. + def _setup_ls(self): + command = "shell '(ls -1); echo \"\n$?\"'" + output = adb_command(self.device, command, timeout=self.timeout) + lines = output.splitlines() + retval = lines[-1].strip() + if int(retval) == 0: + self.ls_command = 'ls -1' + else: + self.ls_command = 'ls' + logger.info("ls command is set to {}".format(self.ls_command)) + def __init__(self, device=None, timeout=None): self.timeout = timeout if timeout is not None else self.default_timeout if device is None: @@ -176,6 +193,7 @@ class AdbConnection(object): self.device = device adb_connect(self.device) AdbConnection.active_connections[self.device] += 1 + self._setup_ls() def push(self, source, dest, timeout=None): if timeout is None: @@ -189,7 +207,7 @@ class AdbConnection(object): # Pull all files matching a wildcard expression if os.path.isdir(dest) and \ ('*' in source or '?' in source): - command = 'shell ls {}'.format(source) + command = 'shell {} {}'.format(self.ls_command, source) output = adb_command(self.device, command, timeout=timeout) for line in output.splitlines(): command = "pull '{}' '{}'".format(line, dest)