123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- #!/bin/bash
- # Copyright 2018 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- set -e
- shopt -s nullglob
- shopt -s extglob
- function kill_process() {
- name=$1
- pid=$($adb shell "pidof $name" || true)
- if [ ! -z "$pid" ]; then
- echo "Killing $name..."
- $adb shell "kill $pid"
- else
- echo "$name is not running."
- fi
- }
- function get_data_file() {
- trace_file=$1
- extension=$2
- echo "${trace_file%.*}.$extension"
- }
- function get_logcat_file() {
- trace_file=$1
- get_data_file "$trace_file" "logcat"
- }
- function get_meminfo_file() {
- trace_file=$1
- tag=$2
- get_data_file "$trace_file" "$tag.meminfo"
- }
- function analyze_trace_file() {
- trace_file=$1
- trace_events_to_print=$2
- logcat_file="$(get_logcat_file "$trace_file")"
- echo "Processes started / died:"
- grep -E "Start proc|died|MY-DBG" "$logcat_file"
- extractor_arguments="$trace_file"
- if [ ! -z "$trace_events_to_print" ]; then
- extractor_arguments="$extractor_arguments --print-events=$trace_events_to_print"
- fi
- "$this_path/systrace-extract-startup.py" $extractor_arguments
- }
- function analyze_meminfo_file() {
- meminfo_file=$1
- if [ -f "$meminfo_file" ]; then
- echo "$meminfo_file"
- grep -A 5 "Total RAM" "$meminfo_file"
- fi
- }
- function capture_analyze_meminfo_file() {
- meminfo_file=$1
- $adb shell "dumpsys meminfo" > "$meminfo_file"
- analyze_meminfo_file "$meminfo_file"
- }
- function echo_separator() {
- s="----------"
- echo
- echo "$s$s$s$s$s$s$s$s" # 8*10
- }
- this_path="$(dirname "$0")"
- adb="$ADB_PATH"
- if [ -z "$adb" ]; then
- adb="$(which adb)"
- fi
- if [ -z "$adb" ]; then
- echo "Where's adb? Can't find it."
- exit 1
- fi
- export ADB_PATH="$adb"
- output_tag=
- browser=chrome
- trace_time=10
- cold=false
- url=
- atrace_buffer_size=
- atrace_categories=
- killg=false
- repeat=
- analyze=false
- meminfo=false
- checktabs=false
- taburl=
- trace_events_to_print=
- webapk_package=
- for i in "$@"; do
- case $i in
- --help)
- echo "$(basename "$0") output-tag [options]"
- exit 0
- ;;
- --browser=*)
- browser="${i#*=}"
- ;;
- --url=*)
- url="${i#*=}"
- ;;
- --warm)
- cold=false
- ;;
- --cold)
- cold=true
- ;;
- --atrace=*)
- atrace_categories="${i#*=}"
- ;;
- --atrace-buffer-size*)
- atrace_buffer_size="${i#*=}"
- ;;
- --killg)
- killg=true
- ;;
- --trace-time=*)
- trace_time="${i#*=}"
- ;;
- --repeat=*)
- repeat="${i#*=}"
- ;;
- --analyze)
- analyze=true
- ;;
- --meminfo)
- meminfo=true
- ;;
- --checktabs)
- checktabs=true
- ;;
- --taburl=*)
- taburl="${i#*=}"
- ;;
- --print-trace-events=*)
- trace_events_to_print="${i#*=}"
- ;;
- --webapk=*)
- webapk_package="${i#*=}"
- ;;
- --extra_chrome_categories=*)
- extra_chrome_categories="${i#*=}"
- ;;
- --*)
- echo "Unknown option or missing option argument: $i"
- exit 1
- ;;
- *)
- if [ -z "$output_tag" ]; then
- output_tag="$i"
- else
- echo "Unknown option: $i"
- exit 1
- fi
- ;;
- esac
- if [ -z "$output_tag" ]; then
- echo "First argument must be the output tag."
- exit 1
- fi
- shift
- done
- if [ -d "$output_tag" ]; then
- output_tag="${output_tag%%+(/)}/trace"
- fi
- specified_output_tag="$output_tag"
- if [ $analyze = true ]; then
- for file in $output_tag*.html; do
- echo_separator
- echo "$file"
- analyze_meminfo_file "$(get_meminfo_file "$output_file" "before")"
- analyze_meminfo_file "$(get_meminfo_file "$output_file" "after")"
- echo
- analyze_trace_file "$file" "$print_trace_events"
- done
- exit 0
- fi
- browser_package=
- case $browser in
- chrome)
- browser_package="com.google.android.apps.chrome"
- ;;
- canary)
- browser_package="com.chrome.canary"
- browser="chrome_canary"
- ;;
- dev)
- browser_package="com.chrome.dev"
- ;;
- beta)
- browser_package="com.chrome.beta"
- ;;
- stable)
- browser_package="com.android.chrome"
- ;;
- chromium)
- browser_package="org.chromium.chrome"
- ;;
- *)
- echo "Unknown browser $browser"
- exit 1
- esac
- profile_options=
- profile_options="$profile_options --browser=$browser"
- if [ ! "$browser" = "chrome" ]; then
- output_tag="$output_tag-$browser"
- fi
- profile_options="$profile_options --time=$trace_time"
- if [ ! -z "$atrace_categories" ]; then
- profile_options="$profile_options --atrace-categories=$atrace_categories"
- output_tag="$output_tag-${atrace_categories//,/_}"
- fi
- if [ ! -z "$atrace_buffer_size" ]; then
- profile_options="$profile_options --atrace-buffer-size=$atrace_buffer_size"
- output_tag="$output_tag-${atrace_buffer_size}"
- fi
- if [ $cold = true ]; then
- profile_options="$profile_options --cold"
- output_tag="$output_tag-cold"
- fi
- profile_options="$profile_options --url=$url"
- if [ ! -z "$url" ]; then
- output_tag="$output_tag-url"
- fi
- if [ ! -z "$webapk_package" ]; then
- output_tag="$output_tag-webapk"
- profile_options="$profile_options --webapk-package=$webapk_package"
- fi
- if [ $killg = true ]; then
- output_tag="$output_tag-killg"
- fi
- # Must be last for ease of globbing.
- output_tag="$output_tag-${trace_time}s"
- if [ $checktabs = true ] || [ $killg = true ] || [ ! -z "$taburl" ]; then
- $adb root > /dev/null
- fi
- # Make sure Chrome can write the trace file.
- # These commands may fail with a security exception on some Android devices that
- # don't allow changing permissions. Chrome likely already has these permissions
- # so the script should still work.
- $adb shell "pm grant $browser_package \
- android.permission.READ_EXTERNAL_STORAGE" || true
- $adb shell "pm grant $browser_package \
- android.permission.WRITE_EXTERNAL_STORAGE" || true
- if [ ! -z "$taburl" ]; then
- echo "Opening $taburl in a single tab..."
- $adb shell "am force-stop $browser_package"
- $adb shell "rm -f /data/data/$browser_package/app_tabs/0/tab*"
- $adb shell "am start -a android.intent.action.VIEW \
- -n $browser_package/org.chromium.chrome.browser.ChromeTabbedActivity \
- -d $taburl"
- sleep 5
- $adb shell "am start -a android.intent.action.MAIN -c android.intent.category.HOME"
- sleep 1
- $adb shell "am force-stop $browser_package"
- echo
- fi
- repeat_count=1
- if [ ! -z "$repeat" ]; then
- repeat_count="$repeat"
- fi
- if [ ! -z "$extra_chrome_categories" ]; then
- chrome_categories="_DEFAULT_CHROME_CATEGORIES,${extra_chrome_categories}"
- profile_options="$profile_options --chrome_categories=${chrome_categories}"
- fi
- first_iteration=true
- for iteration in $(seq "$repeat_count"); do
- if [ $first_iteration = true ]; then
- first_iteration=false
- else
- echo_separator
- sleep 2
- fi
- if [ $killg = true ]; then
- echo "Preemptively killing g* processes..."
- $adb logcat -c
- kill_process "com.google.process.gapps"
- kill_process "com.google.android.gms"
- sleep 1
- $adb logcat -d | grep -E "Start proc|died" || true
- fi
- echo
- if [ -z "$repeat" ]; then
- output_file="$output_tag.html"
- if [ -f "$output_file" ]; then
- for i in {2..1000}; do
- output_file="$output_tag~$i.html"
- if [ ! -f "$output_file" ]; then
- break;
- fi
- done
- fi
- if [ -f "$output_file" ]; then
- echo "Failed to find unoccupied output file. Last was: $output_file"
- exit 1
- fi
- else
- output_file="$output_tag~${repeat_count}_$iteration.html"
- if [ -f "$output_file" ]; then
- echo "Output file already exists: $output_file"
- echo "Please add something unique to the tag ($specified_output_tag)."
- exit 1
- fi
- fi
- echo "Output file: $output_file"
- logcat_file="$(get_logcat_file "$output_file")"
- echo "Logcat output file: $logcat_file"
- if [ $meminfo = true ]; then
- echo
- capture_analyze_meminfo_file "$(get_meminfo_file "$output_file" "before")"
- fi
- echo
- echo "Profiling with options: $profile_options"
- ./build/android/adb_profile_chrome_startup \
- $profile_options \
- "--output=$output_file"
- if [ $meminfo = true ]; then
- echo
- capture_analyze_meminfo_file "$(get_meminfo_file "$output_file" "after")"
- fi
- $adb shell "am force-stop $browser_package"
- $adb shell "killall logcat" > /dev/null 2>&1 || true
- $adb logcat -d > "${logcat_file}"
- rm -f chrome-profile-results-*
- $adb shell "rm -f /sdcard/Download/chrome-profile-results-*"
- echo
- analyze_trace_file "$output_file" "$trace_events_to_print"
- if [ $checktabs = true ]; then
- # Yields empty string when value is -1
- active_tab_id="$( \
- $adb shell "cat /data/data/$browser_package/shared_prefs/${browser_package}_preferences.xml" \
- | sed -n 's/^.*ACTIVE_TAB_ID" value="\([0-9]\{1,3\}\).*$/\1/p')"
- # Yields empty string when there is no 'tab' file
- tab_id="$( \
- $adb shell ls /data/data/$browser_package/app_tabs/0 \
- | sed -n 's/tab\([0-9]\{1,3\}\)\s*/\1/p')"
- if [ "$active_tab_id" != "$tab_id" ]; then
- echo "Tab IDs don't match (active_tab_id=$active_tab_id, tab_id=$tab_id), last result is not reliable."
- exit 1
- fi
- fi
- done
|