OSDN Git Service

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