OSDN Git Service

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