Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for screen recording with VIEW intent #44

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 64 additions & 26 deletions record_adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,30 @@
import argparse
import subprocess
import time
import os
import signal


# This script records the phone either through intent or simulating user touch
# for the purpose of generating videos that are consistent.
# The consistency allows us to compare said video.
# This script records a video of the phone screen and triggers app activity in one of three ways:
# - mode == "touch": Simulates user touch at the specified coordinates
# - mode == "launch": Launches an app with the .MainActivity
# - mode == "applink": Launches an app with the VIEW intent and a URL
# We can then compare the recorded videos across browsers.
def main(args):
method = args.input
mode = args.mode
device_path = './sdcard/output.mp4'

if method in 'touch' and (args.coordinate_x is None or args.coordinate_y is None):
print('--touch requires --coordinate-x <coordinate> --coordinate-y <coordinate> to use the touch input')
if mode == 'touch' and (args.coordinate_x is None or args.coordinate_y is None):
print('--mode touch requires --coordinate-x <coordinate> --coordinate-y <coordinate> '
'to use the touch input. Enable the touch coordinate overlay in the Android debug '
'settings to find the right coordinates.')
sys.exit()

if mode == 'launch' and (args.package is None):
print('--mode launch requires --package argument')
sys.exit()

if mode == 'applink' and (args.url is None or args.package is None):
print('--mode applink requires --url and --package arguments')
sys.exit()
# if method in 'intent' and args.package is None:
# print('--intent requires --package <your.package.name>')
# sys.exit()

kill_existing_processes("org.mozilla")
kill_existing_processes("com.android.chrome")
Expand All @@ -34,27 +41,57 @@ def main(args):
record_process = subprocess.Popen(['adb', 'shell', 'screenrecord', '--bugreport'] + [device_path])
time.sleep(3)

# TODO allow intent trigger
# if method in 'intent':
# record_with_intent(args.package)
# else:
simulate_input(args.coordinate_x, args.coordinate_y)
if mode == "touch":
simulate_input(args.coordinate_x, args.coordinate_y)
elif mode == "launch":
# The launch activity name depends on the app.
# To find the right activity name, run `adb shell pm dump <packagename>` and look for an
# activity with `Action: "android.intent.action.MAIN"` and
# `Category: "android.intent.category.LAUNCHER"`.
if args.package.startswith("org.mozilla"):
activity = args.package + "/.App"
else:
# Assume Chrome
activity = args.package + "/com.google.android.apps.chrome.Main"
record_with_activity(activity)
else:
# The app link activity name depends on the app.
# To find the right activity name, run `adb shell pm dump <packagename>` and look for an
# activity with `Action: "android.intent.action.VIEW"` and `Category: "android.intent.category.BROWSABLE"`.
if args.package.startswith("org.mozilla"):
activity = args.package + "/org.mozilla.fenix.IntentReceiverActivity"
else:
# Assume Chrome
activity = args.package + "/com.google.android.apps.chrome.IntentDispatcher"
record_with_view_intent(activity, args.url)

time.sleep(5)
record_process.kill()
time.sleep(5)
pull_recording(device_path, args.output)

# def record_with_intent(package):
# activity_start = subprocess.Popen(['adb', 'shell', 'am', 'start-activity', package +'/.App',
# '--ez finishonboarding true'])
# activity_start.wait()


def simulate_input(x, y):
tap_event = subprocess.Popen(['adb', 'shell', 'input', 'tap'] + [str(x), str(y)])
tap_event.wait()


def record_with_activity(activity):
activity_start = subprocess.Popen(
['adb', 'shell', 'am', 'start-activity',
'-a', 'android.intent.action.VIEW', activity]
)
activity_start.wait()


def record_with_view_intent(activity, url):
activity_start = subprocess.Popen(
['adb', 'shell', 'am', 'start-activity', '-d', url,
'-a', 'android.intent.action.VIEW', activity]
)
activity_start.wait()


def pull_recording(device_path, output):
proc = subprocess.Popen(['adb', 'pull', device_path, output])
proc.wait()
Expand All @@ -79,13 +116,14 @@ def kill_existing_processes(package_substr):

if __name__ == "__main__":
parser = argparse.ArgumentParser(description='record video through adb',
usage=('record_adb.py --input <touch> --coordinate-x and --cordinate-y '
usage=('record_adb.py --mode touch -cx 660 -cy 2222 '
'--output <name.mp4>'))
# add intent later
parser.add_argument('-i', '--input', required=True, choices=("touch"))

parser.add_argument('-m', '--mode', required=True, choices=("touch", "launch", "applink"))
parser.add_argument('-cx', '--coordinate-x', type=int, help="X position of touch event")
parser.add_argument('-cy', '--coordinate-y', type=int, help="Y position of touch event")
# parser.add_argument('-p','--package', type=str, help='package name to record if intent is used')
parser.add_argument('-o', '--output', type=str, help="output name of file")
parser.add_argument('-p', '--package', type=str, help="App package for launch / applink")
parser.add_argument('-u', '--url', type=str, help="applink URL")
parser.add_argument('-o', '--output', required=True, type=str, help="output file path")
args = parser.parse_args()
main(args)
Loading