Quickly logs in on an Android device, via adb, using credentials from a CSV file.
Requirements: dialog
(terminal) or zenity
(GUI) for the UI
Configuration:
.user-passwords.csv
user1,password1
user2,password2
#!/usr/bin/env python | |
import csv | |
import os | |
import subprocess | |
USER_PASSWORDS_FILE = '.user-passwords.csv' | |
def list_connected_devices(): | |
output = subprocess.check_output(['adb', 'devices']) | |
for line in output.splitlines()[1:]: # First line is header | |
if not line: | |
continue | |
data = line.split() | |
yield data[0].decode() | |
def list_credentials(): | |
with open(USER_PASSWORDS_FILE, 'r') as fp: | |
for line in csv.reader(fp): | |
yield tuple(line) | |
def _check_command(name): | |
return subprocess.call( | |
['which', name], | |
stderr=subprocess.DEVNULL, | |
stdout=subprocess.DEVNULL) == 0 | |
def _get_prompt_option(): | |
PROMPT_OPTIONS = [ | |
('zenity', True, _prompt_selection_zenity), | |
('dialog', False, _prompt_selection_dialog), | |
] | |
UI_AVAILABLE = bool(os.environ.get('DISPLAY')) | |
for command, require_ui, function in PROMPT_OPTIONS: | |
if require_ui and not UI_AVAILABLE: | |
continue | |
if _check_command(command): | |
return function | |
raise ValueError('Could not find any alternative to show dialogs. ' | |
'Please install either dialog (for terminal UI) or ' | |
'zenity (for graphical UI)') | |
def prompt_selection(choices, title='Your choice'): | |
func = _get_prompt_option() | |
return func(choices, title=title) | |
def _prompt_selection_dialog(choices, title): | |
args = [ | |
'dialog', '--stdout', '--no-tags', | |
'--menu', title, '0', '0', '0' | |
] | |
for item in choices: | |
args += [item, item] | |
output = subprocess.check_output(args) | |
return output.splitlines()[0].decode() | |
def _prompt_selection_zenity(choices, title): | |
args = [ | |
'zenity', '--list', '--hide-header', | |
'--text', title, | |
'--print-column', '1', # Label | |
'--separator', r'\n', | |
'--column', 'Name', | |
] | |
for item in choices: | |
args.append(item) | |
output = subprocess.check_output(args) | |
return output.splitlines()[0].decode() | |
if __name__ == '__main__': | |
device_name = prompt_selection( | |
sorted(list_connected_devices()), | |
title='Select device') | |
passwords = dict(list_credentials()) | |
user_name = prompt_selection( | |
sorted(passwords.keys()), | |
title='Select user credentials') | |
print('Device: {}'.format(device_name)) | |
print('User: {}'.format(user_name)) | |
user_passowrd = passwords[user_name] | |
command = [ | |
'adb', '-s', device_name, 'shell', | |
'input', 'text', user_name, ';', | |
'input', 'keyevent', 'TAB', ';', | |
'input', 'text', user_passowrd, ';', | |
'input', 'keyevent', 'ENTER'] | |
subprocess.check_call(command) |