Skip to content

Instantly share code, notes, and snippets.

@jadkik
Created December 20, 2015 12:12
Show Gist options
  • Save jadkik/91b4074593c9496ef411 to your computer and use it in GitHub Desktop.
Save jadkik/91b4074593c9496ef411 to your computer and use it in GitHub Desktop.
A small tool to manipulate your phone without a working touchscreen. Install [TouchControl](https://github.com/ternes3/TouchControl-for-Android) to see what happens on your screen as it's happening.
#!/usr/bin/env python3
import os
import sys
import readline
import atexit
from collections import defaultdict
def completer(funcs):
completionhelper = dict()
def thecompleter(text, state):
a = completionhelper.get(text, None)
if a is not None:
return a[state] if state < len(a) else None
a = [f for f in funcs if f.startswith(text)]
completionhelper[text] = a
return a[0] if len(a) > 0 else None
return thecompleter
histfile = os.path.join(os.path.expanduser("~"), ".android_broken_screen_history")
def with_history(funcs):
global histfile
try:
readline.read_history_file(histfile)
except IOError:
pass
atexit.register(readline.write_history_file, histfile)
readline.parse_and_bind("tab: complete")
readline.set_completer(completer(funcs))
def shell(*args):
a = 'adb shell input ' + ' '.join(map(str, args))
print(a, file=sys.stderr)
os.system(a)
def run(*args):
a = 'adb shell ' + ' '.join(map(str, args))
print(a, file=sys.stderr)
os.system(a)
DEFAULT_DURATION = 300
tab = lambda: shell('keyevent', 61)
enter = lambda: shell('keyevent', 66)
back = lambda: shell('keyevent', 4)
power = lambda: shell('keyevent', 26)
home = lambda: shell('keyevent', 3)
volumeup = lambda: shell('keyevent', 24)
volumedown = lambda: shell('keyevent', 25)
up = lambda: shell('keyevent', 19)
down = lambda: shell('keyevent', 20)
left = lambda: shell('keyevent', 21)
right = lambda: shell('keyevent', 22)
swipe = lambda x1, y1, x2, y2, duration=DEFAULT_DURATION: shell('swipe', x1, y1, x2, y2, duration)
hswipe = lambda y, x1, x2, duration=DEFAULT_DURATION: swipe(x1, y, x2, y, duration)
vswipe = lambda x, y1, y2, duration=DEFAULT_DURATION: swipe(x, y1, x, y2, duration)
tap = lambda x, y: shell('tap', x, y)
longpress = lambda x, y, duration=DEFAULT_DURATION: swipe(x, y, x, y, duration)
notification = lambda midx, maxy, duration=DEFAULT_DURATION: vswipe(midx, 0, maxy, duration)
def write(s):
ss = s.split()
for p in ss[:-1]:
shell('text', p) # one word
shell('keyevent', 62) # one space
if len(ss) >= 1:
shell('text', ss[-1]) # last word
allowed_funcs = frozenset((
'shell', 'run',
'write', 'notification',
'hswipe', 'vswipe', 'swipe', 'tap', 'longpress',
'tab', 'enter', 'back', 'power', 'home', 'volumeup', 'volumedown',
'up', 'down', 'left', 'right'
))
if __name__ == '__main__':
try:
try:
resolution = tuple(map(int, input('Resolution (e.g. 1920x1080): ').split('x', 1)))
except (KeyboardInterrupt, EOFError) as e:
raise
except:
resolution = (1920, 1080)
print('Using default resolution', resolution)
else:
print('Using custom resolution', resolution)
print('WARNING: be careful what you write. You may execute arbitrary code on your PC or your Android device if you are not careful (or are malicious).')
input('Press enter if you know what you are doing. Ctrl-C otherwise.')
print('Checking adb devices')
try:
os.system('adb devices')
except:
print('Nope.')
raise
with_history(allowed_funcs)
while True:
cmd = input('> ')
func, *params = cmd.split(None, 1)
params = params[0] if params else ''
if func not in allowed_funcs:
print('Unknown command', func)
continue
elif func == 'help':
print(' '.join(allowed_funcs))
continue
if func == 'write':
write(params)
elif func == 'notification':
try:
midx, maxy = map(int, params.split(None, 1))
except:
midx, maxy = int(resolution[1]/2), int(resolution[0] - 100)
notification(midx, maxy)
elif func in ('tab', 'enter', 'back', 'power', 'home', 'volumeup', 'volumedown', 'up', 'down', 'left', 'right'):
globals()[func]()
elif func in ('swipe', 'hswipe', 'vswipe', 'tap', 'longpress'):
try:
args = map(int, params.split())
globals()[func](*args)
except Exception as e:
print('Could not call', repr(func), 'with params', repr(params))
print(e)
elif func == 'shell':
shell(params)
elif func == 'run':
run(params)
else:
print('This should not happen. Sorry. Try "shell', params, '" instead.')
except (KeyboardInterrupt, EOFError) as e:
print()
print('Exiting...')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment