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