Пример #1
0
def execute_adb_command(adb_cmd, piped_into_cmd=None, ignore_stderr=False):
    final_cmd = ('%s %s' % (_adb_prefix, adb_cmd))
    if piped_into_cmd:
        final_cmd = '%s | %s' % (final_cmd, piped_into_cmd)

    print_verbose("Executing \"%s\"" % final_cmd)
    ps1 = subprocess.Popen(final_cmd,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout_data, stderr_data = ps1.communicate()
    stdout_data = stdout_data.decode('utf-8')
    stderr_data = stderr_data.decode('utf-8')

    _check_for_more_than_one_device_error(stderr_data)
    _check_for_device_not_found_error(stderr_data)
    if not ignore_stderr and stderr_data and len(stderr_data) > 0:
        print_error(stderr_data)

    output = ''
    first_line = True
    if stdout_data:
        for line in stdout_data.split('\n'):
            line = line.strip()
            if not line or len(line) == 0:
                continue
            if first_line:
                output += line
                first_line = False
            else:
                output += '\n' + line
    print_verbose("Result is \"%s\"" % output)
    return output
Пример #2
0
def execute_file_related_adb_shell_command(adb_shell_cmd, file_path, piped_into_cmd=None, ignore_stderr=False,
                                           device_serial=None):
    file_not_found_message = 'No such file or directory'
    is_a_directory_message = 'Is a directory'  # Error when someone tries to delete a dir with "-r"

    adb_cmds_prefix = []
    run_as_package = get_package(file_path)
    if run_as_package:
        adb_cmds_prefix.append('shell run-as %s' % run_as_package)
    if root_required_to_access_file(file_path):
        adb_cmds_prefix.append('shell su root')
    # As a backup, still try with a plain-old access, if run-as is not possible and root is not available.
    adb_cmds_prefix.append('shell')

    stdout = None
    attempt_count = 1
    for adb_cmd_prefix in adb_cmds_prefix:
        print_verbose('Attempt %d/%d: "%s"' % (attempt_count, len(adb_cmds_prefix), adb_cmd_prefix))
        attempt_count += 1
        adb_cmd = '%s %s' % (adb_cmd_prefix, adb_shell_cmd)
        return_code, stdout, stderr = execute_adb_command2(adb_cmd, piped_into_cmd, ignore_stderr,
                                                           device_serial=device_serial)

        if stderr.find(file_not_found_message) >= 0:
            print_error('File not found: %s' % file_path)
            return stderr
        if stderr.find(is_a_directory_message) >= 0:
            print_error('%s is a directory' % file_path)
            return stderr

        api_version = get_device_android_api_version()
        if api_version >= _MIN_VERSION_ABOVE_WHICH_ADB_SHELL_RETURNS_CORRECT_EXIT_CODE and return_code == 0:
            return stdout

    return stdout
Пример #3
0
def _check_for_device_not_found_error(stderr_data):
    if not stderr_data:
        return
    for line in stderr_data.split('\n'):
        line = line.strip()
        if line and len(line) > 0:
            print_verbose(line)
        if line.find('error: device') > -1 and line.find('not found') > -1:
            print_error_and_exit(line)
Пример #4
0
def _check_for_more_than_one_device_error(stderr_data):
    if not stderr_data:
        return
    for line in stderr_data.split('\n'):
        line = line.strip()
        if line and len(line) > 0:
            print_verbose(line)
        if line.find('error: more than one') != -1:
            message = ''
            message += 'More than one device/emulator are connected.\n'
            message += 'Please select a device by providing the serial ID (-s parameter).\n'
            message += 'You can list all connected devices/emulators via \"devices\" subcommand.'
            print_error_and_exit(message)
Пример #5
0
def set_device_id(device_id):
    """
    Make :param device_id: as main device to use
    Primary use-case: scripting
    Command line equivalent: "-s :param device_id:"
    """
    old_adb_prefix = get_adb_prefix()
    if '-s' in old_adb_prefix:
        old_device = old_adb_prefix.split('-s ')[1]
        if ' ' in old_device:
            # Case: device ID is not the last argument
            old_device = old_adb_prefix.split('-s')[1].split(' ')[0]
        print_verbose('Switching from  %s to  %s' % (old_device, device_id))
        old_adb_prefix.replace(old_device, device_id)

    print_verbose('Setting device ID to %s' % device_id)
    set_adb_prefix("%s -s %s" % (old_adb_prefix, device_id))
Пример #6
0
def execute_adb_command2(adb_cmd,
                         piped_into_cmd=None,
                         ignore_stderr=False,
                         device_serial=None):
    adb_prefix = _adb_prefix
    if device_serial:
        adb_prefix = '%s -s %s' % (adb_prefix, device_serial)

    final_cmd = ('%s %s' % (adb_prefix, adb_cmd))
    if piped_into_cmd:
        final_cmd = '%s | %s' % (final_cmd, piped_into_cmd)

    print_verbose("Executing \"%s\"" % final_cmd)
    ps1 = subprocess.Popen(final_cmd,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout_data, stderr_data = ps1.communicate()
    return_code = ps1.returncode
    try:
        stdout_data = stdout_data.decode('utf-8')
    except UnicodeDecodeError:
        print_error(
            'Unable to decode data as UTF-8, defaulting to printing the binary data'
        )
    stderr_data = stderr_data.decode('utf-8')

    _check_for_adb_not_found_error(stderr_data)
    _check_for_more_than_one_device_error(stderr_data)
    _check_for_device_not_found_error(stderr_data)
    if not ignore_stderr and stderr_data:
        print_error(stderr_data)

    if not stdout_data:
        return return_code, None, stderr_data

    # stdout_data is not None
    if isinstance(stdout_data, bytes):
        print_verbose("Result is \"%s\"" % stdout_data)
        return return_code, stdout_data, stderr_data
    # str for Python 3, this used to be unicode type for python 2
    elif isinstance(stdout_data, str):
        output = ''
        first_line = True
        for line in stdout_data.split('\n'):
            line = line.strip()
            if not line:
                continue
            if line in _IGNORED_LINES:
                continue
            if first_line:
                output += line
                first_line = False
            else:
                output += '\n' + line
        print_verbose("Result is \"%s\"" % output)
        return return_code, output, stderr_data
    else:
        print_error_and_exit('stdout_data is weird type: %s' %
                             type(stdout_data))
Пример #7
0
def execute_adb_command(adb_cmd,
                        piped_into_cmd=None,
                        ignore_stderr=False,
                        device_serial=None):
    adb_prefix = _adb_prefix
    if device_serial:
        adb_prefix = '%s -s %s' % (adb_prefix, device_serial)
    final_cmd = ('%s %s' % (adb_prefix, adb_cmd))
    if piped_into_cmd:
        final_cmd = '%s | %s' % (final_cmd, piped_into_cmd)

    print_verbose("Executing \"%s\"" % final_cmd)
    ps1 = subprocess.Popen(final_cmd,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout_data, stderr_data = ps1.communicate()
    try:
        stdout_data = stdout_data.decode('utf-8')
    except UnicodeDecodeError:
        print_error(
            'Unable to decode data as UTF-8, defaulting to printing the binary data'
        )
    stderr_data = stderr_data.decode('utf-8')

    _check_for_adb_not_found_error(stderr_data)
    _check_for_more_than_one_device_error(stderr_data)
    _check_for_device_not_found_error(stderr_data)
    if not ignore_stderr and stderr_data and len(stderr_data) > 0:
        print_error(stderr_data)

    if stdout_data:
        if isinstance(stdout_data, bytes):
            print_verbose("Result is \"%s\"" % stdout_data)
            return stdout_data
        # str for Python 3 and unicode for Python 2
        # unicode is undefined for Python 3
        elif isinstance(stdout_data, (str, unicode)):
            output = ''
            first_line = True
            for line in stdout_data.split('\n'):
                line = line.strip()
                if not line or len(line) == 0:
                    continue
                if line in _IGNORED_LINES:
                    continue
                if first_line:
                    output += line
                    first_line = False
                else:
                    output += '\n' + line
            print_verbose("Result is \"%s\"" % output)
            return output

    return None
Пример #8
0
def execute_adb_command2(adb_cmd,
                         piped_into_cmd=None,
                         ignore_stderr=False,
                         device_serial=None) -> [int, str, str]:
    """
    :param adb_cmd: command to run inside the adb shell (so, don't prefix it with "adb")
    :param piped_into_cmd: command to pipe the output of this command into
    :param ignore_stderr: if true, errors in stderr stream will be ignored while piping commands
    :param device_serial: device serial to send this command to (in case of multiple devices)
    :return: (return_code, stdout, stderr)
    """
    adb_prefix = _adb_prefix
    if device_serial:
        adb_prefix = '%s -s %s' % (adb_prefix, device_serial)

    final_cmd = ('%s %s' % (adb_prefix, adb_cmd))
    if piped_into_cmd:
        final_cmd = '%s | %s' % (final_cmd, piped_into_cmd)

    print_verbose("Executing \"%s\"" % final_cmd)
    with subprocess.Popen(final_cmd,
                          shell=True,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE) as ps1:
        stdout_data, stderr_data = ps1.communicate()
        return_code = ps1.returncode
    try:
        stdout_data = stdout_data.decode('utf-8')
    except UnicodeDecodeError:
        print_error(
            'Unable to decode data as UTF-8, defaulting to printing the binary data'
        )
    stderr_data = stderr_data.decode('utf-8')

    _check_for_adb_not_found_error(stderr_data)
    _check_for_more_than_one_device_error(stderr_data)
    _check_for_device_not_found_error(stderr_data)
    if not ignore_stderr and stderr_data:
        print_error(stderr_data)

    if not stdout_data:
        return return_code, None, stderr_data

    # stdout_data is not None
    if isinstance(stdout_data, bytes):
        print_verbose("Result is \"%s\"" % stdout_data)
        return return_code, stdout_data, stderr_data
    # str for Python 3, this used to be unicode type for python 2
    elif isinstance(stdout_data, str):
        output = ''
        first_line = True
        for line in stdout_data.split('\n'):
            line = line.strip()
            if not line:
                continue
            if line in _IGNORED_LINES:
                continue
            if first_line:
                output += line
                first_line = False
            else:
                output += '\n' + line
        print_verbose("Result is \"%s\"" % output)
        return return_code, output, stderr_data
    else:
        print_error_and_exit('stdout_data is weird type: %s' %
                             type(stdout_data))