Skip to content

Instantly share code, notes, and snippets.

@mlagerberg
Created August 30, 2022 11:57
Show Gist options
  • Save mlagerberg/1005e3b00f690e8099f95c2413824247 to your computer and use it in GitHub Desktop.
Save mlagerberg/1005e3b00f690e8099f95c2413824247 to your computer and use it in GitHub Desktop.
Android ADB Record touch events as a macro
#!/usr/bin/env python3
import subprocess
import sys
import time
#
# Usage:
# python record_taps.py /dev/input/event3 output_file.sh
# Find out your input event name by running:
# adb shell getevent -lp
# and look for the device that supports ABS_MT_* events
#
# <output_file.sh> becomes a bash file that replays the touch events
# through ADB.
#
# Requires: Python3, ADB installed and 1 single device or emulator connected.
#
# Based on the original script by Cartucho:
# https://github.com/Cartucho/android-touch-record-replay
# Adapted to use `adb shell input` to replay events becauase
# of permission issues around sendevent.
SWIPE_THRESHOLD = 100
def write_command(outputpath, command):
print(command)
with open(outputpath, 'a') as f:
f.write(f"{command}\n")
def main(touchscreen, outputpath):
p = subprocess.Popen(['adb', 'exec-out', 'getevent', '-lt', touchscreen], stdout=subprocess.PIPE)
with open(outputpath, 'w') as f:
f.write("#!/bin/bash\n\n")
print('Recording! You can now tap and swipe. Press Ctrl+C to stop.')
last_up_time = None
first_x = None
first_y = None
last_x = None
last_y = None
touch_started = False
try:
while True:
output = p.stdout.readline().decode('ascii')
if output == '' and p.poll() is not None:
break
if output:
timestamp, event_data = output.split("]", 1)
event_type, event_code, event_value = event_data.split()
try:
# convert hexadecimal to int
event_value = int(event_value, 16)
except ValueError:
pass
if event_code == "BTN_TOUCH" and event_value == "DOWN":
touch_started = True
# Add a pause since the last touch UP
if not last_up_time is None:
diff = time.time() - last_up_time
write_command(outputpath, f"sleep {diff}")
if touch_started and event_code == "ABS_MT_POSITION_X":
if first_x is None:
first_x = event_value
else:
last_x = event_value
if touch_started and event_code == "ABS_MT_POSITION_Y":
if first_y is None:
first_y = event_value
else:
last_y = event_value
if event_code == "BTN_TOUCH" and event_value == "UP":
# Distinguish taps from swipes
if last_x is None or last_y is None or (abs(last_x - first_x) < SWIPE_THRESHOLD and abs(last_y - first_y) < SWIPE_THRESHOLD):
write_command(outputpath, f"adb shell input tap {first_x} {first_y}")
else:
write_command(outputpath, f"adb shell input swipe {first_x} {first_y} {last_x} {last_y}")
last_up_time = time.time()
touch_started = False
first_x = None
first_y = None
last_x = None
last_y = None
except KeyboardInterrupt:
print(f"Done. Your script is saved to {outputpath}.")
if __name__ == "__main__":
if len(sys.argv) == 3:
touchscreen = sys.argv[1]
outputpath = sys.argv[2]
main(touchscreen, outputpath)
else:
print("""
Usage:
python3 record.py /dev/input/event3 <output_file>.sh
Find out your input event name by running:
adb shell getevent -lp
and look for the device that supports ABS_MT_* events
""")
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment