mirror of
				https://github.com/ARM-software/devlib.git
				synced 2025-11-04 07:51:21 +00:00 
			
		
		
		
	android/adb: Enable fall back for su command
				
					
				
			Commit 89c40fb switched from using `echo CMD | su` to `su -c CMD`
however not all modern versions of `su` support this format.
Automatically try and detect if the new style is supported when
connecting and if not, fall back to the old implementation.
			
			
This commit is contained in:
		@@ -239,6 +239,7 @@ class AdbConnection(object):
 | 
				
			|||||||
    active_connections = defaultdict(int)
 | 
					    active_connections = defaultdict(int)
 | 
				
			||||||
    default_timeout = 10
 | 
					    default_timeout = 10
 | 
				
			||||||
    ls_command = 'ls'
 | 
					    ls_command = 'ls'
 | 
				
			||||||
 | 
					    su_cmd = 'su -c {}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def name(self):
 | 
					    def name(self):
 | 
				
			||||||
@@ -264,6 +265,7 @@ class AdbConnection(object):
 | 
				
			|||||||
            self.ls_command = 'ls'
 | 
					            self.ls_command = 'ls'
 | 
				
			||||||
        logger.debug("ls command is set to {}".format(self.ls_command))
 | 
					        logger.debug("ls command is set to {}".format(self.ls_command))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # pylint: disable=unused-argument
 | 
					    # pylint: disable=unused-argument
 | 
				
			||||||
    def __init__(self, device=None, timeout=None, platform=None, adb_server=None):
 | 
					    def __init__(self, device=None, timeout=None, platform=None, adb_server=None):
 | 
				
			||||||
        self.timeout = timeout if timeout is not None else self.default_timeout
 | 
					        self.timeout = timeout if timeout is not None else self.default_timeout
 | 
				
			||||||
@@ -274,6 +276,7 @@ class AdbConnection(object):
 | 
				
			|||||||
        adb_connect(self.device)
 | 
					        adb_connect(self.device)
 | 
				
			||||||
        AdbConnection.active_connections[self.device] += 1
 | 
					        AdbConnection.active_connections[self.device] += 1
 | 
				
			||||||
        self._setup_ls()
 | 
					        self._setup_ls()
 | 
				
			||||||
 | 
					        self._setup_su()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def push(self, source, dest, timeout=None):
 | 
					    def push(self, source, dest, timeout=None):
 | 
				
			||||||
        if timeout is None:
 | 
					        if timeout is None:
 | 
				
			||||||
@@ -303,7 +306,7 @@ class AdbConnection(object):
 | 
				
			|||||||
                as_root=False, strip_colors=True, will_succeed=False):
 | 
					                as_root=False, strip_colors=True, will_succeed=False):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            return adb_shell(self.device, command, timeout, check_exit_code,
 | 
					            return adb_shell(self.device, command, timeout, check_exit_code,
 | 
				
			||||||
                             as_root, adb_server=self.adb_server)
 | 
					                             as_root, adb_server=self.adb_server, su_cmd=self.su_cmd)
 | 
				
			||||||
        except TargetStableError as e:
 | 
					        except TargetStableError as e:
 | 
				
			||||||
            if will_succeed:
 | 
					            if will_succeed:
 | 
				
			||||||
                raise TargetTransientError(e)
 | 
					                raise TargetTransientError(e)
 | 
				
			||||||
@@ -326,6 +329,18 @@ class AdbConnection(object):
 | 
				
			|||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _setup_su(self):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            # Try the new style of invoking `su`
 | 
				
			||||||
 | 
					            self.execute('ls', timeout=self.timeout, as_root=True,
 | 
				
			||||||
 | 
					                         check_exit_code=True)
 | 
				
			||||||
 | 
					        # If failure assume either old style or unrooted. Here we will assume
 | 
				
			||||||
 | 
					        # old style and root status will be verified later.
 | 
				
			||||||
 | 
					        except (TargetStableError, TargetTransientError, TimeoutError):
 | 
				
			||||||
 | 
					            self.su_cmd = 'echo {} | su'
 | 
				
			||||||
 | 
					        logger.debug("su command is set to {}".format(quote(self.su_cmd)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def fastboot_command(command, timeout=None, device=None):
 | 
					def fastboot_command(command, timeout=None, device=None):
 | 
				
			||||||
    _check_env()
 | 
					    _check_env()
 | 
				
			||||||
    target = '-s {}'.format(quote(device)) if device else ''
 | 
					    target = '-s {}'.format(quote(device)) if device else ''
 | 
				
			||||||
@@ -423,7 +438,7 @@ def _ping(device):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# pylint: disable=too-many-locals
 | 
					# pylint: disable=too-many-locals
 | 
				
			||||||
def adb_shell(device, command, timeout=None, check_exit_code=False,
 | 
					def adb_shell(device, command, timeout=None, check_exit_code=False,
 | 
				
			||||||
              as_root=False, adb_server=None):  # NOQA
 | 
					              as_root=False, adb_server=None, su_cmd='su -c {}'):  # NOQA
 | 
				
			||||||
    _check_env()
 | 
					    _check_env()
 | 
				
			||||||
    parts = ['adb']
 | 
					    parts = ['adb']
 | 
				
			||||||
    if adb_server is not None:
 | 
					    if adb_server is not None:
 | 
				
			||||||
@@ -431,7 +446,7 @@ def adb_shell(device, command, timeout=None, check_exit_code=False,
 | 
				
			|||||||
    if device is not None:
 | 
					    if device is not None:
 | 
				
			||||||
        parts += ['-s', device]
 | 
					        parts += ['-s', device]
 | 
				
			||||||
    parts += ['shell',
 | 
					    parts += ['shell',
 | 
				
			||||||
              command if not as_root else 'su -c {}'.format(quote(command))]
 | 
					              command if not as_root else su_cmd.format(quote(command))]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger.debug(' '.join(quote(part) for part in parts))
 | 
					    logger.debug(' '.join(quote(part) for part in parts))
 | 
				
			||||||
    # On older combinations of ADB/Android versions, the adb host command always
 | 
					    # On older combinations of ADB/Android versions, the adb host command always
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user