Skip to content

Commit

Permalink
Add support for screen recording with VIEW intent.
Browse files Browse the repository at this point in the history
You can run it as follows:

```
python3 ./record_adb.py --mode applink --package org.mozilla.fenix --url https://theme-crave-demo.myshopify.com/ --output shopify-app-link.mp4
```

This also adds support for launching the app with the launcher activity,
as an alternative to simulating user touch.
Simulating user touch to start an app can be tricky if you're installing
apps in an automated fashion (e.g. for CI testing) and can't ensure that
the app icon is placed in a specific place on the screen.

```
python3 ./record_adb.py --mode launch --package org.mozilla.fenix --output launch.mp4
```
  • Loading branch information
mstange authored and MarcLeclair committed Jul 10, 2024
1 parent 4187327 commit 1c39e9b
Showing 1 changed file with 64 additions and 26 deletions.
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)

0 comments on commit 1c39e9b

Please sign in to comment.