envsetup.sh revision 7dfdb843b25b4ef04c47b148e0095f292eceacd4
1function hmm() {
2cat <<EOF
3Invoke ". 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
24Environment 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
29Look at the source to view more functions. The complete list is:
30EOF
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.
41function 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    unset build_dicts_script
64    ret=$?
65    if [ $ret -ne 0 ]
66    then
67        return $ret
68    fi
69    BUILD_VAR_CACHE_READY="true"
70}
71
72# Delete the build cache, so that we can still call into the build system
73# to get build variables not listed in this script.
74function 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.
88function 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.
106function 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
124function 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
139VARIANT_CHOICES=(user userdebug eng)
140
141# check to see if the supplied variant is valid
142function 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
154function 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
268function 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
278function 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
291function set_sequence_number()
292{
293    export BUILD_ENV_SEQUENCE_NUMBER=10
294}
295
296function 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
311function 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
334function 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#
394function 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
435function 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
482function 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.
503unset LUNCH_MENU_CHOICES
504function 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
517add_lunch_combo aosp_arm-eng
518add_lunch_combo aosp_arm64-eng
519add_lunch_combo aosp_mips-eng
520add_lunch_combo aosp_mips64-eng
521add_lunch_combo aosp_x86-eng
522add_lunch_combo aosp_x86_64-eng
523
524function 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
543function 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.
620function _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}
630complete -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)
634function 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
685function 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)
713function 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
726function 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
738function 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
755function 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
795function 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
848function 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
867function 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
908function 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
918function 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>
937function 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
959function 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
988function 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
1017function 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
1034function 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
1062function systemstack()
1063{
1064    stacks system_server
1065}
1066
1067function 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.
1117function 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
1131case `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)' \
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\)' \
1144                -exec grep --color -n "$@" {} +
1145        }
1146        ;;
1147esac
1148
1149function gettargetarch
1150{
1151    get_build_var TARGET_ARCH
1152}
1153
1154function 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
1160function 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
1166function 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
1172function 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
1179function 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
1185function 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
1191function 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
1197case `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        ;;
1226esac
1227
1228function getprebuilt
1229{
1230    get_abs_build_var ANDROID_PREBUILTS
1231}
1232
1233function 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.
1282function 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
1332function 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
1350function getsdcardpath()
1351{
1352    adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
1353}
1354
1355function getscreenshotpath()
1356{
1357    echo "$(getsdcardpath)/Pictures/Screenshots"
1358}
1359
1360function 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
1372function 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
1381function stopviewserver()
1382{
1383    adb shell service call window 2
1384}
1385
1386function isviewserverstarted()
1387{
1388    adb shell service call window 3
1389}
1390
1391function key_home()
1392{
1393    adb shell input keyevent 3
1394}
1395
1396function key_back()
1397{
1398    adb shell input keyevent 4
1399}
1400
1401function key_menu()
1402{
1403    adb shell input keyevent 82
1404}
1405
1406function 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
1427function 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
1437function 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.
1488function 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
1528function 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
1540function get_make_command()
1541{
1542  echo command make
1543}
1544
1545function 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
1583function 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
1612if [ "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
1620fi
1621
1622# Execute the contents of any vendorsetup.sh files we can find.
1623for 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`
1626do
1627    echo "including $f"
1628    . $f
1629done
1630unset f
1631
1632addcompletions
1633