OSDN Git Service

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