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