Created
August 30, 2022 11:57
-
-
Save mlagerberg/1005e3b00f690e8099f95c2413824247 to your computer and use it in GitHub Desktop.
Android ADB Record touch events as a macro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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