@ -14,32 +14,53 @@ import os
import tempfile
from subprocess import run
PATH_PREFIX = ' /data/local/tmp '
PATH_PREFIX = " /data/local/tmp "
PROD_FENIX = ' fenix '
PROD_GVE = ' geckoview_example '
PROD_FENIX = " fenix "
PROD_GVE = " geckoview_example "
PRODUCTS = [ PROD_FENIX , PROD_GVE ]
GV_CONFIG = b ''' env:
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 " )
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 ( )
@ -51,48 +72,52 @@ def push(id, filename):
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 ( ' \n Startup 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 )
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 (
" \n Startup 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 ' ] )
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 '
" 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 '
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 '
filename = id + " -geckoview-config.yaml "
if args . command == ' activate ' :
if args . command == " activate " :
push ( id , filename )
elif args . command == ' deactivate ' :
elif args . command == " deactivate " :
remove ( filename )
if __name__ == ' __main__ ' :
if __name__ == " __main__ " :
main ( )