Home | History | Annotate | Download | only in build
      1 function hmm() {
      2 cat <<EOF
      3 Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
      4 - lunch:     lunch <product_name>-<build_variant>
      5 - tapas:     tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
      6 - croot:     Changes directory to the top of the tree.
      7 - m:         Makes from the top of the tree.
      8 - mm:        Builds all of the modules in the current directory, but not their dependencies.
      9 - mmm:       Builds all of the modules in the supplied directories, but not their dependencies.
     10              To limit the modules being built use the syntax: mmm dir/:target1,target2.
     11 - mma:       Builds all of the modules in the current directory, and their dependencies.
     12 - mmma:      Builds all of the modules in the supplied directories, and their dependencies.
     13 - provision: Flash device with all required partitions. Options will be passed on to fastboot.
     14 - cgrep:     Greps on all local C/C++ files.
     15 - ggrep:     Greps on all local Gradle files.
     16 - jgrep:     Greps on all local Java files.
     17 - resgrep:   Greps on all local res/*.xml files.
     18 - mangrep:   Greps on all local AndroidManifest.xml files.
     19 - mgrep:     Greps on all local Makefiles files.
     20 - sepgrep:   Greps on all local sepolicy files.
     21 - sgrep:     Greps on all local source files.
     22 - godir:     Go to the directory containing a file.
     23 
     24 Environment options:
     25 - SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
     26                  ASAN_OPTIONS=detect_leaks=0 will be set by default until the
     27                  build is leak-check clean.
     28 
     29 Look at the source to view more functions. The complete list is:
     30 EOF
     31     T=$(gettop)
     32     local A
     33     A=""
     34     for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
     35       A="$A $i"
     36     done
     37     echo $A
     38 }
     39 
     40 # Get all the build variables needed by this script in a single call to the build system.
     41 function build_build_var_cache()
     42 {
     43     T=$(gettop)
     44     # Grep out the variable names from the script.
     45     cached_vars=`cat $T/build/envsetup.sh | tr '()' '  ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
     46     cached_abs_vars=`cat $T/build/envsetup.sh | tr '()' '  ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
     47     # Call the build system to dump the "<val>=<value>" pairs as a shell script.
     48     build_dicts_script=`\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
     49                         command make --no-print-directory -f build/core/config.mk \
     50                         dump-many-vars \
     51                         DUMP_MANY_VARS="$cached_vars" \
     52                         DUMP_MANY_ABS_VARS="$cached_abs_vars" \
     53                         DUMP_VAR_PREFIX="var_cache_" \
     54                         DUMP_ABS_VAR_PREFIX="abs_var_cache_"`
     55     local ret=$?
     56     if [ $ret -ne 0 ]
     57     then
     58         unset build_dicts_script
     59         return $ret
     60     fi
     61     # Excute the script to store the "<val>=<value>" pairs as shell variables.
     62     eval "$build_dicts_script"
     63     ret=$?
     64     unset build_dicts_script
     65     if [ $ret -ne 0 ]
     66     then
     67         return $ret
     68     fi
     69     BUILD_VAR_CACHE_READY="true"
     70 }
     71 
     72 # Delete the build var cache, so that we can still call into the build system
     73 # to get build variables not listed in this script.
     74 function destroy_build_var_cache()
     75 {
     76     unset BUILD_VAR_CACHE_READY
     77     for v in $cached_vars; do
     78       unset var_cache_$v
     79     done
     80     unset cached_vars
     81     for v in $cached_abs_vars; do
     82       unset abs_var_cache_$v
     83     done
     84     unset cached_abs_vars
     85 }
     86 
     87 # Get the value of a build variable as an absolute path.
     88 function get_abs_build_var()
     89 {
     90     if [ "$BUILD_VAR_CACHE_READY" = "true" ]
     91     then
     92         eval echo \"\${abs_var_cache_$1}\"
     93     return
     94     fi
     95 
     96     T=$(gettop)
     97     if [ ! "$T" ]; then
     98         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
     99         return
    100     fi
    101     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
    102       command make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
    103 }
    104 
    105 # Get the exact value of a build variable.
    106 function get_build_var()
    107 {
    108     if [ "$BUILD_VAR_CACHE_READY" = "true" ]
    109     then
    110         eval echo \"\${var_cache_$1}\"
    111     return
    112     fi
    113 
    114     T=$(gettop)
    115     if [ ! "$T" ]; then
    116         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
    117         return
    118     fi
    119     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
    120       command make --no-print-directory -f build/core/config.mk dumpvar-$1)
    121 }
    122 
    123 # check to see if the supplied product is one we can build
    124 function check_product()
    125 {
    126     T=$(gettop)
    127     if [ ! "$T" ]; then
    128         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
    129         return
    130     fi
    131         TARGET_PRODUCT=$1 \
    132         TARGET_BUILD_VARIANT= \
    133         TARGET_BUILD_TYPE= \
    134         TARGET_BUILD_APPS= \
    135         get_build_var TARGET_DEVICE > /dev/null
    136     # hide successful answers, but allow the errors to show
    137 }
    138 
    139 VARIANT_CHOICES=(user userdebug eng)
    140 
    141 # check to see if the supplied variant is valid
    142 function check_variant()
    143 {
    144     for v in ${VARIANT_CHOICES[@]}
    145     do
    146         if [ "$v" = "$1" ]
    147         then
    148             return 0
    149         fi
    150     done
    151     return 1
    152 }
    153 
    154 function setpaths()
    155 {
    156     T=$(gettop)
    157     if [ ! "$T" ]; then
    158         echo "Couldn't locate the top of the tree.  Try setting TOP."
    159         return
    160     fi
    161 
    162     ##################################################################
    163     #                                                                #
    164     #              Read me before you modify this code               #
    165     #                                                                #
    166     #   This function sets ANDROID_BUILD_PATHS to what it is adding  #
    167     #   to PATH, and the next time it is run, it removes that from   #
    168     #   PATH.  This is required so lunch can be run more than once   #
    169     #   and still have working paths.                                #
    170     #                                                                #
    171     ##################################################################
    172 
    173     # Note: on windows/cygwin, ANDROID_BUILD_PATHS will contain spaces
    174     # due to "C:\Program Files" being in the path.
    175 
    176     # out with the old
    177     if [ -n "$ANDROID_BUILD_PATHS" ] ; then
    178         export PATH=${PATH/$ANDROID_BUILD_PATHS/}
    179     fi
    180     if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then
    181         export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}
    182         # strip leading ':', if any
    183         export PATH=${PATH/:%/}
    184     fi
    185 
    186     # and in with the new
    187     prebuiltdir=$(getprebuilt)
    188     gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
    189 
    190     # defined in core/config.mk
    191     targetgccversion=$(get_build_var TARGET_GCC_VERSION)
    192     targetgccversion2=$(get_build_var 2ND_TARGET_GCC_VERSION)
    193     export TARGET_GCC_VERSION=$targetgccversion
    194 
    195     # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.
    196     export ANDROID_TOOLCHAIN=
    197     export ANDROID_TOOLCHAIN_2ND_ARCH=
    198     local ARCH=$(get_build_var TARGET_ARCH)
    199     case $ARCH in
    200         x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
    201             ;;
    202         x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
    203             ;;
    204         arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
    205             ;;
    206         arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin;
    207                toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
    208             ;;
    209         mips|mips64) toolchaindir=mips/mips64el-linux-android-$targetgccversion/bin
    210             ;;
    211         *)
    212             echo "Can't find toolchain for unknown architecture: $ARCH"
    213             toolchaindir=xxxxxxxxx
    214             ;;
    215     esac
    216     if [ -d "$gccprebuiltdir/$toolchaindir" ]; then
    217         export ANDROID_TOOLCHAIN=$gccprebuiltdir/$toolchaindir
    218     fi
    219 
    220     if [ -d "$gccprebuiltdir/$toolchaindir2" ]; then
    221         export ANDROID_TOOLCHAIN_2ND_ARCH=$gccprebuiltdir/$toolchaindir2
    222     fi
    223 
    224     export ANDROID_DEV_SCRIPTS=$T/development/scripts:$T/prebuilts/devtools/tools:$T/external/selinux/prebuilts/bin
    225     export ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_TOOLCHAIN:$ANDROID_TOOLCHAIN_2ND_ARCH:$ANDROID_DEV_SCRIPTS:
    226 
    227     # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
    228     # to ensure that the corresponding 'emulator' binaries are used.
    229     case $(uname -s) in
    230         Darwin)
    231             ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64
    232             ;;
    233         Linux)
    234             ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64
    235             ;;
    236         *)
    237             ANDROID_EMULATOR_PREBUILTS=
    238             ;;
    239     esac
    240     if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
    241         ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS$ANDROID_EMULATOR_PREBUILTS:
    242         export ANDROID_EMULATOR_PREBUILTS
    243     fi
    244 
    245     export PATH=$ANDROID_BUILD_PATHS$PATH
    246     export PYTHONPATH=$T/development/python-packages:$PYTHONPATH
    247 
    248     unset ANDROID_JAVA_TOOLCHAIN
    249     unset ANDROID_PRE_BUILD_PATHS
    250     if [ -n "$JAVA_HOME" ]; then
    251         export ANDROID_JAVA_TOOLCHAIN=$JAVA_HOME/bin
    252         export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN:
    253         export PATH=$ANDROID_PRE_BUILD_PATHS$PATH
    254     fi
    255 
    256     unset ANDROID_PRODUCT_OUT
    257     export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
    258     export OUT=$ANDROID_PRODUCT_OUT
    259 
    260     unset ANDROID_HOST_OUT
    261     export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT)
    262 
    263     # needed for building linux on MacOS
    264     # TODO: fix the path
    265     #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
    266 }
    267 
    268 function printconfig()
    269 {
    270     T=$(gettop)
    271     if [ ! "$T" ]; then
    272         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
    273         return
    274     fi
    275     get_build_var report_config
    276 }
    277 
    278 function set_stuff_for_environment()
    279 {
    280     settitle
    281     set_java_home
    282     setpaths
    283     set_sequence_number
    284 
    285     export ANDROID_BUILD_TOP=$(gettop)
    286     # With this environment variable new GCC can apply colors to warnings/errors
    287     export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
    288     export ASAN_OPTIONS=detect_leaks=0
    289 }
    290 
    291 function set_sequence_number()
    292 {
    293     export BUILD_ENV_SEQUENCE_NUMBER=10
    294 }
    295 
    296 function settitle()
    297 {
    298     if [ "$STAY_OFF_MY_LAWN" = "" ]; then
    299         local arch=$(gettargetarch)
    300         local product=$TARGET_PRODUCT
    301         local variant=$TARGET_BUILD_VARIANT
    302         local apps=$TARGET_BUILD_APPS
    303         if [ -z "$apps" ]; then
    304             export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
    305         else
    306             export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""
    307         fi
    308     fi
    309 }
    310 
    311 function addcompletions()
    312 {
    313     local T dir f
    314 
    315     # Keep us from trying to run in something that isn't bash.
    316     if [ -z "${BASH_VERSION}" ]; then
    317         return
    318     fi
    319 
    320     # Keep us from trying to run in bash that's too old.
    321     if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
    322         return
    323     fi
    324 
    325     dir="sdk/bash_completion"
    326     if [ -d ${dir} ]; then
    327         for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
    328             echo "including $f"
    329             . $f
    330         done
    331     fi
    332 }
    333 
    334 function choosetype()
    335 {
    336     echo "Build type choices are:"
    337     echo "     1. release"
    338     echo "     2. debug"
    339     echo
    340 
    341     local DEFAULT_NUM DEFAULT_VALUE
    342     DEFAULT_NUM=1
    343     DEFAULT_VALUE=release
    344 
    345     export TARGET_BUILD_TYPE=
    346     local ANSWER
    347     while [ -z $TARGET_BUILD_TYPE ]
    348     do
    349         echo -n "Which would you like? ["$DEFAULT_NUM"] "
    350         if [ -z "$1" ] ; then
    351             read ANSWER
    352         else
    353             echo $1
    354             ANSWER=$1
    355         fi
    356         case $ANSWER in
    357         "")
    358             export TARGET_BUILD_TYPE=$DEFAULT_VALUE
    359             ;;
    360         1)
    361             export TARGET_BUILD_TYPE=release
    362             ;;
    363         release)
    364             export TARGET_BUILD_TYPE=release
    365             ;;
    366         2)
    367             export TARGET_BUILD_TYPE=debug
    368             ;;
    369         debug)
    370             export TARGET_BUILD_TYPE=debug
    371             ;;
    372         *)
    373             echo
    374             echo "I didn't understand your response.  Please try again."
    375             echo
    376             ;;
    377         esac
    378         if [ -n "$1" ] ; then
    379             break
    380         fi
    381     done
    382 
    383     build_build_var_cache
    384     set_stuff_for_environment
    385     destroy_build_var_cache
    386 }
    387 
    388 #
    389 # This function isn't really right:  It chooses a TARGET_PRODUCT
    390 # based on the list of boards.  Usually, that gets you something
    391 # that kinda works with a generic product, but really, you should
    392 # pick a product by name.
    393 #
    394 function chooseproduct()
    395 {
    396     if [ "x$TARGET_PRODUCT" != x ] ; then
    397         default_value=$TARGET_PRODUCT
    398     else
    399         default_value=aosp_arm
    400     fi
    401 
    402     export TARGET_BUILD_APPS=
    403     export TARGET_PRODUCT=
    404     local ANSWER
    405     while [ -z "$TARGET_PRODUCT" ]
    406     do
    407         echo -n "Which product would you like? [$default_value] "
    408         if [ -z "$1" ] ; then
    409             read ANSWER
    410         else
    411             echo $1
    412             ANSWER=$1
    413         fi
    414 
    415         if [ -z "$ANSWER" ] ; then
    416             export TARGET_PRODUCT=$default_value
    417         else
    418             if check_product $ANSWER
    419             then
    420                 export TARGET_PRODUCT=$ANSWER
    421             else
    422                 echo "** Not a valid product: $ANSWER"
    423             fi
    424         fi
    425         if [ -n "$1" ] ; then
    426             break
    427         fi
    428     done
    429 
    430     build_build_var_cache
    431     set_stuff_for_environment
    432     destroy_build_var_cache
    433 }
    434 
    435 function choosevariant()
    436 {
    437     echo "Variant choices are:"
    438     local index=1
    439     local v
    440     for v in ${VARIANT_CHOICES[@]}
    441     do
    442         # The product name is the name of the directory containing
    443         # the makefile we found, above.
    444         echo "     $index. $v"
    445         index=$(($index+1))
    446     done
    447 
    448     local default_value=eng
    449     local ANSWER
    450 
    451     export TARGET_BUILD_VARIANT=
    452     while [ -z "$TARGET_BUILD_VARIANT" ]
    453     do
    454         echo -n "Which would you like? [$default_value] "
    455         if [ -z "$1" ] ; then
    456             read ANSWER
    457         else
    458             echo $1
    459             ANSWER=$1
    460         fi
    461 
    462         if [ -z "$ANSWER" ] ; then
    463             export TARGET_BUILD_VARIANT=$default_value
    464         elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
    465             if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
    466                 export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-1))]}
    467             fi
    468         else
    469             if check_variant $ANSWER
    470             then
    471                 export TARGET_BUILD_VARIANT=$ANSWER
    472             else
    473                 echo "** Not a valid variant: $ANSWER"
    474             fi
    475         fi
    476         if [ -n "$1" ] ; then
    477             break
    478         fi
    479     done
    480 }
    481 
    482 function choosecombo()
    483 {
    484     choosetype $1
    485 
    486     echo
    487     echo
    488     chooseproduct $2
    489 
    490     echo
    491     echo
    492     choosevariant $3
    493 
    494     echo
    495     build_build_var_cache
    496     set_stuff_for_environment
    497     printconfig
    498     destroy_build_var_cache
    499 }
    500 
    501 # Clear this variable.  It will be built up again when the vendorsetup.sh
    502 # files are included at the end of this file.
    503 unset LUNCH_MENU_CHOICES
    504 function add_lunch_combo()
    505 {
    506     local new_combo=$1
    507     local c
    508     for c in ${LUNCH_MENU_CHOICES[@]} ; do
    509         if [ "$new_combo" = "$c" ] ; then
    510             return
    511         fi
    512     done
    513     LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
    514 }
    515 
    516 # add the default one here
    517 add_lunch_combo aosp_arm-eng
    518 add_lunch_combo aosp_arm64-eng
    519 add_lunch_combo aosp_mips-eng
    520 add_lunch_combo aosp_mips64-eng
    521 add_lunch_combo aosp_x86-eng
    522 add_lunch_combo aosp_x86_64-eng
    523 
    524 function print_lunch_menu()
    525 {
    526     local uname=$(uname)
    527     echo
    528     echo "You're building on" $uname
    529     echo
    530     echo "Lunch menu... pick a combo:"
    531 
    532     local i=1
    533     local choice
    534     for choice in ${LUNCH_MENU_CHOICES[@]}
    535     do
    536         echo "     $i. $choice"
    537         i=$(($i+1))
    538     done
    539 
    540     echo
    541 }
    542 
    543 function lunch()
    544 {
    545     local answer
    546 
    547     if [ "$1" ] ; then
    548         answer=$1
    549     else
    550         print_lunch_menu
    551         echo -n "Which would you like? [aosp_arm-eng] "
    552         read answer
    553     fi
    554 
    555     local selection=
    556 
    557     if [ -z "$answer" ]
    558     then
    559         selection=aosp_arm-eng
    560     elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
    561     then
    562         if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
    563         then
    564             selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
    565         fi
    566     elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
    567     then
    568         selection=$answer
    569     fi
    570 
    571     if [ -z "$selection" ]
    572     then
    573         echo
    574         echo "Invalid lunch combo: $answer"
    575         return 1
    576     fi
    577 
    578     export TARGET_BUILD_APPS=
    579 
    580     local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
    581     check_variant $variant
    582     if [ $? -ne 0 ]
    583     then
    584         echo
    585         echo "** Invalid variant: '$variant'"
    586         echo "** Must be one of ${VARIANT_CHOICES[@]}"
    587         variant=
    588     fi
    589 
    590     local product=$(echo -n $selection | sed -e "s/-.*$//")
    591     TARGET_PRODUCT=$product \
    592     TARGET_BUILD_VARIANT=$variant \
    593     build_build_var_cache
    594     if [ $? -ne 0 ]
    595     then
    596         echo
    597         echo "** Don't have a product spec for: '$product'"
    598         echo "** Do you have the right repo manifest?"
    599         product=
    600     fi
    601 
    602     if [ -z "$product" -o -z "$variant" ]
    603     then
    604         echo
    605         return 1
    606     fi
    607 
    608     export TARGET_PRODUCT=$product
    609     export TARGET_BUILD_VARIANT=$variant
    610     export TARGET_BUILD_TYPE=release
    611 
    612     echo
    613 
    614     set_stuff_for_environment
    615     printconfig
    616     destroy_build_var_cache
    617 }
    618 
    619 # Tab completion for lunch.
    620 function _lunch()
    621 {
    622     local cur prev opts
    623     COMPREPLY=()
    624     cur="${COMP_WORDS[COMP_CWORD]}"
    625     prev="${COMP_WORDS[COMP_CWORD-1]}"
    626 
    627     COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) )
    628     return 0
    629 }
    630 complete -F _lunch lunch
    631 
    632 # Configures the build to build unbundled apps.
    633 # Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
    634 function tapas()
    635 {
    636     local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)"
    637     local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
    638     local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
    639     local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5|arm64|x86_64|mips64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
    640 
    641     if [ $(echo $arch | wc -w) -gt 1 ]; then
    642         echo "tapas: Error: Multiple build archs supplied: $arch"
    643         return
    644     fi
    645     if [ $(echo $variant | wc -w) -gt 1 ]; then
    646         echo "tapas: Error: Multiple build variants supplied: $variant"
    647         return
    648     fi
    649     if [ $(echo $density | wc -w) -gt 1 ]; then
    650         echo "tapas: Error: Multiple densities supplied: $density"
    651         return
    652     fi
    653 
    654     local product=aosp_arm
    655     case $arch in
    656       x86)    product=aosp_x86;;
    657       mips)   product=aosp_mips;;
    658       armv5)  product=generic_armv5;;
    659       arm64)  product=aosp_arm64;;
    660       x86_64) product=aosp_x86_64;;
    661       mips64)  product=aosp_mips64;;
    662     esac
    663     if [ -z "$variant" ]; then
    664         variant=eng
    665     fi
    666     if [ -z "$apps" ]; then
    667         apps=all
    668     fi
    669     if [ -z "$density" ]; then
    670         density=alldpi
    671     fi
    672 
    673     export TARGET_PRODUCT=$product
    674     export TARGET_BUILD_VARIANT=$variant
    675     export TARGET_BUILD_DENSITY=$density
    676     export TARGET_BUILD_TYPE=release
    677     export TARGET_BUILD_APPS=$apps
    678 
    679     build_build_var_cache
    680     set_stuff_for_environment
    681     printconfig
    682     destroy_build_var_cache
    683 }
    684 
    685 function gettop
    686 {
    687     local TOPFILE=build/core/envsetup.mk
    688     if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
    689         # The following circumlocution ensures we remove symlinks from TOP.
    690         (cd $TOP; PWD= /bin/pwd)
    691     else
    692         if [ -f $TOPFILE ] ; then
    693             # The following circumlocution (repeated below as well) ensures
    694             # that we record the true directory name and not one that is
    695             # faked up with symlink names.
    696             PWD= /bin/pwd
    697         else
    698             local HERE=$PWD
    699             T=
    700             while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
    701                 \cd ..
    702                 T=`PWD= /bin/pwd -P`
    703             done
    704             \cd $HERE
    705             if [ -f "$T/$TOPFILE" ]; then
    706                 echo $T
    707             fi
    708         fi
    709     fi
    710 }
    711 
    712 # Return driver for "make", if any (eg. static analyzer)
    713 function getdriver()
    714 {
    715     local T="$1"
    716     test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
    717     if [ -n "$WITH_STATIC_ANALYZER" ]; then
    718         echo "\
    719 $T/prebuilts/misc/linux-x86/analyzer/tools/scan-build/scan-build \
    720 --use-analyzer $T/prebuilts/misc/linux-x86/analyzer/bin/analyzer \
    721 --status-bugs \
    722 --top=$T"
    723     fi
    724 }
    725 
    726 function m()
    727 {
    728     local T=$(gettop)
    729     local DRV=$(getdriver $T)
    730     if [ "$T" ]; then
    731         $DRV make -C $T -f build/core/main.mk $@
    732     else
    733         echo "Couldn't locate the top of the tree.  Try setting TOP."
    734         return 1
    735     fi
    736 }
    737 
    738 function findmakefile()
    739 {
    740     TOPFILE=build/core/envsetup.mk
    741     local HERE=$PWD
    742     T=
    743     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
    744         T=`PWD= /bin/pwd`
    745         if [ -f "$T/Android.mk" ]; then
    746             echo $T/Android.mk
    747             \cd $HERE
    748             return
    749         fi
    750         \cd ..
    751     done
    752     \cd $HERE
    753 }
    754 
    755 function mm()
    756 {
    757     local T=$(gettop)
    758     local DRV=$(getdriver $T)
    759     # If we're sitting in the root of the build tree, just do a
    760     # normal make.
    761     if [ -f build/core/envsetup.mk -a -f Makefile ]; then
    762         $DRV make $@
    763     else
    764         # Find the closest Android.mk file.
    765         local M=$(findmakefile)
    766         local MODULES=
    767         local GET_INSTALL_PATH=
    768         local ARGS=
    769         # Remove the path to top as the makefilepath needs to be relative
    770         local M=`echo $M|sed 's:'$T'/::'`
    771         if [ ! "$T" ]; then
    772             echo "Couldn't locate the top of the tree.  Try setting TOP."
    773             return 1
    774         elif [ ! "$M" ]; then
    775             echo "Couldn't locate a makefile from the current directory."
    776             return 1
    777         else
    778             for ARG in $@; do
    779                 case $ARG in
    780                   GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
    781                 esac
    782             done
    783             if [ -n "$GET_INSTALL_PATH" ]; then
    784               MODULES=
    785               ARGS=GET-INSTALL-PATH
    786             else
    787               MODULES=all_modules
    788               ARGS=$@
    789             fi
    790             ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS
    791         fi
    792     fi
    793 }
    794 
    795 function mmm()
    796 {
    797     local T=$(gettop)
    798     local DRV=$(getdriver $T)
    799     if [ "$T" ]; then
    800         local MAKEFILE=
    801         local MODULES=
    802         local ARGS=
    803         local DIR TO_CHOP
    804         local GET_INSTALL_PATH=
    805         local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
    806         local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
    807         for DIR in $DIRS ; do
    808             MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
    809             if [ "$MODULES" = "" ]; then
    810                 MODULES=all_modules
    811             fi
    812             DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
    813             if [ -f $DIR/Android.mk ]; then
    814                 local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
    815                 local TO_CHOP=`expr $TO_CHOP + 1`
    816                 local START=`PWD= /bin/pwd`
    817                 local MFILE=`echo $START | cut -c${TO_CHOP}-`
    818                 if [ "$MFILE" = "" ] ; then
    819                     MFILE=$DIR/Android.mk
    820                 else
    821                     MFILE=$MFILE/$DIR/Android.mk
    822                 fi
    823                 MAKEFILE="$MAKEFILE $MFILE"
    824             else
    825                 case $DIR in
    826                   showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
    827                   GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;
    828                   *) if [ -d $DIR ]; then
    829                          echo "No Android.mk in $DIR.";
    830                      else
    831                          echo "Couldn't locate the directory $DIR";
    832                      fi
    833                      return 1;;
    834                 esac
    835             fi
    836         done
    837         if [ -n "$GET_INSTALL_PATH" ]; then
    838           ARGS=$GET_INSTALL_PATH
    839           MODULES=
    840         fi
    841         ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
    842     else
    843         echo "Couldn't locate the top of the tree.  Try setting TOP."
    844         return 1
    845     fi
    846 }
    847 
    848 function mma()
    849 {
    850   local T=$(gettop)
    851   local DRV=$(getdriver $T)
    852   if [ -f build/core/envsetup.mk -a -f Makefile ]; then
    853     $DRV make $@
    854   else
    855     if [ ! "$T" ]; then
    856       echo "Couldn't locate the top of the tree.  Try setting TOP."
    857       return 1
    858     fi
    859     local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'`
    860     local MODULES_IN_PATHS=MODULES-IN-$MY_PWD
    861     # Convert "/" to "-".
    862     MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
    863     $DRV make -C $T -f build/core/main.mk $@ $MODULES_IN_PATHS
    864   fi
    865 }
    866 
    867 function mmma()
    868 {
    869   local T=$(gettop)
    870   local DRV=$(getdriver $T)
    871   if [ "$T" ]; then
    872     local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
    873     local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
    874     local MY_PWD=`PWD= /bin/pwd`
    875     if [ "$MY_PWD" = "$T" ]; then
    876       MY_PWD=
    877     else
    878       MY_PWD=`echo $MY_PWD|sed 's:'$T'/::'`
    879     fi
    880     local DIR=
    881     local MODULES_IN_PATHS=
    882     local ARGS=
    883     for DIR in $DIRS ; do
    884       if [ -d $DIR ]; then
    885         # Remove the leading ./ and trailing / if any exists.
    886         DIR=${DIR#./}
    887         DIR=${DIR%/}
    888         if [ "$MY_PWD" != "" ]; then
    889           DIR=$MY_PWD/$DIR
    890         fi
    891         MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$DIR"
    892       else
    893         case $DIR in
    894           showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
    895           *) echo "Couldn't find directory $DIR"; return 1;;
    896         esac
    897       fi
    898     done
    899     # Convert "/" to "-".
    900     MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
    901     $DRV make -C $T -f build/core/main.mk $DASH_ARGS $ARGS $MODULES_IN_PATHS
    902   else
    903     echo "Couldn't locate the top of the tree.  Try setting TOP."
    904     return 1
    905   fi
    906 }
    907 
    908 function croot()
    909 {
    910     T=$(gettop)
    911     if [ "$T" ]; then
    912         \cd $(gettop)
    913     else
    914         echo "Couldn't locate the top of the tree.  Try setting TOP."
    915     fi
    916 }
    917 
    918 function cproj()
    919 {
    920     TOPFILE=build/core/envsetup.mk
    921     local HERE=$PWD
    922     T=
    923     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
    924         T=$PWD
    925         if [ -f "$T/Android.mk" ]; then
    926             \cd $T
    927             return
    928         fi
    929         \cd ..
    930     done
    931     \cd $HERE
    932     echo "can't find Android.mk"
    933 }
    934 
    935 # simplified version of ps; output in the form
    936 # <pid> <procname>
    937 function qpid() {
    938     local prepend=''
    939     local append=''
    940     if [ "$1" = "--exact" ]; then
    941         prepend=' '
    942         append='$'
    943         shift
    944     elif [ "$1" = "--help" -o "$1" = "-h" ]; then
    945         echo "usage: qpid [[--exact] <process name|pid>"
    946         return 255
    947     fi
    948 
    949     local EXE="$1"
    950     if [ "$EXE" ] ; then
    951         qpid | \grep "$prepend$EXE$append"
    952     else
    953         adb shell ps \
    954             | tr -d '\r' \
    955             | sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/'
    956     fi
    957 }
    958 
    959 function pid()
    960 {
    961     local prepend=''
    962     local append=''
    963     if [ "$1" = "--exact" ]; then
    964         prepend=' '
    965         append='$'
    966         shift
    967     fi
    968     local EXE="$1"
    969     if [ "$EXE" ] ; then
    970         local PID=`adb shell ps \
    971             | tr -d '\r' \
    972             | \grep "$prepend$EXE$append" \
    973             | sed -e 's/^[^ ]* *\([0-9]*\).*$/\1/'`
    974         echo "$PID"
    975     else
    976         echo "usage: pid [--exact] <process name>"
    977         return 255
    978     fi
    979 }
    980 
    981 # coredump_setup - enable core dumps globally for any process
    982 #                  that has the core-file-size limit set correctly
    983 #
    984 # NOTE: You must call also coredump_enable for a specific process
    985 #       if its core-file-size limit is not set already.
    986 # NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
    987 
    988 function coredump_setup()
    989 {
    990     echo "Getting root...";
    991     adb root;
    992     adb wait-for-device;
    993 
    994     echo "Remounting root partition read-write...";
    995     adb shell mount -w -o remount -t rootfs rootfs;
    996     sleep 1;
    997     adb wait-for-device;
    998     adb shell mkdir -p /cores;
    999     adb shell mount -t tmpfs tmpfs /cores;
   1000     adb shell chmod 0777 /cores;
   1001 
   1002     echo "Granting SELinux permission to dump in /cores...";
   1003     adb shell restorecon -R /cores;
   1004 
   1005     echo "Set core pattern.";
   1006     adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
   1007 
   1008     echo "Done."
   1009 }
   1010 
   1011 # coredump_enable - enable core dumps for the specified process
   1012 # $1 = PID of process (e.g., $(pid mediaserver))
   1013 #
   1014 # NOTE: coredump_setup must have been called as well for a core
   1015 #       dump to actually be generated.
   1016 
   1017 function coredump_enable()
   1018 {
   1019     local PID=$1;
   1020     if [ -z "$PID" ]; then
   1021         printf "Expecting a PID!\n";
   1022         return;
   1023     fi;
   1024     echo "Setting core limit for $PID to infinite...";
   1025     adb shell prlimit $PID 4 -1 -1
   1026 }
   1027 
   1028 # core - send SIGV and pull the core for process
   1029 # $1 = PID of process (e.g., $(pid mediaserver))
   1030 #
   1031 # NOTE: coredump_setup must be called once per boot for core dumps to be
   1032 #       enabled globally.
   1033 
   1034 function core()
   1035 {
   1036     local PID=$1;
   1037 
   1038     if [ -z "$PID" ]; then
   1039         printf "Expecting a PID!\n";
   1040         return;
   1041     fi;
   1042 
   1043     local CORENAME=core.$PID;
   1044     local COREPATH=/cores/$CORENAME;
   1045     local SIG=SEGV;
   1046 
   1047     coredump_enable $1;
   1048 
   1049     local done=0;
   1050     while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
   1051         printf "\tSending SIG%s to %d...\n" $SIG $PID;
   1052         adb shell kill -$SIG $PID;
   1053         sleep 1;
   1054     done;
   1055 
   1056     adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
   1057     echo "Done: core is under $COREPATH on device.";
   1058 }
   1059 
   1060 # systemstack - dump the current stack trace of all threads in the system process
   1061 # to the usual ANR traces file
   1062 function systemstack()
   1063 {
   1064     stacks system_server
   1065 }
   1066 
   1067 function stacks()
   1068 {
   1069     if [[ $1 =~ ^[0-9]+$ ]] ; then
   1070         local PID="$1"
   1071     elif [ "$1" ] ; then
   1072         local PIDLIST="$(pid $1)"
   1073         if [[ $PIDLIST =~ ^[0-9]+$ ]] ; then
   1074             local PID="$PIDLIST"
   1075         elif [ "$PIDLIST" ] ; then
   1076             echo "more than one process: $1"
   1077         else
   1078             echo "no such process: $1"
   1079         fi
   1080     else
   1081         echo "usage: stacks [pid|process name]"
   1082     fi
   1083 
   1084     if [ "$PID" ] ; then
   1085         # Determine whether the process is native
   1086         if adb shell ls -l /proc/$PID/exe | grep -q /system/bin/app_process ; then
   1087             # Dump stacks of Dalvik process
   1088             local TRACES=/data/anr/traces.txt
   1089             local ORIG=/data/anr/traces.orig
   1090             local TMP=/data/anr/traces.tmp
   1091 
   1092             # Keep original traces to avoid clobbering
   1093             adb shell mv $TRACES $ORIG
   1094 
   1095             # Make sure we have a usable file
   1096             adb shell touch $TRACES
   1097             adb shell chmod 666 $TRACES
   1098 
   1099             # Dump stacks and wait for dump to finish
   1100             adb shell kill -3 $PID
   1101             adb shell notify $TRACES >/dev/null
   1102 
   1103             # Restore original stacks, and show current output
   1104             adb shell mv $TRACES $TMP
   1105             adb shell mv $ORIG $TRACES
   1106             adb shell cat $TMP
   1107         else
   1108             # Dump stacks of native process
   1109             local USE64BIT="$(is64bit $PID)"
   1110             adb shell debuggerd$USE64BIT -b $PID
   1111         fi
   1112     fi
   1113 }
   1114 
   1115 # Read the ELF header from /proc/$PID/exe to determine if the process is
   1116 # 64-bit.
   1117 function is64bit()
   1118 {
   1119     local PID="$1"
   1120     if [ "$PID" ] ; then
   1121         if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -ps)" -eq "02" ]] ; then
   1122             echo "64"
   1123         else
   1124             echo ""
   1125         fi
   1126     else
   1127         echo ""
   1128     fi
   1129 }
   1130 
   1131 case `uname -s` in
   1132     Darwin)
   1133         function sgrep()
   1134         {
   1135             find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cc|cpp|S|java|xml|sh|mk|aidl|vts)' \
   1136                 -exec grep --color -n "$@" {} +
   1137         }
   1138 
   1139         ;;
   1140     *)
   1141         function sgrep()
   1142         {
   1143             find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cc\|cpp\|S\|java\|xml\|sh\|mk\|aidl\|vts\)' \
   1144                 -exec grep --color -n "$@" {} +
   1145         }
   1146         ;;
   1147 esac
   1148 
   1149 function gettargetarch
   1150 {
   1151     get_build_var TARGET_ARCH
   1152 }
   1153 
   1154 function ggrep()
   1155 {
   1156     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" \
   1157         -exec grep --color -n "$@" {} +
   1158 }
   1159 
   1160 function jgrep()
   1161 {
   1162     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" \
   1163         -exec grep --color -n "$@" {} +
   1164 }
   1165 
   1166 function cgrep()
   1167 {
   1168     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \
   1169         -exec grep --color -n "$@" {} +
   1170 }
   1171 
   1172 function resgrep()
   1173 {
   1174     for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do
   1175         find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} +
   1176     done
   1177 }
   1178 
   1179 function mangrep()
   1180 {
   1181     find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' \
   1182         -exec grep --color -n "$@" {} +
   1183 }
   1184 
   1185 function sepgrep()
   1186 {
   1187     find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \
   1188         -exec grep --color -n -r --exclude-dir=\.git "$@" {} +
   1189 }
   1190 
   1191 function rcgrep()
   1192 {
   1193     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rc*" \
   1194         -exec grep --color -n "$@" {} +
   1195 }
   1196 
   1197 case `uname -s` in
   1198     Darwin)
   1199         function mgrep()
   1200         {
   1201             find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' \
   1202                 -exec grep --color -n "$@" {} +
   1203         }
   1204 
   1205         function treegrep()
   1206         {
   1207             find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|S|java|xml)' \
   1208                 -exec grep --color -n -i "$@" {} +
   1209         }
   1210 
   1211         ;;
   1212     *)
   1213         function mgrep()
   1214         {
   1215             find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f \
   1216                 -exec grep --color -n "$@" {} +
   1217         }
   1218 
   1219         function treegrep()
   1220         {
   1221             find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f \
   1222                 -exec grep --color -n -i "$@" {} +
   1223         }
   1224 
   1225         ;;
   1226 esac
   1227 
   1228 function getprebuilt
   1229 {
   1230     get_abs_build_var ANDROID_PREBUILTS
   1231 }
   1232 
   1233 function tracedmdump()
   1234 {
   1235     T=$(gettop)
   1236     if [ ! "$T" ]; then
   1237         echo "Couldn't locate the top of the tree.  Try setting TOP."
   1238         return
   1239     fi
   1240     local prebuiltdir=$(getprebuilt)
   1241     local arch=$(gettargetarch)
   1242     local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu
   1243 
   1244     local TRACE=$1
   1245     if [ ! "$TRACE" ] ; then
   1246         echo "usage:  tracedmdump  tracename"
   1247         return
   1248     fi
   1249 
   1250     if [ ! -r "$KERNEL" ] ; then
   1251         echo "Error: cannot find kernel: '$KERNEL'"
   1252         return
   1253     fi
   1254 
   1255     local BASETRACE=$(basename $TRACE)
   1256     if [ "$BASETRACE" = "$TRACE" ] ; then
   1257         TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
   1258     fi
   1259 
   1260     echo "post-processing traces..."
   1261     rm -f $TRACE/qtrace.dexlist
   1262     post_trace $TRACE
   1263     if [ $? -ne 0 ]; then
   1264         echo "***"
   1265         echo "*** Error: malformed trace.  Did you remember to exit the emulator?"
   1266         echo "***"
   1267         return
   1268     fi
   1269     echo "generating dexlist output..."
   1270     /bin/ls $ANDROID_PRODUCT_OUT/system/framework/*.jar $ANDROID_PRODUCT_OUT/system/app/*.apk $ANDROID_PRODUCT_OUT/data/app/*.apk 2>/dev/null | xargs dexlist > $TRACE/qtrace.dexlist
   1271     echo "generating dmtrace data..."
   1272     q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
   1273     echo "generating html file..."
   1274     dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
   1275     echo "done, see $TRACE/dmtrace.html for details"
   1276     echo "or run:"
   1277     echo "    traceview $TRACE/dmtrace"
   1278 }
   1279 
   1280 # communicate with a running device or emulator, set up necessary state,
   1281 # and run the hat command.
   1282 function runhat()
   1283 {
   1284     # process standard adb options
   1285     local adbTarget=""
   1286     if [ "$1" = "-d" -o "$1" = "-e" ]; then
   1287         adbTarget=$1
   1288         shift 1
   1289     elif [ "$1" = "-s" ]; then
   1290         adbTarget="$1 $2"
   1291         shift 2
   1292     fi
   1293     local adbOptions=${adbTarget}
   1294     #echo adbOptions = ${adbOptions}
   1295 
   1296     # runhat options
   1297     local targetPid=$1
   1298 
   1299     if [ "$targetPid" = "" ]; then
   1300         echo "Usage: runhat [ -d | -e | -s serial ] target-pid"
   1301         return
   1302     fi
   1303 
   1304     # confirm hat is available
   1305     if [ -z $(which hat) ]; then
   1306         echo "hat is not available in this configuration."
   1307         return
   1308     fi
   1309 
   1310     # issue "am" command to cause the hprof dump
   1311     local devFile=/data/local/tmp/hprof-$targetPid
   1312     echo "Poking $targetPid and waiting for data..."
   1313     echo "Storing data at $devFile"
   1314     adb ${adbOptions} shell am dumpheap $targetPid $devFile
   1315     echo "Press enter when logcat shows \"hprof: heap dump completed\""
   1316     echo -n "> "
   1317     read
   1318 
   1319     local localFile=/tmp/$$-hprof
   1320 
   1321     echo "Retrieving file $devFile..."
   1322     adb ${adbOptions} pull $devFile $localFile
   1323 
   1324     adb ${adbOptions} shell rm $devFile
   1325 
   1326     echo "Running hat on $localFile"
   1327     echo "View the output by pointing your browser at http://localhost:7000/"
   1328     echo ""
   1329     hat -JXmx512m $localFile
   1330 }
   1331 
   1332 function getbugreports()
   1333 {
   1334     local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
   1335 
   1336     if [ ! "$reports" ]; then
   1337         echo "Could not locate any bugreports."
   1338         return
   1339     fi
   1340 
   1341     local report
   1342     for report in ${reports[@]}
   1343     do
   1344         echo "/sdcard/bugreports/${report}"
   1345         adb pull /sdcard/bugreports/${report} ${report}
   1346         gunzip ${report}
   1347     done
   1348 }
   1349 
   1350 function getsdcardpath()
   1351 {
   1352     adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
   1353 }
   1354 
   1355 function getscreenshotpath()
   1356 {
   1357     echo "$(getsdcardpath)/Pictures/Screenshots"
   1358 }
   1359 
   1360 function getlastscreenshot()
   1361 {
   1362     local screenshot_path=$(getscreenshotpath)
   1363     local screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1`
   1364     if [ "$screenshot" = "" ]; then
   1365         echo "No screenshots found."
   1366         return
   1367     fi
   1368     echo "${screenshot}"
   1369     adb ${adbOptions} pull ${screenshot_path}/${screenshot}
   1370 }
   1371 
   1372 function startviewserver()
   1373 {
   1374     local port=4939
   1375     if [ $# -gt 0 ]; then
   1376             port=$1
   1377     fi
   1378     adb shell service call window 1 i32 $port
   1379 }
   1380 
   1381 function stopviewserver()
   1382 {
   1383     adb shell service call window 2
   1384 }
   1385 
   1386 function isviewserverstarted()
   1387 {
   1388     adb shell service call window 3
   1389 }
   1390 
   1391 function key_home()
   1392 {
   1393     adb shell input keyevent 3
   1394 }
   1395 
   1396 function key_back()
   1397 {
   1398     adb shell input keyevent 4
   1399 }
   1400 
   1401 function key_menu()
   1402 {
   1403     adb shell input keyevent 82
   1404 }
   1405 
   1406 function smoketest()
   1407 {
   1408     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
   1409         echo "Couldn't locate output files.  Try running 'lunch' first." >&2
   1410         return
   1411     fi
   1412     T=$(gettop)
   1413     if [ ! "$T" ]; then
   1414         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
   1415         return
   1416     fi
   1417 
   1418     (\cd "$T" && mmm tests/SmokeTest) &&
   1419       adb uninstall com.android.smoketest > /dev/null &&
   1420       adb uninstall com.android.smoketest.tests > /dev/null &&
   1421       adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
   1422       adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk &&
   1423       adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
   1424 }
   1425 
   1426 # simple shortcut to the runtest command
   1427 function runtest()
   1428 {
   1429     T=$(gettop)
   1430     if [ ! "$T" ]; then
   1431         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
   1432         return
   1433     fi
   1434     ("$T"/development/testrunner/runtest.py $@)
   1435 }
   1436 
   1437 function godir () {
   1438     if [[ -z "$1" ]]; then
   1439         echo "Usage: godir <regex>"
   1440         return
   1441     fi
   1442     T=$(gettop)
   1443     if [ ! "$OUT_DIR" = "" ]; then
   1444         mkdir -p $OUT_DIR
   1445         FILELIST=$OUT_DIR/filelist
   1446     else
   1447         FILELIST=$T/filelist
   1448     fi
   1449     if [[ ! -f $FILELIST ]]; then
   1450         echo -n "Creating index..."
   1451         (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST)
   1452         echo " Done"
   1453         echo ""
   1454     fi
   1455     local lines
   1456     lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq))
   1457     if [[ ${#lines[@]} = 0 ]]; then
   1458         echo "Not found"
   1459         return
   1460     fi
   1461     local pathname
   1462     local choice
   1463     if [[ ${#lines[@]} > 1 ]]; then
   1464         while [[ -z "$pathname" ]]; do
   1465             local index=1
   1466             local line
   1467             for line in ${lines[@]}; do
   1468                 printf "%6s %s\n" "[$index]" $line
   1469                 index=$(($index + 1))
   1470             done
   1471             echo
   1472             echo -n "Select one: "
   1473             unset choice
   1474             read choice
   1475             if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
   1476                 echo "Invalid choice"
   1477                 continue
   1478             fi
   1479             pathname=${lines[$(($choice-1))]}
   1480         done
   1481     else
   1482         pathname=${lines[0]}
   1483     fi
   1484     \cd $T/$pathname
   1485 }
   1486 
   1487 # Force JAVA_HOME to point to java 1.7/1.8 if it isn't already set.
   1488 function set_java_home() {
   1489     # Clear the existing JAVA_HOME value if we set it ourselves, so that
   1490     # we can reset it later, depending on the version of java the build
   1491     # system needs.
   1492     #
   1493     # If we don't do this, the JAVA_HOME value set by the first call to
   1494     # build/envsetup.sh will persist forever.
   1495     if [ -n "$ANDROID_SET_JAVA_HOME" ]; then
   1496       export JAVA_HOME=""
   1497     fi
   1498 
   1499     if [ ! "$JAVA_HOME" ]; then
   1500       if [ -n "$LEGACY_USE_JAVA7" ]; then
   1501         echo Warning: Support for JDK 7 will be dropped. Switch to JDK 8.
   1502         case `uname -s` in
   1503             Darwin)
   1504                 export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
   1505                 ;;
   1506             *)
   1507                 export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
   1508                 ;;
   1509         esac
   1510       else
   1511         case `uname -s` in
   1512             Darwin)
   1513                 export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
   1514                 ;;
   1515             *)
   1516                 export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
   1517                 ;;
   1518         esac
   1519       fi
   1520 
   1521       # Keep track of the fact that we set JAVA_HOME ourselves, so that
   1522       # we can change it on the next envsetup.sh, if required.
   1523       export ANDROID_SET_JAVA_HOME=true
   1524     fi
   1525 }
   1526 
   1527 # Print colored exit condition
   1528 function pez {
   1529     "$@"
   1530     local retval=$?
   1531     if [ $retval -ne 0 ]
   1532     then
   1533         echo $'\E'"[0;31mFAILURE\e[00m"
   1534     else
   1535         echo $'\E'"[0;32mSUCCESS\e[00m"
   1536     fi
   1537     return $retval
   1538 }
   1539 
   1540 function get_make_command()
   1541 {
   1542   echo command make
   1543 }
   1544 
   1545 function make()
   1546 {
   1547     local start_time=$(date +"%s")
   1548     $(get_make_command) "$@"
   1549     local ret=$?
   1550     local end_time=$(date +"%s")
   1551     local tdiff=$(($end_time-$start_time))
   1552     local hours=$(($tdiff / 3600 ))
   1553     local mins=$((($tdiff % 3600) / 60))
   1554     local secs=$(($tdiff % 60))
   1555     local ncolors=$(tput colors 2>/dev/null)
   1556     if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
   1557         color_failed=$'\E'"[0;31m"
   1558         color_success=$'\E'"[0;32m"
   1559         color_reset=$'\E'"[00m"
   1560     else
   1561         color_failed=""
   1562         color_success=""
   1563         color_reset=""
   1564     fi
   1565     echo
   1566     if [ $ret -eq 0 ] ; then
   1567         echo -n "${color_success}#### make completed successfully "
   1568     else
   1569         echo -n "${color_failed}#### make failed to build some targets "
   1570     fi
   1571     if [ $hours -gt 0 ] ; then
   1572         printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
   1573     elif [ $mins -gt 0 ] ; then
   1574         printf "(%02g:%02g (mm:ss))" $mins $secs
   1575     elif [ $secs -gt 0 ] ; then
   1576         printf "(%s seconds)" $secs
   1577     fi
   1578     echo " ####${color_reset}"
   1579     echo
   1580     return $ret
   1581 }
   1582 
   1583 function provision()
   1584 {
   1585     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
   1586         echo "Couldn't locate output files.  Try running 'lunch' first." >&2
   1587         return 1
   1588     fi
   1589     if [ ! -e "$ANDROID_PRODUCT_OUT/provision-device" ]; then
   1590         echo "There is no provisioning script for the device." >&2
   1591         return 1
   1592     fi
   1593 
   1594     # Check if user really wants to do this.
   1595     if [ "$1" = "--no-confirmation" ]; then
   1596         shift 1
   1597     else
   1598         echo "This action will reflash your device."
   1599         echo ""
   1600         echo "ALL DATA ON THE DEVICE WILL BE IRREVOCABLY ERASED."
   1601         echo ""
   1602         echo -n "Are you sure you want to do this (yes/no)? "
   1603         read
   1604         if [[ "${REPLY}" != "yes" ]] ; then
   1605             echo "Not taking any action. Exiting." >&2
   1606             return 1
   1607         fi
   1608     fi
   1609     "$ANDROID_PRODUCT_OUT/provision-device" "$@"
   1610 }
   1611 
   1612 if [ "x$SHELL" != "x/bin/bash" ]; then
   1613     case `ps -o command -p $$` in
   1614         *bash*)
   1615             ;;
   1616         *)
   1617             echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
   1618             ;;
   1619     esac
   1620 fi
   1621 
   1622 # Execute the contents of any vendorsetup.sh files we can find.
   1623 for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
   1624          `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
   1625          `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
   1626 do
   1627     echo "including $f"
   1628     . $f
   1629 done
   1630 unset f
   1631 
   1632 addcompletions
   1633