124 lines
3.7 KiB
Python
Executable File
124 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
"""
|
|
A script to set up startup profiling with the Firefox Profiler. See
|
|
https://profiler.firefox.com/docs/#/./guide-remote-profiling?id=startup-profiling
|
|
for more information.
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import tempfile
|
|
from subprocess import run
|
|
|
|
PATH_PREFIX = "/data/local/tmp"
|
|
|
|
PROD_FENIX = "fenix"
|
|
PROD_GVE = "geckoview_example"
|
|
PRODUCTS = [PROD_FENIX, PROD_GVE]
|
|
|
|
GV_CONFIG = b"""env:
|
|
MOZ_PROFILER_STARTUP: 1
|
|
MOZ_PROFILER_STARTUP_INTERVAL: 5
|
|
MOZ_PROFILER_STARTUP_FEATURES: js,stackwalk,leaf,screenshots,ipcmessages,java,cpu
|
|
MOZ_PROFILER_STARTUP_FILTERS: GeckoMain,Compositor,Renderer,IPDL Background
|
|
"""
|
|
|
|
|
|
def parse_args():
|
|
p = argparse.ArgumentParser(
|
|
description=(
|
|
"Easily enable start up profiling using the Firefox Profiler. Finish capturing the profile in "
|
|
"about:debugging on desktop. See "
|
|
"https://profiler.firefox.com/docs/#/./guide-remote-profiling?id=startup-profiling for "
|
|
"details."
|
|
)
|
|
)
|
|
p.add_argument(
|
|
"command",
|
|
choices=["activate", "deactivate"],
|
|
help=(
|
|
"whether to activate or deactive start up "
|
|
"profiling for the given release channel"
|
|
),
|
|
)
|
|
p.add_argument(
|
|
"release_channel",
|
|
choices=["nightly", "beta", "release", "debug"],
|
|
help=(
|
|
"the release channel to "
|
|
"change the startup profiling state of the command on"
|
|
),
|
|
)
|
|
|
|
p.add_argument(
|
|
"-p",
|
|
"--product",
|
|
choices=PRODUCTS,
|
|
default=PROD_FENIX,
|
|
help="which product to work on",
|
|
)
|
|
return p.parse_args()
|
|
|
|
|
|
def push(id, filename):
|
|
config = tempfile.NamedTemporaryFile(delete=False)
|
|
try:
|
|
# I think the file needs to be closed to save its contents for adb push to
|
|
# work correctly so we close it here and later delete it manually.
|
|
with config.file as f:
|
|
f.write(GV_CONFIG)
|
|
|
|
print("Pushing {} to device.".format(filename))
|
|
run(["adb", "push", config.name, os.path.join(PATH_PREFIX, filename)])
|
|
run(["adb", "shell", "am", "set-debug-app", "--persistent", id])
|
|
print(
|
|
"\nStartup profiling enabled on all future start ups, possibly even after reinstall."
|
|
)
|
|
print("Call script with `deactivate` to disable it.")
|
|
print(
|
|
"DISABLE 'Remote debugging via USB' IN THE APP SETTINGS BEFORE STARTING THE APP & RE-ENABLE TO CAPTURE THE PROFILE.",
|
|
"This avoids the additional overhead added when 'Remote debugging via USB' is enabled during start up.",
|
|
sep=os.linesep,
|
|
)
|
|
finally:
|
|
os.remove(config.name)
|
|
|
|
|
|
def remove(filename):
|
|
print("Removing {} from device.".format(filename))
|
|
run(["adb", "shell", "rm", PATH_PREFIX + "/" + filename])
|
|
run(["adb", "shell", "am", "clear-debug-app"])
|
|
|
|
|
|
def convert_channel_to_id(product, channel):
|
|
if product == PROD_FENIX:
|
|
mapping = {
|
|
"release": "org.mozilla.firefox",
|
|
"beta": "org.mozilla.firefox_beta",
|
|
"nightly": "org.mozilla.fenix",
|
|
"debug": "org.mozilla.fenix.debug",
|
|
}
|
|
return mapping[channel]
|
|
elif product == PROD_GVE:
|
|
return "org.mozilla.geckoview_example"
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
id = convert_channel_to_id(args.product, args.release_channel)
|
|
filename = id + "-geckoview-config.yaml"
|
|
|
|
if args.command == "activate":
|
|
push(id, filename)
|
|
elif args.command == "deactivate":
|
|
remove(filename)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|