Beispiel #1
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))
Beispiel #2
0
def get_device_android_api_version(device_serial=None):
    version_string = get_adb_shell_property('ro.build.version.sdk',
                                            device_serial=device_serial)
    if version_string is None:
        print_error_and_exit(
            'Unable to get Android device version, is it still connected?')
    return int(version_string)
Beispiel #3
0
def _fail_with_python2_warning():
    msg = (
        'You are using Python 2\nADB-enhanced no longer supports Python 2.\n' +
        'Install Python 3 and then re-install this tool using\n' +
        '\"sudo pip uninstall adb-enhanced && sudo pip3 install adb-enhanced\"'
    )
    print_error_and_exit(msg)
Beispiel #4
0
def _check_for_adb_not_found_error(stderr_data):
    if not stderr_data:
        return
    stderr_data = stderr_data.strip()
    if stderr_data.endswith('%s: command not found' % _adb_prefix):
        message = 'ADB (Android debug bridge) command not found.\n'
        message += 'Install ADB via https://developer.android.com/studio/releases/platform-tools.html'
        print_error_and_exit(message)
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)
Beispiel #6
0
def validate_options(args):
    count = 0
    if args['--emulator']:
        count += 1
    if args['--device']:
        count += 1
    if args['--serial']:
        count += 1
    if count > 1:
        print_error_and_exit('Only one out of -e, -d, or -s can be provided')
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)
Beispiel #8
0
def main():
    if _using_python2():
        _fail_with_python2_warning()

    args = docopt.docopt(USAGE_STRING, version=get_version())
    set_verbose(args['--verbose'])

    validate_options(args)
    options = get_generic_options_from_args(args)
    if options:
        adb_prefix = '%s %s' % (adb_helper.get_adb_prefix(), options)
        adb_helper.set_adb_prefix(adb_prefix)

    # rotate
    if args['rotate'] and args['portrait']:
        adb_enhanced.handle_rotate('portrait')
    elif args['rotate'] and args['landscape']:
        adb_enhanced.handle_rotate('landscape')
    elif args['rotate'] and args['left']:
        adb_enhanced.handle_rotate('left')
    elif args['rotate'] and args['right']:
        adb_enhanced.handle_rotate('right')

    # gfx
    elif args['gfx'] and args['on']:
        adb_enhanced.handle_gfx('on')
    elif args['gfx'] and args['off']:
        adb_enhanced.handle_gfx('off')
    elif args['gfx'] and args['lines']:
        adb_enhanced.handle_gfx('lines')

    # overdraw
    elif args['overdraw'] and args['on']:
        adb_enhanced.handle_overdraw('on')
    elif args['overdraw'] and args['off']:
        adb_enhanced.handle_overdraw('off')
    elif args['overdraw'] and args['deut']:
        adb_enhanced.handle_overdraw('deut')

    elif args['layout']:
        adb_enhanced.handle_layout(args['on'])
    elif args['airplane']:  # This command does not always work
        adb_enhanced.handle_airplane(args['on'])

    # battery
    elif args['battery'] and args['saver']:
        adb_enhanced.handle_battery_saver(args['on'])
    elif args['battery'] and args['level']:
        adb_enhanced.handle_battery_level(int(args['<percentage>']))
    elif args['battery'] and args['reset']:
        adb_enhanced.handle_battery_reset()

    elif args['doze']:
        adb_enhanced.handle_doze(args['on'])
    elif args['jank']:
        adb_enhanced.handle_get_jank(args['<app_name>'])
    elif args['devices']:
        adb_enhanced.handle_list_devices()
    elif args['top-activity']:
        adb_enhanced.print_top_activity()
    elif args['dump-ui']:
        adb_enhanced.dump_ui(args['<xml_file>'])
    elif args['force-stop']:
        app_name = args['<app_name>']
        adb_enhanced.force_stop(app_name)
    elif args['clear-data']:
        app_name = args['<app_name>']
        adb_enhanced.clear_disk_data(app_name)

    # mobile-data
    elif args['mobile-data'] and args['saver']:
        adb_enhanced.handle_mobile_data_saver(args['on'])
    elif args['mobile-data']:
        adb_enhanced.handle_mobile_data(args['on'])

    elif args['wifi']:
        adb_enhanced.set_wifi(args['on'])

    elif args['rtl']:  # This is not working as expected
        adb_enhanced.force_rtl(args['on'])
    elif args['screenshot']:
        adb_enhanced.dump_screenshot(args['<filename.png>'])
    elif args['screenrecord']:
        adb_enhanced.dump_screenrecord(args['<filename.mp4>'])
    elif args['dont-keep-activities']:
        adb_enhanced.handle_dont_keep_activities_in_background(args['on'])
    elif args['animations']:
        adb_enhanced.toggle_animations(args['on'])
    elif args['show-taps']:
        adb_enhanced.toggle_show_taps(args['on'])
    elif args['stay-awake-while-charging']:
        # Keep screen on while the device is charging.
        adb_enhanced.stay_awake_while_charging(args['on'])
    elif args['input-text']:
        adb_enhanced.input_text(args['<text>'])
    elif args['back']:
        adb_enhanced.press_back()
    elif args['open-url']:
        url = args['<url>']
        adb_enhanced.open_url(url)
    elif args['permission-groups'] and args['list'] and args['all']:
        adb_enhanced.list_permission_groups()
    elif args['permissions'] and args['list']:
        adb_enhanced.list_permissions(args['dangerous'])
    elif args['permissions']:
        app_name = args['<app_name>']
        permission_group = adb_enhanced.get_permission_group(args)

        permissions = adb_enhanced.get_permissions_in_permission_group(permission_group)
        if not permissions and \
                adb_enhanced.is_permission_group_unavailable_after_api_29(permission_group) and \
                adb_enhanced.get_device_android_api_version() >= 29:
            print_error_and_exit('Android has made contacts group empty on API 29 and beyond, '
                                 'your device version is %d' %
                                 adb_enhanced.get_device_android_api_version())
        elif not permissions:
            print_error_and_exit('No permissions found in permissions group: %s' % permission_group)
        adb_enhanced.grant_or_revoke_runtime_permissions(
            app_name, args['grant'], permissions)

    elif args['notifications'] and args['list']:
        adb_enhanced.print_notifications()

    # apps list
    elif args['apps'] and args['list'] and args['all']:
        adb_enhanced.print_list_all_apps()
    elif args['apps'] and args['list'] and args['system']:
        adb_enhanced.list_system_apps()
    elif args['apps'] and args['list'] and args['third-party']:
        adb_enhanced.print_list_non_system_apps()
    elif args['apps'] and args['list'] and args['debug']:
        adb_enhanced.list_debug_apps()
    elif args['apps'] and args['list'] and args['backup-enabled']:
        adb_enhanced.list_allow_backup_apps()

    # standby bucket
    elif args['standby-bucket'] and args['get']:
        adb_enhanced.get_standby_bucket(args['<app_name>'])
    elif args['standby-bucket'] and args['set']:
        adb_enhanced.set_standby_bucket(args['<app_name>'], adb_enhanced.calculate_standby_mode(args))

    elif args['restrict-background']:
        adb_enhanced.apply_or_remove_background_restriction(args['<app_name>'], args['true'])
    elif args['ls']:
        file_path = args['<file_path>']
        long_format = args['-l']
        # Always include hidden files, -a is left for backward-compatibility but is a no-op now.
        include_hidden_files = True
        recursive = args['-R'] or args['-r']
        adb_enhanced.list_directory(file_path, long_format, recursive, include_hidden_files)
    elif args['rm']:
        file_path = args['<file_path>']
        force_delete = args['-f']
        recursive = args['-R'] or args['-r']
        adb_enhanced.delete_file(file_path, force_delete, recursive)
    elif args['mv']:
        src_path = args['<src_path>']
        dest_path = args['<dest_path>']
        force_move = args['-f']
        adb_enhanced.move_file(src_path, dest_path, force_move)
    elif args['pull']:
        remote_file_path = args['<file_path_on_android>']
        local_file_path = args['<file_path_on_machine>']
        copy_ancillary = args['-a']
        adb_enhanced.pull_file(remote_file_path, local_file_path, copy_ancillary)
    elif args['push']:
        remote_file_path = args['<file_path_on_android>']
        local_file_path = args['<file_path_on_machine>']
        adb_enhanced.push_file(local_file_path, remote_file_path)
    elif args['cat']:
        file_path = args['<file_path>']
        adb_enhanced.cat_file(file_path)
    elif args['start']:
        adb_enhanced.launch_app(args['<app_name>'])
    elif args['stop']:
        adb_enhanced.stop_app(args['<app_name>'])
    elif args['restart']:
        app_name = args['<app_name>']
        adb_enhanced.force_stop(app_name)
        adb_enhanced.launch_app(app_name)

    # app
    elif args['app'] and args['info']:
        adb_enhanced.print_app_info(args['<app_name>'])
    elif args['app'] and args['path']:
        adb_enhanced.print_app_path(args['<app_name>'])
    elif args['app'] and args['signature']:
        adb_enhanced.print_app_signature(args['<app_name>'])
    elif args['app'] and args['backup']:
        app_name = args['<app_name>']
        backup_tar_file_path = args['<backup_tar_file_path>']
        if not backup_tar_file_path:
            backup_tar_file_path = '%s_backup.tar' % app_name
        adb_enhanced.perform_app_backup(app_name, backup_tar_file_path)

    # dark mode
    elif args['dark'] and args['mode']:
        if args['on']:
            adb_enhanced.set_dark_mode(True)
        elif args['off']:
            adb_enhanced.set_dark_mode(False)

    elif args['screen'] and args['on']:
        adb_enhanced.switch_screen(adb_enhanced.SCREEN_ON)
    elif args['screen'] and args['off']:
        adb_enhanced.switch_screen(adb_enhanced.SCREEN_OFF)
    elif args['screen'] and args['toggle']:
        adb_enhanced.switch_screen(adb_enhanced.SCREEN_TOGGLE)

    elif args['install']:
        file_path = args['<file_path>']
        adb_enhanced.perform_install(file_path)
    elif args['uninstall']:
        adb_enhanced.perform_uninstall(args['<app_name>'], args['--first-user'])

    elif args['enable']:
        if args['wireless'] and args['debugging']:
            adb_enhanced.enable_wireless_debug()

    elif args['disable']:
        if args['wireless'] and args['debugging']:
            adb_enhanced.disable_wireless_debug()

    # alarm
    elif args['alarm'] and args['all']:
        adb_enhanced.alarm_manager(adb_enhanced.AlarmEnum.ALL)
    elif args['alarm'] and args['history']:
        adb_enhanced.alarm_manager(adb_enhanced.AlarmEnum.HISTORY)
    elif args['alarm'] and args['pending']:
        adb_enhanced.alarm_manager(adb_enhanced.AlarmEnum.PENDING)
    elif args['alarm'] and args['top']:
        adb_enhanced.alarm_manager(adb_enhanced.AlarmEnum.TOP)

    else:
        print_error_and_exit('Not implemented: "%s"' % ' '.join(sys.argv))
Beispiel #9
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))