OSDN Git Service

build: Add "installrecovery" command
[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 - mmp:       Builds all of the modules in the current directory and pushes them to the device.
14 - mmmp:      Builds all of the modules in the supplied directories and pushes them to the device.
15 - provision: Flash device with all required partitions. Options will be passed on to fastboot.
16 - cgrep:     Greps on all local C/C++ files.
17 - ggrep:     Greps on all local Gradle files.
18 - jgrep:     Greps on all local Java files.
19 - resgrep:   Greps on all local res/*.xml files.
20 - mangrep:   Greps on all local AndroidManifest.xml files.
21 - mgrep:     Greps on all local Makefiles files.
22 - sepgrep:   Greps on all local sepolicy files.
23 - sgrep:     Greps on all local source files.
24 - godir:     Go to the directory containing a file.
25 - cmremote:  Add git remote for CM Gerrit Review
26 - cmgerrit:  A Git wrapper that fetches/pushes patch from/to CM Gerrit Review
27 - aospremote: Add git remote for matching AOSP repository
28 - cmrebase:  Rebase a Gerrit change and push it again
29 - mka:       Builds using SCHED_BATCH on all processors
30 - reposync:  Parallel repo sync using ionice and SCHED_BATCH
31 - installboot: Installs a boot.img to the connected device.
32 - installrecovery: Installs a recovery.img to the connected device.
33 - repodiff:  Diff 2 different branches or tags within the same repo
34
35 Environment options:
36 - SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
37                  ASAN_OPTIONS=detect_leaks=0 will be set by default until the
38                  build is leak-check clean.
39
40 Look at the source to view more functions. The complete list is:
41 EOF
42     T=$(gettop)
43     local A
44     A=""
45     for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
46       A="$A $i"
47     done
48     echo $A
49 }
50
51 # Get all the build variables needed by this script in a single call to the build system.
52 function build_build_var_cache()
53 {
54     T=$(gettop)
55     # Grep out the variable names from the script.
56     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' ' '`
57     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' ' '`
58     # Call the build system to dump the "<val>=<value>" pairs as a shell script.
59     build_dicts_script=`\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
60                         command make --no-print-directory -f build/core/config.mk \
61                         dump-many-vars \
62                         DUMP_MANY_VARS="$cached_vars" \
63                         DUMP_MANY_ABS_VARS="$cached_abs_vars" \
64                         DUMP_VAR_PREFIX="var_cache_" \
65                         DUMP_ABS_VAR_PREFIX="abs_var_cache_"`
66     local ret=$?
67     if [ $ret -ne 0 ]
68     then
69         unset build_dicts_script
70         return $ret
71     fi
72     # Excute the script to store the "<val>=<value>" pairs as shell variables.
73     eval "$build_dicts_script"
74     ret=$?
75     unset build_dicts_script
76     if [ $ret -ne 0 ]
77     then
78         return $ret
79     fi
80     BUILD_VAR_CACHE_READY="true"
81 }
82
83 # Delete the build var cache, so that we can still call into the build system
84 # to get build variables not listed in this script.
85 function destroy_build_var_cache()
86 {
87     unset BUILD_VAR_CACHE_READY
88     for v in $cached_vars; do
89       unset var_cache_$v
90     done
91     unset cached_vars
92     for v in $cached_abs_vars; do
93       unset abs_var_cache_$v
94     done
95     unset cached_abs_vars
96 }
97
98 # Get the value of a build variable as an absolute path.
99 function get_abs_build_var()
100 {
101     if [ "$BUILD_VAR_CACHE_READY" = "true" ]
102     then
103         eval echo \"\${abs_var_cache_$1}\"
104     return
105     fi
106
107     T=$(gettop)
108     if [ ! "$T" ]; then
109         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
110         return
111     fi
112     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
113       command make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
114 }
115
116 # Get the exact value of a build variable.
117 function get_build_var()
118 {
119     if [ "$BUILD_VAR_CACHE_READY" = "true" ]
120     then
121         eval echo \"\${var_cache_$1}\"
122     return
123     fi
124
125     T=$(gettop)
126     if [ ! "$T" ]; then
127         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
128         return
129     fi
130     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
131       command make --no-print-directory -f build/core/config.mk dumpvar-$1)
132 }
133
134 # check to see if the supplied product is one we can build
135 function check_product()
136 {
137     T=$(gettop)
138     if [ ! "$T" ]; then
139         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
140         return
141     fi
142
143     if (echo -n $1 | grep -q -e "^cm_") ; then
144        CM_BUILD=$(echo -n $1 | sed -e 's/^cm_//g')
145     else
146        CM_BUILD=
147     fi
148     export CM_BUILD
149
150         TARGET_PRODUCT=$1 \
151         TARGET_BUILD_VARIANT= \
152         TARGET_BUILD_TYPE= \
153         TARGET_BUILD_APPS= \
154         get_build_var TARGET_DEVICE > /dev/null
155     # hide successful answers, but allow the errors to show
156 }
157
158 VARIANT_CHOICES=(user userdebug eng)
159
160 # check to see if the supplied variant is valid
161 function check_variant()
162 {
163     for v in ${VARIANT_CHOICES[@]}
164     do
165         if [ "$v" = "$1" ]
166         then
167             return 0
168         fi
169     done
170     return 1
171 }
172
173 function setpaths()
174 {
175     T=$(gettop)
176     if [ ! "$T" ]; then
177         echo "Couldn't locate the top of the tree.  Try setting TOP."
178         return
179     fi
180
181     ##################################################################
182     #                                                                #
183     #              Read me before you modify this code               #
184     #                                                                #
185     #   This function sets ANDROID_BUILD_PATHS to what it is adding  #
186     #   to PATH, and the next time it is run, it removes that from   #
187     #   PATH.  This is required so lunch can be run more than once   #
188     #   and still have working paths.                                #
189     #                                                                #
190     ##################################################################
191
192     # Note: on windows/cygwin, ANDROID_BUILD_PATHS will contain spaces
193     # due to "C:\Program Files" being in the path.
194
195     # out with the old
196     if [ -n "$ANDROID_BUILD_PATHS" ] ; then
197         export PATH=${PATH/$ANDROID_BUILD_PATHS/}
198     fi
199     if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then
200         export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}
201         # strip leading ':', if any
202         export PATH=${PATH/:%/}
203     fi
204
205     # and in with the new
206     prebuiltdir=$(getprebuilt)
207     gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
208
209     # defined in core/config.mk
210     targetgccversion=$(get_build_var TARGET_GCC_VERSION)
211     targetgccversion2=$(get_build_var 2ND_TARGET_GCC_VERSION)
212     export TARGET_GCC_VERSION=$targetgccversion
213
214     # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.
215     export ANDROID_TOOLCHAIN=
216     export ANDROID_TOOLCHAIN_2ND_ARCH=
217     local ARCH=$(get_build_var TARGET_ARCH)
218     case $ARCH in
219         x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
220             ;;
221         x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
222             ;;
223         arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
224             ;;
225         arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin;
226                toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
227             ;;
228         mips|mips64) toolchaindir=mips/mips64el-linux-android-$targetgccversion/bin
229             ;;
230         *)
231             echo "Can't find toolchain for unknown architecture: $ARCH"
232             toolchaindir=xxxxxxxxx
233             ;;
234     esac
235     if [ -d "$gccprebuiltdir/$toolchaindir" ]; then
236         export ANDROID_TOOLCHAIN=$gccprebuiltdir/$toolchaindir
237     fi
238
239     if [ -d "$gccprebuiltdir/$toolchaindir2" ]; then
240         export ANDROID_TOOLCHAIN_2ND_ARCH=$gccprebuiltdir/$toolchaindir2
241     fi
242
243     export ANDROID_DEV_SCRIPTS=$T/development/scripts:$T/prebuilts/devtools/tools:$T/external/selinux/prebuilts/bin
244     export ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_TOOLCHAIN:$ANDROID_TOOLCHAIN_2ND_ARCH:$ANDROID_DEV_SCRIPTS:
245
246     # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
247     # to ensure that the corresponding 'emulator' binaries are used.
248     case $(uname -s) in
249         Darwin)
250             ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64
251             ;;
252         Linux)
253             ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64
254             ;;
255         *)
256             ANDROID_EMULATOR_PREBUILTS=
257             ;;
258     esac
259     if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
260         ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS$ANDROID_EMULATOR_PREBUILTS:
261         export ANDROID_EMULATOR_PREBUILTS
262     fi
263
264     export PATH=$ANDROID_BUILD_PATHS$PATH
265     export PYTHONPATH=$T/development/python-packages:$PYTHONPATH
266
267     unset ANDROID_JAVA_TOOLCHAIN
268     unset ANDROID_PRE_BUILD_PATHS
269     if [ -n "$JAVA_HOME" ]; then
270         export ANDROID_JAVA_TOOLCHAIN=$JAVA_HOME/bin
271         export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN:
272         export PATH=$ANDROID_PRE_BUILD_PATHS$PATH
273     fi
274
275     unset ANDROID_PRODUCT_OUT
276     export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
277     export OUT=$ANDROID_PRODUCT_OUT
278
279     unset ANDROID_HOST_OUT
280     export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT)
281
282     # needed for building linux on MacOS
283     # TODO: fix the path
284     #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
285 }
286
287 function printconfig()
288 {
289     T=$(gettop)
290     if [ ! "$T" ]; then
291         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
292         return
293     fi
294     get_build_var report_config
295 }
296
297 function set_stuff_for_environment()
298 {
299     settitle
300     set_java_home
301     setpaths
302     set_sequence_number
303
304     export ANDROID_BUILD_TOP=$(gettop)
305     # With this environment variable new GCC can apply colors to warnings/errors
306     export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
307     export ASAN_OPTIONS=detect_leaks=0
308 }
309
310 function set_sequence_number()
311 {
312     export BUILD_ENV_SEQUENCE_NUMBER=10
313 }
314
315 function settitle()
316 {
317     if [ "$STAY_OFF_MY_LAWN" = "" ]; then
318         local arch=$(gettargetarch)
319         local product=$TARGET_PRODUCT
320         local variant=$TARGET_BUILD_VARIANT
321         local apps=$TARGET_BUILD_APPS
322         if [ -z "$apps" ]; then
323             export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
324         else
325             export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""
326         fi
327     fi
328 }
329
330 function addcompletions()
331 {
332     local T dir f
333
334     # Keep us from trying to run in something that isn't bash.
335     if [ -z "${BASH_VERSION}" ]; then
336         return
337     fi
338
339     # Keep us from trying to run in bash that's too old.
340     if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
341         return
342     fi
343
344     dir="sdk/bash_completion"
345     if [ -d ${dir} ]; then
346         for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
347             echo "including $f"
348             . $f
349         done
350     fi
351 }
352
353 function choosetype()
354 {
355     echo "Build type choices are:"
356     echo "     1. release"
357     echo "     2. debug"
358     echo
359
360     local DEFAULT_NUM DEFAULT_VALUE
361     DEFAULT_NUM=1
362     DEFAULT_VALUE=release
363
364     export TARGET_BUILD_TYPE=
365     local ANSWER
366     while [ -z $TARGET_BUILD_TYPE ]
367     do
368         echo -n "Which would you like? ["$DEFAULT_NUM"] "
369         if [ -z "$1" ] ; then
370             read ANSWER
371         else
372             echo $1
373             ANSWER=$1
374         fi
375         case $ANSWER in
376         "")
377             export TARGET_BUILD_TYPE=$DEFAULT_VALUE
378             ;;
379         1)
380             export TARGET_BUILD_TYPE=release
381             ;;
382         release)
383             export TARGET_BUILD_TYPE=release
384             ;;
385         2)
386             export TARGET_BUILD_TYPE=debug
387             ;;
388         debug)
389             export TARGET_BUILD_TYPE=debug
390             ;;
391         *)
392             echo
393             echo "I didn't understand your response.  Please try again."
394             echo
395             ;;
396         esac
397         if [ -n "$1" ] ; then
398             break
399         fi
400     done
401
402     build_build_var_cache
403     set_stuff_for_environment
404     destroy_build_var_cache
405 }
406
407 #
408 # This function isn't really right:  It chooses a TARGET_PRODUCT
409 # based on the list of boards.  Usually, that gets you something
410 # that kinda works with a generic product, but really, you should
411 # pick a product by name.
412 #
413 function chooseproduct()
414 {
415     if [ "x$TARGET_PRODUCT" != x ] ; then
416         default_value=$TARGET_PRODUCT
417     else
418         default_value=aosp_arm
419     fi
420
421     export TARGET_BUILD_APPS=
422     export TARGET_PRODUCT=
423     local ANSWER
424     while [ -z "$TARGET_PRODUCT" ]
425     do
426         echo -n "Which product would you like? [$default_value] "
427         if [ -z "$1" ] ; then
428             read ANSWER
429         else
430             echo $1
431             ANSWER=$1
432         fi
433
434         if [ -z "$ANSWER" ] ; then
435             export TARGET_PRODUCT=$default_value
436         else
437             if check_product $ANSWER
438             then
439                 export TARGET_PRODUCT=$ANSWER
440             else
441                 echo "** Not a valid product: $ANSWER"
442             fi
443         fi
444         if [ -n "$1" ] ; then
445             break
446         fi
447     done
448
449     build_build_var_cache
450     set_stuff_for_environment
451     destroy_build_var_cache
452 }
453
454 function choosevariant()
455 {
456     echo "Variant choices are:"
457     local index=1
458     local v
459     for v in ${VARIANT_CHOICES[@]}
460     do
461         # The product name is the name of the directory containing
462         # the makefile we found, above.
463         echo "     $index. $v"
464         index=$(($index+1))
465     done
466
467     local default_value=eng
468     local ANSWER
469
470     export TARGET_BUILD_VARIANT=
471     while [ -z "$TARGET_BUILD_VARIANT" ]
472     do
473         echo -n "Which would you like? [$default_value] "
474         if [ -z "$1" ] ; then
475             read ANSWER
476         else
477             echo $1
478             ANSWER=$1
479         fi
480
481         if [ -z "$ANSWER" ] ; then
482             export TARGET_BUILD_VARIANT=$default_value
483         elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
484             if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
485                 export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-1))]}
486             fi
487         else
488             if check_variant $ANSWER
489             then
490                 export TARGET_BUILD_VARIANT=$ANSWER
491             else
492                 echo "** Not a valid variant: $ANSWER"
493             fi
494         fi
495         if [ -n "$1" ] ; then
496             break
497         fi
498     done
499 }
500
501 function choosecombo()
502 {
503     choosetype $1
504
505     echo
506     echo
507     chooseproduct $2
508
509     echo
510     echo
511     choosevariant $3
512
513     echo
514     build_build_var_cache
515     set_stuff_for_environment
516     printconfig
517     destroy_build_var_cache
518 }
519
520 # Clear this variable.  It will be built up again when the vendorsetup.sh
521 # files are included at the end of this file.
522 unset LUNCH_MENU_CHOICES
523 function add_lunch_combo()
524 {
525     local new_combo=$1
526     local c
527     for c in ${LUNCH_MENU_CHOICES[@]} ; do
528         if [ "$new_combo" = "$c" ] ; then
529             return
530         fi
531     done
532     LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
533 }
534
535 # add the default one here
536 add_lunch_combo aosp_arm-eng
537 add_lunch_combo aosp_arm64-eng
538 add_lunch_combo aosp_mips-eng
539 add_lunch_combo aosp_mips64-eng
540 add_lunch_combo aosp_x86-eng
541 add_lunch_combo aosp_x86_64-eng
542
543 function print_lunch_menu()
544 {
545     local uname=$(uname)
546     echo
547     echo "You're building on" $uname
548     if [ "$(uname)" = "Darwin" ] ; then
549        echo "  (ohai, koush!)"
550     fi
551     echo
552     if [ "z${CM_DEVICES_ONLY}" != "z" ]; then
553        echo "Breakfast menu... pick a combo:"
554     else
555        echo "Lunch menu... pick a combo:"
556     fi
557
558     local i=1
559     local choice
560     for choice in ${LUNCH_MENU_CHOICES[@]}
561     do
562         echo "     $i. $choice"
563         i=$(($i+1))
564     done
565
566     if [ "z${CM_DEVICES_ONLY}" != "z" ]; then
567        echo "... and don't forget the bacon!"
568     fi
569
570     echo
571 }
572
573 function brunch()
574 {
575     breakfast $*
576     if [ $? -eq 0 ]; then
577         mka bacon
578     else
579         echo "No such item in brunch menu. Try 'breakfast'"
580         return 1
581     fi
582     return $?
583 }
584
585 function breakfast()
586 {
587     target=$1
588     CM_DEVICES_ONLY="true"
589     unset LUNCH_MENU_CHOICES
590     add_lunch_combo full-eng
591     for f in `/bin/ls vendor/cm/vendorsetup.sh 2> /dev/null`
592         do
593             echo "including $f"
594             . $f
595         done
596     unset f
597
598     if [ $# -eq 0 ]; then
599         # No arguments, so let's have the full menu
600         lunch
601     else
602         echo "z$target" | grep -q "-"
603         if [ $? -eq 0 ]; then
604             # A buildtype was specified, assume a full device name
605             lunch $target
606         else
607             # This is probably just the CM model name
608             lunch cm_$target-userdebug
609         fi
610     fi
611     return $?
612 }
613
614 alias bib=breakfast
615
616 function lunch()
617 {
618     local answer
619
620     if [ "$1" ] ; then
621         answer=$1
622     else
623         print_lunch_menu
624         echo -n "Which would you like? [aosp_arm-eng] "
625         read answer
626     fi
627
628     local selection=
629
630     if [ -z "$answer" ]
631     then
632         selection=aosp_arm-eng
633     elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
634     then
635         if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
636         then
637             selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
638         fi
639     elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
640     then
641         selection=$answer
642     fi
643
644     if [ -z "$selection" ]
645     then
646         echo
647         echo "Invalid lunch combo: $answer"
648         return 1
649     fi
650
651     export TARGET_BUILD_APPS=
652
653     local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
654     check_variant $variant
655     if [ $? -ne 0 ]
656     then
657         echo
658         echo "** Invalid variant: '$variant'"
659         echo "** Must be one of ${VARIANT_CHOICES[@]}"
660         variant=
661     fi
662
663     local product=$(echo -n $selection | sed -e "s/-.*$//")
664     TARGET_PRODUCT=$product \
665     TARGET_BUILD_VARIANT=$variant \
666     build_build_var_cache
667     if [ $? -ne 0 ]
668     then
669         # if we can't find a product, try to grab it off the CM github
670         T=$(gettop)
671         pushd $T > /dev/null
672         build/tools/roomservice.py $product
673         popd > /dev/null
674         check_product $product
675     else
676         build/tools/roomservice.py $product true
677     fi
678     if [ $? -ne 0 ]
679     then
680         echo
681         echo "** Don't have a product spec for: '$product'"
682         echo "** Do you have the right repo manifest?"
683         product=
684     fi
685
686     if [ -z "$product" -o -z "$variant" ]
687     then
688         echo
689         return 1
690     fi
691
692     export TARGET_PRODUCT=$product
693     export TARGET_BUILD_VARIANT=$variant
694     export TARGET_BUILD_TYPE=release
695
696     echo
697
698     set_stuff_for_environment
699     printconfig
700     destroy_build_var_cache
701 }
702
703 # Tab completion for lunch.
704 function _lunch()
705 {
706     local cur prev opts
707     COMPREPLY=()
708     cur="${COMP_WORDS[COMP_CWORD]}"
709     prev="${COMP_WORDS[COMP_CWORD-1]}"
710
711     COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) )
712     return 0
713 }
714 complete -F _lunch lunch
715
716 # Configures the build to build unbundled apps.
717 # Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
718 function tapas()
719 {
720     local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)"
721     local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
722     local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
723     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)"
724
725     if [ $(echo $arch | wc -w) -gt 1 ]; then
726         echo "tapas: Error: Multiple build archs supplied: $arch"
727         return
728     fi
729     if [ $(echo $variant | wc -w) -gt 1 ]; then
730         echo "tapas: Error: Multiple build variants supplied: $variant"
731         return
732     fi
733     if [ $(echo $density | wc -w) -gt 1 ]; then
734         echo "tapas: Error: Multiple densities supplied: $density"
735         return
736     fi
737
738     local product=aosp_arm
739     case $arch in
740       x86)    product=aosp_x86;;
741       mips)   product=aosp_mips;;
742       armv5)  product=generic_armv5;;
743       arm64)  product=aosp_arm64;;
744       x86_64) product=aosp_x86_64;;
745       mips64)  product=aosp_mips64;;
746     esac
747     if [ -z "$variant" ]; then
748         variant=eng
749     fi
750     if [ -z "$apps" ]; then
751         apps=all
752     fi
753     if [ -z "$density" ]; then
754         density=alldpi
755     fi
756
757     export TARGET_PRODUCT=$product
758     export TARGET_BUILD_VARIANT=$variant
759     export TARGET_BUILD_DENSITY=$density
760     export TARGET_BUILD_TYPE=release
761     export TARGET_BUILD_APPS=$apps
762
763     build_build_var_cache
764     set_stuff_for_environment
765     printconfig
766     destroy_build_var_cache
767 }
768
769 function eat()
770 {
771     if [ "$OUT" ] ; then
772         MODVERSION=`sed -n -e'/ro\.cm\.version/s/.*=//p' $OUT/system/build.prop`
773         ZIPFILE=cm-$MODVERSION.zip
774         ZIPPATH=$OUT/$ZIPFILE
775         if [ ! -f $ZIPPATH ] ; then
776             echo "Nothing to eat"
777             return 1
778         fi
779         adb start-server # Prevent unexpected starting server message from adb get-state in the next line
780         if [ $(adb get-state) != device -a $(adb shell busybox test -e /sbin/recovery 2> /dev/null; echo $?) != 0 ] ; then
781             echo "No device is online. Waiting for one..."
782             echo "Please connect USB and/or enable USB debugging"
783             until [ $(adb get-state) = device -o $(adb shell busybox test -e /sbin/recovery 2> /dev/null; echo $?) = 0 ];do
784                 sleep 1
785             done
786             echo "Device Found.."
787         fi
788         # if adbd isn't root we can't write to /cache/recovery/
789         adb root
790         sleep 1
791         adb wait-for-device
792         SZ=`stat -c %s $ZIPPATH`
793         CACHESIZE=`adb shell busybox df -PB1 /cache | grep /cache | tr -s ' ' | cut -d ' ' -f 4`
794         if [ $CACHESIZE -gt $SZ ];
795         then
796             PUSHDIR=/cache/
797             DIR=cache
798         else
799             PUSHDIR=/storage/sdcard0/
800              # Optional path for sdcard0 in recovery
801              [ -z "$1" ] && DIR=sdcard/0 || DIR=$1
802         fi
803         echo "Pushing $ZIPFILE to $PUSHDIR"
804         if adb push $ZIPPATH $PUSHDIR ; then
805             cat << EOF > /tmp/command
806 --update_package=/$DIR/$ZIPFILE
807 EOF
808             if adb push /tmp/command /cache/recovery/ ; then
809                 echo "Rebooting into recovery for installation"
810                 adb reboot recovery
811             fi
812             rm /tmp/command
813         fi
814     else
815         echo "Nothing to eat"
816         return 1
817     fi
818     return $?
819 }
820
821 function gettop
822 {
823     local TOPFILE=build/core/envsetup.mk
824     if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
825         # The following circumlocution ensures we remove symlinks from TOP.
826         (cd $TOP; PWD= /bin/pwd)
827     else
828         if [ -f $TOPFILE ] ; then
829             # The following circumlocution (repeated below as well) ensures
830             # that we record the true directory name and not one that is
831             # faked up with symlink names.
832             PWD= /bin/pwd
833         else
834             local HERE=$PWD
835             T=
836             while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
837                 \cd ..
838                 T=`PWD= /bin/pwd -P`
839             done
840             \cd $HERE
841             if [ -f "$T/$TOPFILE" ]; then
842                 echo $T
843             fi
844         fi
845     fi
846 }
847
848 # Return driver for "make", if any (eg. static analyzer)
849 function getdriver()
850 {
851     local T="$1"
852     test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
853     if [ -n "$WITH_STATIC_ANALYZER" ]; then
854         echo "\
855 $T/prebuilts/misc/linux-x86/analyzer/tools/scan-build/scan-build \
856 --use-analyzer $T/prebuilts/misc/linux-x86/analyzer/bin/analyzer \
857 --status-bugs \
858 --top=$T"
859     fi
860 }
861
862 function m()
863 {
864     local T=$(gettop)
865     local DRV=$(getdriver $T)
866     if [ "$T" ]; then
867         $DRV make -C $T -f build/core/main.mk $@
868     else
869         echo "Couldn't locate the top of the tree.  Try setting TOP."
870         return 1
871     fi
872 }
873
874 function findmakefile()
875 {
876     TOPFILE=build/core/envsetup.mk
877     local HERE=$PWD
878     T=
879     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
880         T=`PWD= /bin/pwd`
881         if [ -f "$T/Android.mk" ]; then
882             echo $T/Android.mk
883             \cd $HERE
884             return
885         fi
886         \cd ..
887     done
888     \cd $HERE
889 }
890
891 function mm()
892 {
893     local T=$(gettop)
894     local DRV=$(getdriver $T)
895     # If we're sitting in the root of the build tree, just do a
896     # normal make.
897     if [ -f build/core/envsetup.mk -a -f Makefile ]; then
898         $DRV make $@
899     else
900         # Find the closest Android.mk file.
901         local M=$(findmakefile)
902         local MODULES=
903         local GET_INSTALL_PATH=
904         local ARGS=
905         # Remove the path to top as the makefilepath needs to be relative
906         local M=`echo $M|sed 's:'$T'/::'`
907         if [ ! "$T" ]; then
908             echo "Couldn't locate the top of the tree.  Try setting TOP."
909             return 1
910         elif [ ! "$M" ]; then
911             echo "Couldn't locate a makefile from the current directory."
912             return 1
913         else
914             for ARG in $@; do
915                 case $ARG in
916                   GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
917                 esac
918             done
919             if [ -n "$GET_INSTALL_PATH" ]; then
920               MODULES=
921               ARGS=GET-INSTALL-PATH
922             else
923               MODULES=all_modules
924               ARGS=$@
925             fi
926             ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS
927         fi
928     fi
929 }
930
931 function mmm()
932 {
933     local T=$(gettop)
934     local DRV=$(getdriver $T)
935     if [ "$T" ]; then
936         local MAKEFILE=
937         local MODULES=
938         local ARGS=
939         local DIR TO_CHOP
940         local GET_INSTALL_PATH=
941         local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
942         local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
943         for DIR in $DIRS ; do
944             MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
945             if [ "$MODULES" = "" ]; then
946                 MODULES=all_modules
947             fi
948             DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
949             if [ -f $DIR/Android.mk ]; then
950                 local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
951                 local TO_CHOP=`expr $TO_CHOP + 1`
952                 local START=`PWD= /bin/pwd`
953                 local MFILE=`echo $START | cut -c${TO_CHOP}-`
954                 if [ "$MFILE" = "" ] ; then
955                     MFILE=$DIR/Android.mk
956                 else
957                     MFILE=$MFILE/$DIR/Android.mk
958                 fi
959                 MAKEFILE="$MAKEFILE $MFILE"
960             else
961                 case $DIR in
962                   showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
963                   GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;
964                   *) if [ -d $DIR ]; then
965                          echo "No Android.mk in $DIR.";
966                      else
967                          echo "Couldn't locate the directory $DIR";
968                      fi
969                      return 1;;
970                 esac
971             fi
972         done
973         if [ -n "$GET_INSTALL_PATH" ]; then
974           ARGS=$GET_INSTALL_PATH
975           MODULES=
976         fi
977         ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
978     else
979         echo "Couldn't locate the top of the tree.  Try setting TOP."
980         return 1
981     fi
982 }
983
984 function mma()
985 {
986   local T=$(gettop)
987   local DRV=$(getdriver $T)
988   if [ -f build/core/envsetup.mk -a -f Makefile ]; then
989     $DRV make $@
990   else
991     if [ ! "$T" ]; then
992       echo "Couldn't locate the top of the tree.  Try setting TOP."
993       return 1
994     fi
995     local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'`
996     local MODULES_IN_PATHS=MODULES-IN-$MY_PWD
997     # Convert "/" to "-".
998     MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
999     $DRV make -C $T -f build/core/main.mk $@ $MODULES_IN_PATHS
1000   fi
1001 }
1002
1003 function mmma()
1004 {
1005   local T=$(gettop)
1006   local DRV=$(getdriver $T)
1007   if [ "$T" ]; then
1008     local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
1009     local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
1010     local MY_PWD=`PWD= /bin/pwd`
1011     if [ "$MY_PWD" = "$T" ]; then
1012       MY_PWD=
1013     else
1014       MY_PWD=`echo $MY_PWD|sed 's:'$T'/::'`
1015     fi
1016     local DIR=
1017     local MODULES_IN_PATHS=
1018     local ARGS=
1019     for DIR in $DIRS ; do
1020       if [ -d $DIR ]; then
1021         # Remove the leading ./ and trailing / if any exists.
1022         DIR=${DIR#./}
1023         DIR=${DIR%/}
1024         if [ "$MY_PWD" != "" ]; then
1025           DIR=$MY_PWD/$DIR
1026         fi
1027         MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$DIR"
1028       else
1029         case $DIR in
1030           showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
1031           *) echo "Couldn't find directory $DIR"; return 1;;
1032         esac
1033       fi
1034     done
1035     # Convert "/" to "-".
1036     MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
1037     $DRV make -C $T -f build/core/main.mk $DASH_ARGS $ARGS $MODULES_IN_PATHS
1038   else
1039     echo "Couldn't locate the top of the tree.  Try setting TOP."
1040     return 1
1041   fi
1042 }
1043
1044 function croot()
1045 {
1046     T=$(gettop)
1047     if [ "$T" ]; then
1048         \cd $(gettop)
1049     else
1050         echo "Couldn't locate the top of the tree.  Try setting TOP."
1051     fi
1052 }
1053
1054 function cproj()
1055 {
1056     TOPFILE=build/core/envsetup.mk
1057     local HERE=$PWD
1058     T=
1059     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
1060         T=$PWD
1061         if [ -f "$T/Android.mk" ]; then
1062             \cd $T
1063             return
1064         fi
1065         \cd ..
1066     done
1067     \cd $HERE
1068     echo "can't find Android.mk"
1069 }
1070
1071 # simplified version of ps; output in the form
1072 # <pid> <procname>
1073 function qpid() {
1074     local prepend=''
1075     local append=''
1076     if [ "$1" = "--exact" ]; then
1077         prepend=' '
1078         append='$'
1079         shift
1080     elif [ "$1" = "--help" -o "$1" = "-h" ]; then
1081         echo "usage: qpid [[--exact] <process name|pid>"
1082         return 255
1083     fi
1084
1085     local EXE="$1"
1086     if [ "$EXE" ] ; then
1087         qpid | \grep "$prepend$EXE$append"
1088     else
1089         adb shell ps \
1090             | tr -d '\r' \
1091             | sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/'
1092     fi
1093 }
1094
1095 function pid()
1096 {
1097     local prepend=''
1098     local append=''
1099     if [ "$1" = "--exact" ]; then
1100         prepend=' '
1101         append='$'
1102         shift
1103     fi
1104     local EXE="$1"
1105     if [ "$EXE" ] ; then
1106         local PID=`adb shell ps \
1107             | tr -d '\r' \
1108             | \grep "$prepend$EXE$append" \
1109             | sed -e 's/^[^ ]* *\([0-9]*\).*$/\1/'`
1110         echo "$PID"
1111     else
1112         echo "usage: pid [--exact] <process name>"
1113         return 255
1114     fi
1115 }
1116
1117 # coredump_setup - enable core dumps globally for any process
1118 #                  that has the core-file-size limit set correctly
1119 #
1120 # NOTE: You must call also coredump_enable for a specific process
1121 #       if its core-file-size limit is not set already.
1122 # NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
1123
1124 function coredump_setup()
1125 {
1126     echo "Getting root...";
1127     adb root;
1128     adb wait-for-device;
1129
1130     echo "Remounting root partition read-write...";
1131     adb shell mount -w -o remount -t rootfs rootfs;
1132     sleep 1;
1133     adb wait-for-device;
1134     adb shell mkdir -p /cores;
1135     adb shell mount -t tmpfs tmpfs /cores;
1136     adb shell chmod 0777 /cores;
1137
1138     echo "Granting SELinux permission to dump in /cores...";
1139     adb shell restorecon -R /cores;
1140
1141     echo "Set core pattern.";
1142     adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
1143
1144     echo "Done."
1145 }
1146
1147 # coredump_enable - enable core dumps for the specified process
1148 # $1 = PID of process (e.g., $(pid mediaserver))
1149 #
1150 # NOTE: coredump_setup must have been called as well for a core
1151 #       dump to actually be generated.
1152
1153 function coredump_enable()
1154 {
1155     local PID=$1;
1156     if [ -z "$PID" ]; then
1157         printf "Expecting a PID!\n";
1158         return;
1159     fi;
1160     echo "Setting core limit for $PID to infinite...";
1161     adb shell prlimit $PID 4 -1 -1
1162 }
1163
1164 # core - send SIGV and pull the core for process
1165 # $1 = PID of process (e.g., $(pid mediaserver))
1166 #
1167 # NOTE: coredump_setup must be called once per boot for core dumps to be
1168 #       enabled globally.
1169
1170 function core()
1171 {
1172     local PID=$1;
1173
1174     if [ -z "$PID" ]; then
1175         printf "Expecting a PID!\n";
1176         return;
1177     fi;
1178
1179     local CORENAME=core.$PID;
1180     local COREPATH=/cores/$CORENAME;
1181     local SIG=SEGV;
1182
1183     coredump_enable $1;
1184
1185     local done=0;
1186     while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
1187         printf "\tSending SIG%s to %d...\n" $SIG $PID;
1188         adb shell kill -$SIG $PID;
1189         sleep 1;
1190     done;
1191
1192     adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
1193     echo "Done: core is under $COREPATH on device.";
1194 }
1195
1196 # systemstack - dump the current stack trace of all threads in the system process
1197 # to the usual ANR traces file
1198 function systemstack()
1199 {
1200     stacks system_server
1201 }
1202
1203 function stacks()
1204 {
1205     if [[ $1 =~ ^[0-9]+$ ]] ; then
1206         local PID="$1"
1207     elif [ "$1" ] ; then
1208         local PIDLIST="$(pid $1)"
1209         if [[ $PIDLIST =~ ^[0-9]+$ ]] ; then
1210             local PID="$PIDLIST"
1211         elif [ "$PIDLIST" ] ; then
1212             echo "more than one process: $1"
1213         else
1214             echo "no such process: $1"
1215         fi
1216     else
1217         echo "usage: stacks [pid|process name]"
1218     fi
1219
1220     if [ "$PID" ] ; then
1221         # Determine whether the process is native
1222         if adb shell ls -l /proc/$PID/exe | grep -q /system/bin/app_process ; then
1223             # Dump stacks of Dalvik process
1224             local TRACES=/data/anr/traces.txt
1225             local ORIG=/data/anr/traces.orig
1226             local TMP=/data/anr/traces.tmp
1227
1228             # Keep original traces to avoid clobbering
1229             adb shell mv $TRACES $ORIG
1230
1231             # Make sure we have a usable file
1232             adb shell touch $TRACES
1233             adb shell chmod 666 $TRACES
1234
1235             # Dump stacks and wait for dump to finish
1236             adb shell kill -3 $PID
1237             adb shell notify $TRACES >/dev/null
1238
1239             # Restore original stacks, and show current output
1240             adb shell mv $TRACES $TMP
1241             adb shell mv $ORIG $TRACES
1242             adb shell cat $TMP
1243         else
1244             # Dump stacks of native process
1245             local USE64BIT="$(is64bit $PID)"
1246             adb shell debuggerd$USE64BIT -b $PID
1247         fi
1248     fi
1249 }
1250
1251 # Read the ELF header from /proc/$PID/exe to determine if the process is
1252 # 64-bit.
1253 function is64bit()
1254 {
1255     local PID="$1"
1256     if [ "$PID" ] ; then
1257         if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -ps)" -eq "02" ]] ; then
1258             echo "64"
1259         else
1260             echo ""
1261         fi
1262     else
1263         echo ""
1264     fi
1265 }
1266
1267 case `uname -s` in
1268     Darwin)
1269         function sgrep()
1270         {
1271             find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cc|cpp|S|java|xml|sh|mk|aidl|vts)' \
1272                 -exec grep --color -n "$@" {} +
1273         }
1274
1275         ;;
1276     *)
1277         function sgrep()
1278         {
1279             find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cc\|cpp\|S\|java\|xml\|sh\|mk\|aidl\|vts\)' \
1280                 -exec grep --color -n "$@" {} +
1281         }
1282         ;;
1283 esac
1284
1285 function gettargetarch
1286 {
1287     get_build_var TARGET_ARCH
1288 }
1289
1290 function ggrep()
1291 {
1292     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" \
1293         -exec grep --color -n "$@" {} +
1294 }
1295
1296 function jgrep()
1297 {
1298     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" \
1299         -exec grep --color -n "$@" {} +
1300 }
1301
1302 function cgrep()
1303 {
1304     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' \) \
1305         -exec grep --color -n "$@" {} +
1306 }
1307
1308 function resgrep()
1309 {
1310     for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do
1311         find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} +
1312     done
1313 }
1314
1315 function mangrep()
1316 {
1317     find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' \
1318         -exec grep --color -n "$@" {} +
1319 }
1320
1321 function sepgrep()
1322 {
1323     find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \
1324         -exec grep --color -n -r --exclude-dir=\.git "$@" {} +
1325 }
1326
1327 function rcgrep()
1328 {
1329     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rc*" \
1330         -exec grep --color -n "$@" {} +
1331 }
1332
1333 case `uname -s` in
1334     Darwin)
1335         function mgrep()
1336         {
1337             find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' \
1338                 -exec grep --color -n "$@" {} +
1339         }
1340
1341         function treegrep()
1342         {
1343             find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|S|java|xml)' \
1344                 -exec grep --color -n -i "$@" {} +
1345         }
1346
1347         ;;
1348     *)
1349         function mgrep()
1350         {
1351             find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f \
1352                 -exec grep --color -n "$@" {} +
1353         }
1354
1355         function treegrep()
1356         {
1357             find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f \
1358                 -exec grep --color -n -i "$@" {} +
1359         }
1360
1361         ;;
1362 esac
1363
1364 function getprebuilt
1365 {
1366     get_abs_build_var ANDROID_PREBUILTS
1367 }
1368
1369 function tracedmdump()
1370 {
1371     T=$(gettop)
1372     if [ ! "$T" ]; then
1373         echo "Couldn't locate the top of the tree.  Try setting TOP."
1374         return
1375     fi
1376     local prebuiltdir=$(getprebuilt)
1377     local arch=$(gettargetarch)
1378     local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu
1379
1380     local TRACE=$1
1381     if [ ! "$TRACE" ] ; then
1382         echo "usage:  tracedmdump  tracename"
1383         return
1384     fi
1385
1386     if [ ! -r "$KERNEL" ] ; then
1387         echo "Error: cannot find kernel: '$KERNEL'"
1388         return
1389     fi
1390
1391     local BASETRACE=$(basename $TRACE)
1392     if [ "$BASETRACE" = "$TRACE" ] ; then
1393         TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
1394     fi
1395
1396     echo "post-processing traces..."
1397     rm -f $TRACE/qtrace.dexlist
1398     post_trace $TRACE
1399     if [ $? -ne 0 ]; then
1400         echo "***"
1401         echo "*** Error: malformed trace.  Did you remember to exit the emulator?"
1402         echo "***"
1403         return
1404     fi
1405     echo "generating dexlist output..."
1406     /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
1407     echo "generating dmtrace data..."
1408     q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
1409     echo "generating html file..."
1410     dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
1411     echo "done, see $TRACE/dmtrace.html for details"
1412     echo "or run:"
1413     echo "    traceview $TRACE/dmtrace"
1414 }
1415
1416 # communicate with a running device or emulator, set up necessary state,
1417 # and run the hat command.
1418 function runhat()
1419 {
1420     # process standard adb options
1421     local adbTarget=""
1422     if [ "$1" = "-d" -o "$1" = "-e" ]; then
1423         adbTarget=$1
1424         shift 1
1425     elif [ "$1" = "-s" ]; then
1426         adbTarget="$1 $2"
1427         shift 2
1428     fi
1429     local adbOptions=${adbTarget}
1430     #echo adbOptions = ${adbOptions}
1431
1432     # runhat options
1433     local targetPid=$1
1434
1435     if [ "$targetPid" = "" ]; then
1436         echo "Usage: runhat [ -d | -e | -s serial ] target-pid"
1437         return
1438     fi
1439
1440     # confirm hat is available
1441     if [ -z $(which hat) ]; then
1442         echo "hat is not available in this configuration."
1443         return
1444     fi
1445
1446     # issue "am" command to cause the hprof dump
1447     local devFile=/data/local/tmp/hprof-$targetPid
1448     echo "Poking $targetPid and waiting for data..."
1449     echo "Storing data at $devFile"
1450     adb ${adbOptions} shell am dumpheap $targetPid $devFile
1451     echo "Press enter when logcat shows \"hprof: heap dump completed\""
1452     echo -n "> "
1453     read
1454
1455     local localFile=/tmp/$$-hprof
1456
1457     echo "Retrieving file $devFile..."
1458     adb ${adbOptions} pull $devFile $localFile
1459
1460     adb ${adbOptions} shell rm $devFile
1461
1462     echo "Running hat on $localFile"
1463     echo "View the output by pointing your browser at http://localhost:7000/"
1464     echo ""
1465     hat -JXmx512m $localFile
1466 }
1467
1468 function getbugreports()
1469 {
1470     local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
1471
1472     if [ ! "$reports" ]; then
1473         echo "Could not locate any bugreports."
1474         return
1475     fi
1476
1477     local report
1478     for report in ${reports[@]}
1479     do
1480         echo "/sdcard/bugreports/${report}"
1481         adb pull /sdcard/bugreports/${report} ${report}
1482         gunzip ${report}
1483     done
1484 }
1485
1486 function getsdcardpath()
1487 {
1488     adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
1489 }
1490
1491 function getscreenshotpath()
1492 {
1493     echo "$(getsdcardpath)/Pictures/Screenshots"
1494 }
1495
1496 function getlastscreenshot()
1497 {
1498     local screenshot_path=$(getscreenshotpath)
1499     local screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1`
1500     if [ "$screenshot" = "" ]; then
1501         echo "No screenshots found."
1502         return
1503     fi
1504     echo "${screenshot}"
1505     adb ${adbOptions} pull ${screenshot_path}/${screenshot}
1506 }
1507
1508 function startviewserver()
1509 {
1510     local port=4939
1511     if [ $# -gt 0 ]; then
1512             port=$1
1513     fi
1514     adb shell service call window 1 i32 $port
1515 }
1516
1517 function stopviewserver()
1518 {
1519     adb shell service call window 2
1520 }
1521
1522 function isviewserverstarted()
1523 {
1524     adb shell service call window 3
1525 }
1526
1527 function key_home()
1528 {
1529     adb shell input keyevent 3
1530 }
1531
1532 function key_back()
1533 {
1534     adb shell input keyevent 4
1535 }
1536
1537 function key_menu()
1538 {
1539     adb shell input keyevent 82
1540 }
1541
1542 function smoketest()
1543 {
1544     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
1545         echo "Couldn't locate output files.  Try running 'lunch' first." >&2
1546         return
1547     fi
1548     T=$(gettop)
1549     if [ ! "$T" ]; then
1550         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
1551         return
1552     fi
1553
1554     (\cd "$T" && mmm tests/SmokeTest) &&
1555       adb uninstall com.android.smoketest > /dev/null &&
1556       adb uninstall com.android.smoketest.tests > /dev/null &&
1557       adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
1558       adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk &&
1559       adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
1560 }
1561
1562 # simple shortcut to the runtest command
1563 function runtest()
1564 {
1565     T=$(gettop)
1566     if [ ! "$T" ]; then
1567         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
1568         return
1569     fi
1570     ("$T"/development/testrunner/runtest.py $@)
1571 }
1572
1573 function godir () {
1574     if [[ -z "$1" ]]; then
1575         echo "Usage: godir <regex>"
1576         return
1577     fi
1578     T=$(gettop)
1579     if [ ! "$OUT_DIR" = "" ]; then
1580         mkdir -p $OUT_DIR
1581         FILELIST=$OUT_DIR/filelist
1582     else
1583         FILELIST=$T/filelist
1584     fi
1585     if [[ ! -f $FILELIST ]]; then
1586         echo -n "Creating index..."
1587         (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST)
1588         echo " Done"
1589         echo ""
1590     fi
1591     local lines
1592     lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq))
1593     if [[ ${#lines[@]} = 0 ]]; then
1594         echo "Not found"
1595         return
1596     fi
1597     local pathname
1598     local choice
1599     if [[ ${#lines[@]} > 1 ]]; then
1600         while [[ -z "$pathname" ]]; do
1601             local index=1
1602             local line
1603             for line in ${lines[@]}; do
1604                 printf "%6s %s\n" "[$index]" $line
1605                 index=$(($index + 1))
1606             done
1607             echo
1608             echo -n "Select one: "
1609             unset choice
1610             read choice
1611             if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
1612                 echo "Invalid choice"
1613                 continue
1614             fi
1615             pathname=${lines[$(($choice-1))]}
1616         done
1617     else
1618         pathname=${lines[0]}
1619     fi
1620     \cd $T/$pathname
1621 }
1622
1623 function cmremote()
1624 {
1625     git remote rm cmremote 2> /dev/null
1626     if [ ! -d .git ]
1627     then
1628         echo .git directory not found. Please run this from the root directory of the Android repository you wish to set up.
1629     fi
1630     GERRIT_REMOTE=$(cat .git/config  | grep git://github.com | awk '{ print $NF }' | sed s#git://github.com/##g)
1631     if [ -z "$GERRIT_REMOTE" ]
1632     then
1633         GERRIT_REMOTE=$(cat .git/config  | grep http://github.com | awk '{ print $NF }' | sed s#http://github.com/##g)
1634         if [ -z "$GERRIT_REMOTE" ]
1635         then
1636           echo Unable to set up the git remote, are you in the root of the repo?
1637           return 0
1638         fi
1639     fi
1640     CMUSER=`git config --get review.review.cyanogenmod.com.username`
1641     if [ -z "$CMUSER" ]
1642     then
1643         git remote add cmremote ssh://review.cyanogenmod.com:29418/$GERRIT_REMOTE
1644     else
1645         git remote add cmremote ssh://$CMUSER@review.cyanogenmod.com:29418/$GERRIT_REMOTE
1646     fi
1647     echo You can now push to "cmremote".
1648 }
1649 export -f cmremote
1650
1651 function aospremote()
1652 {
1653     git remote rm aosp 2> /dev/null
1654     if [ ! -d .git ]
1655     then
1656         echo .git directory not found. Please run this from the root directory of the Android repository you wish to set up.
1657     fi
1658     PROJECT=`pwd | sed s#$ANDROID_BUILD_TOP/##g`
1659     if (echo $PROJECT | grep -qv "^device")
1660     then
1661         PFX="platform/"
1662     fi
1663     git remote add aosp https://android.googlesource.com/$PFX$PROJECT
1664     echo "Remote 'aosp' created"
1665 }
1666 export -f aospremote
1667
1668 function installboot()
1669 {
1670     if [ ! -e "$OUT/recovery/root/etc/recovery.fstab" ];
1671     then
1672         echo "No recovery.fstab found. Build recovery first."
1673         return 1
1674     fi
1675     if [ ! -e "$OUT/boot.img" ];
1676     then
1677         echo "No boot.img found. Run make bootimage first."
1678         return 1
1679     fi
1680     PARTITION=`grep "^\/boot" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}`
1681     if [ -z "$PARTITION" ];
1682     then
1683         echo "Unable to determine boot partition."
1684         return 1
1685     fi
1686     adb start-server
1687     adb root
1688     sleep 1
1689     adb wait-for-device
1690     adb remount
1691     adb wait-for-device
1692     if (adb shell cat /system/build.prop | grep -q "ro.cm.device=$CM_BUILD");
1693     then
1694         adb push $OUT/boot.img /cache/
1695         for i in $OUT/system/lib/modules/*;
1696         do
1697             adb push $i /system/lib/modules/
1698         done
1699         adb shell dd if=/cache/boot.img of=$PARTITION
1700         adb shell chmod 644 /system/lib/modules/*
1701         echo "Installation complete."
1702     else
1703         echo "The connected device does not appear to be $CM_BUILD, run away!"
1704     fi
1705 }
1706
1707 function installrecovery()
1708 {
1709     if [ ! -e "$OUT/recovery/root/etc/recovery.fstab" ];
1710     then
1711         echo "No recovery.fstab found. Build recovery first."
1712         return 1
1713     fi
1714     if [ ! -e "$OUT/recovery.img" ];
1715     then
1716         echo "No recovery.img found. Run make recoveryimage first."
1717         return 1
1718     fi
1719     PARTITION=`grep "^\/recovery" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}`
1720     if [ -z "$PARTITION" ];
1721     then
1722         echo "Unable to determine recovery partition."
1723         return 1
1724     fi
1725     adb start-server
1726     adb root
1727     sleep 1
1728     adb wait-for-device
1729     adb remount
1730     adb wait-for-device
1731     if (adb shell cat /system/build.prop | grep -q "ro.cm.device=$CM_BUILD");
1732     then
1733         adb push $OUT/recovery.img /cache/
1734         adb shell dd if=/cache/recovery.img of=$PARTITION
1735         echo "Installation complete."
1736     else
1737         echo "The connected device does not appear to be $CM_BUILD, run away!"
1738     fi
1739 }
1740
1741 function makerecipe() {
1742   if [ -z "$1" ]
1743   then
1744     echo "No branch name provided."
1745     return 1
1746   fi
1747   cd android
1748   sed -i s/'default revision=.*'/'default revision="refs\/heads\/'$1'"'/ default.xml
1749   git commit -a -m "$1"
1750   cd ..
1751
1752   repo forall -c '
1753
1754   if [ "$REPO_REMOTE" == "github" ]
1755   then
1756     pwd
1757     cmremote
1758     git push cmremote HEAD:refs/heads/'$1'
1759   fi
1760   '
1761 }
1762
1763 function cmgerrit() {
1764     if [ $# -eq 0 ]; then
1765         $FUNCNAME help
1766         return 1
1767     fi
1768     local user=`git config --get review.review.cyanogenmod.com.username`
1769     local review=`git config --get remote.github.review`
1770     local project=`git config --get remote.github.projectname`
1771     local command=$1
1772     shift
1773     case $command in
1774         help)
1775             if [ $# -eq 0 ]; then
1776                 cat <<EOF
1777 Usage:
1778     $FUNCNAME COMMAND [OPTIONS] [CHANGE-ID[/PATCH-SET]][{@|^|~|:}ARG] [-- ARGS]
1779
1780 Commands:
1781     fetch   Just fetch the change as FETCH_HEAD
1782     help    Show this help, or for a specific command
1783     pull    Pull a change into current branch
1784     push    Push HEAD or a local branch to Gerrit for a specific branch
1785
1786 Any other Git commands that support refname would work as:
1787     git fetch URL CHANGE && git COMMAND OPTIONS FETCH_HEAD{@|^|~|:}ARG -- ARGS
1788
1789 See '$FUNCNAME help COMMAND' for more information on a specific command.
1790
1791 Example:
1792     $FUNCNAME checkout -b topic 1234/5
1793 works as:
1794     git fetch http://DOMAIN/p/PROJECT refs/changes/34/1234/5 \\
1795       && git checkout -b topic FETCH_HEAD
1796 will checkout a new branch 'topic' base on patch-set 5 of change 1234.
1797 Patch-set 1 will be fetched if omitted.
1798 EOF
1799                 return
1800             fi
1801             case $1 in
1802                 __cmg_*) echo "For internal use only." ;;
1803                 changes|for)
1804                     if [ "$FUNCNAME" = "cmgerrit" ]; then
1805                         echo "'$FUNCNAME $1' is deprecated."
1806                     fi
1807                     ;;
1808                 help) $FUNCNAME help ;;
1809                 fetch|pull) cat <<EOF
1810 usage: $FUNCNAME $1 [OPTIONS] CHANGE-ID[/PATCH-SET]
1811
1812 works as:
1813     git $1 OPTIONS http://DOMAIN/p/PROJECT \\
1814       refs/changes/HASH/CHANGE-ID/{PATCH-SET|1}
1815
1816 Example:
1817     $FUNCNAME $1 1234
1818 will $1 patch-set 1 of change 1234
1819 EOF
1820                     ;;
1821                 push) cat <<EOF
1822 usage: $FUNCNAME push [OPTIONS] [LOCAL_BRANCH:]REMOTE_BRANCH
1823
1824 works as:
1825     git push OPTIONS ssh://USER@DOMAIN:29418/PROJECT \\
1826       {LOCAL_BRANCH|HEAD}:refs/for/REMOTE_BRANCH
1827
1828 Example:
1829     $FUNCNAME push fix6789:gingerbread
1830 will push local branch 'fix6789' to Gerrit for branch 'gingerbread'.
1831 HEAD will be pushed from local if omitted.
1832 EOF
1833                     ;;
1834                 *)
1835                     $FUNCNAME __cmg_err_not_supported $1 && return
1836                     cat <<EOF
1837 usage: $FUNCNAME $1 [OPTIONS] CHANGE-ID[/PATCH-SET][{@|^|~|:}ARG] [-- ARGS]
1838
1839 works as:
1840     git fetch http://DOMAIN/p/PROJECT \\
1841       refs/changes/HASH/CHANGE-ID/{PATCH-SET|1} \\
1842       && git $1 OPTIONS FETCH_HEAD{@|^|~|:}ARG -- ARGS
1843 EOF
1844                     ;;
1845             esac
1846             ;;
1847         __cmg_get_ref)
1848             $FUNCNAME __cmg_err_no_arg $command $# && return 1
1849             local change_id patchset_id hash
1850             case $1 in
1851                 */*)
1852                     change_id=${1%%/*}
1853                     patchset_id=${1#*/}
1854                     ;;
1855                 *)
1856                     change_id=$1
1857                     patchset_id=1
1858                     ;;
1859             esac
1860             hash=$(($change_id % 100))
1861             case $hash in
1862                 [0-9]) hash="0$hash" ;;
1863             esac
1864             echo "refs/changes/$hash/$change_id/$patchset_id"
1865             ;;
1866         fetch|pull)
1867             $FUNCNAME __cmg_err_no_arg $command $# help && return 1
1868             $FUNCNAME __cmg_err_not_repo && return 1
1869             local change=$1
1870             shift
1871             git $command $@ http://$review/p/$project \
1872                 $($FUNCNAME __cmg_get_ref $change) || return 1
1873             ;;
1874         push)
1875             $FUNCNAME __cmg_err_no_arg $command $# help && return 1
1876             $FUNCNAME __cmg_err_not_repo && return 1
1877             if [ -z "$user" ]; then
1878                 echo >&2 "Gerrit username not found."
1879                 return 1
1880             fi
1881             local local_branch remote_branch
1882             case $1 in
1883                 *:*)
1884                     local_branch=${1%:*}
1885                     remote_branch=${1##*:}
1886                     ;;
1887                 *)
1888                     local_branch=HEAD
1889                     remote_branch=$1
1890                     ;;
1891             esac
1892             shift
1893             git push $@ ssh://$user@$review:29418/$project \
1894                 $local_branch:refs/for/$remote_branch || return 1
1895             ;;
1896         changes|for)
1897             if [ "$FUNCNAME" = "cmgerrit" ]; then
1898                 echo >&2 "'$FUNCNAME $command' is deprecated."
1899             fi
1900             ;;
1901         __cmg_err_no_arg)
1902             if [ $# -lt 2 ]; then
1903                 echo >&2 "'$FUNCNAME $command' missing argument."
1904             elif [ $2 -eq 0 ]; then
1905                 if [ -n "$3" ]; then
1906                     $FUNCNAME help $1
1907                 else
1908                     echo >&2 "'$FUNCNAME $1' missing argument."
1909                 fi
1910             else
1911                 return 1
1912             fi
1913             ;;
1914         __cmg_err_not_repo)
1915             if [ -z "$review" -o -z "$project" ]; then
1916                 echo >&2 "Not currently in any reviewable repository."
1917             else
1918                 return 1
1919             fi
1920             ;;
1921         __cmg_err_not_supported)
1922             $FUNCNAME __cmg_err_no_arg $command $# && return
1923             case $1 in
1924                 #TODO: filter more git commands that don't use refname
1925                 init|add|rm|mv|status|clone|remote|bisect|config|stash)
1926                     echo >&2 "'$FUNCNAME $1' is not supported."
1927                     ;;
1928                 *) return 1 ;;
1929             esac
1930             ;;
1931     #TODO: other special cases?
1932         *)
1933             $FUNCNAME __cmg_err_not_supported $command && return 1
1934             $FUNCNAME __cmg_err_no_arg $command $# help && return 1
1935             $FUNCNAME __cmg_err_not_repo && return 1
1936             local args="$@"
1937             local change pre_args refs_arg post_args
1938             case "$args" in
1939                 *--\ *)
1940                     pre_args=${args%%-- *}
1941                     post_args="-- ${args#*-- }"
1942                     ;;
1943                 *) pre_args="$args" ;;
1944             esac
1945             args=($pre_args)
1946             pre_args=
1947             if [ ${#args[@]} -gt 0 ]; then
1948                 change=${args[${#args[@]}-1]}
1949             fi
1950             if [ ${#args[@]} -gt 1 ]; then
1951                 pre_args=${args[0]}
1952                 for ((i=1; i<${#args[@]}-1; i++)); do
1953                     pre_args="$pre_args ${args[$i]}"
1954                 done
1955             fi
1956             while ((1)); do
1957                 case $change in
1958                     ""|--)
1959                         $FUNCNAME help $command
1960                         return 1
1961                         ;;
1962                     *@*)
1963                         if [ -z "$refs_arg" ]; then
1964                             refs_arg="@${change#*@}"
1965                             change=${change%%@*}
1966                         fi
1967                         ;;
1968                     *~*)
1969                         if [ -z "$refs_arg" ]; then
1970                             refs_arg="~${change#*~}"
1971                             change=${change%%~*}
1972                         fi
1973                         ;;
1974                     *^*)
1975                         if [ -z "$refs_arg" ]; then
1976                             refs_arg="^${change#*^}"
1977                             change=${change%%^*}
1978                         fi
1979                         ;;
1980                     *:*)
1981                         if [ -z "$refs_arg" ]; then
1982                             refs_arg=":${change#*:}"
1983                             change=${change%%:*}
1984                         fi
1985                         ;;
1986                     *) break ;;
1987                 esac
1988             done
1989             $FUNCNAME fetch $change \
1990                 && git $command $pre_args FETCH_HEAD$refs_arg $post_args \
1991                 || return 1
1992             ;;
1993     esac
1994 }
1995
1996 function cmrebase() {
1997     local repo=$1
1998     local refs=$2
1999     local pwd="$(pwd)"
2000     local dir="$(gettop)/$repo"
2001
2002     if [ -z $repo ] || [ -z $refs ]; then
2003         echo "CyanogenMod Gerrit Rebase Usage: "
2004         echo "      cmrebase <path to project> <patch IDs on Gerrit>"
2005         echo "      The patch IDs appear on the Gerrit commands that are offered."
2006         echo "      They consist on a series of numbers and slashes, after the text"
2007         echo "      refs/changes. For example, the ID in the following command is 26/8126/2"
2008         echo ""
2009         echo "      git[...]ges_apps_Camera refs/changes/26/8126/2 && git cherry-pick FETCH_HEAD"
2010         echo ""
2011         return
2012     fi
2013
2014     if [ ! -d $dir ]; then
2015         echo "Directory $dir doesn't exist in tree."
2016         return
2017     fi
2018     cd $dir
2019     repo=$(cat .git/config  | grep git://github.com | awk '{ print $NF }' | sed s#git://github.com/##g)
2020     echo "Starting branch..."
2021     repo start tmprebase .
2022     echo "Bringing it up to date..."
2023     repo sync .
2024     echo "Fetching change..."
2025     git fetch "http://review.cyanogenmod.com/p/$repo" "refs/changes/$refs" && git cherry-pick FETCH_HEAD
2026     if [ "$?" != "0" ]; then
2027         echo "Error cherry-picking. Not uploading!"
2028         return
2029     fi
2030     echo "Uploading..."
2031     repo upload .
2032     echo "Cleaning up..."
2033     repo abandon tmprebase .
2034     cd $pwd
2035 }
2036
2037 function mka() {
2038     case `uname -s` in
2039         Darwin)
2040             make -j `sysctl hw.ncpu|cut -d" " -f2` "$@"
2041             ;;
2042         *)
2043             schedtool -B -n 1 -e ionice -n 1 make -j `cat /proc/cpuinfo | grep "^processor" | wc -l` "$@"
2044             ;;
2045     esac
2046 }
2047
2048 function reposync() {
2049     case `uname -s` in
2050         Darwin)
2051             repo sync -j 4 "$@"
2052             ;;
2053         *)
2054             schedtool -B -n 1 -e ionice -n 1 `which repo` sync -j 4 "$@"
2055             ;;
2056     esac
2057 }
2058
2059 function repodiff() {
2060     if [ -z "$*" ]; then
2061         echo "Usage: repodiff <ref-from> [[ref-to] [--numstat]]"
2062         return
2063     fi
2064     diffopts=$* repo forall -c \
2065       'echo "$REPO_PATH ($REPO_REMOTE)"; git diff ${diffopts} 2>/dev/null ;'
2066 }
2067
2068 # Credit for color strip sed: http://goo.gl/BoIcm
2069 function dopush()
2070 {
2071     local func=$1
2072     shift
2073
2074     adb start-server # Prevent unexpected starting server message from adb get-state in the next line
2075     if [ $(adb get-state) != device -a $(adb shell busybox test -e /sbin/recovery 2> /dev/null; echo $?) != 0 ] ; then
2076         echo "No device is online. Waiting for one..."
2077         echo "Please connect USB and/or enable USB debugging"
2078         until [ $(adb get-state) = device -o $(adb shell busybox test -e /sbin/recovery 2> /dev/null; echo $?) = 0 ];do
2079             sleep 1
2080         done
2081         echo "Device Found."
2082     fi
2083
2084     adb root &> /dev/null
2085     sleep 0.3
2086     adb wait-for-device &> /dev/null
2087     sleep 0.3
2088     adb remount &> /dev/null
2089
2090     $func $* | tee $OUT/.log
2091
2092     # Install: <file>
2093     LOC=$(cat $OUT/.log | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' | grep 'Install' | cut -d ':' -f 2)
2094
2095     # Copy: <file>
2096     LOC=$LOC $(cat $OUT/.log | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' | grep 'Copy' | cut -d ':' -f 2)
2097
2098     for FILE in $LOC; do
2099         # Get target file name (i.e. system/bin/adb)
2100         TARGET=$(echo $FILE | sed "s#$OUT/##")
2101
2102         # Don't send files that are not in /system.
2103         if ! echo $TARGET | egrep '^system\/' > /dev/null ; then
2104             continue
2105         else
2106             case $TARGET in
2107             system/app/SystemUI.apk|system/framework/*)
2108                 stop_n_start=true
2109             ;;
2110             *)
2111                 stop_n_start=false
2112             ;;
2113             esac
2114             if $stop_n_start ; then adb shell stop ; fi
2115             echo "Pushing: $TARGET"
2116             adb push $FILE $TARGET
2117             if $stop_n_start ; then adb shell start ; fi
2118         fi
2119     done
2120     rm -f $OUT/.log
2121     return 0
2122 }
2123
2124 alias mmp='dopush mm'
2125 alias mmmp='dopush mmm'
2126 alias mkap='dopush mka'
2127 alias cmkap='dopush cmka'
2128
2129 # Force JAVA_HOME to point to java 1.7/1.8 if it isn't already set.
2130 function set_java_home() {
2131     # Clear the existing JAVA_HOME value if we set it ourselves, so that
2132     # we can reset it later, depending on the version of java the build
2133     # system needs.
2134     #
2135     # If we don't do this, the JAVA_HOME value set by the first call to
2136     # build/envsetup.sh will persist forever.
2137     if [ -n "$ANDROID_SET_JAVA_HOME" ]; then
2138       export JAVA_HOME=""
2139     fi
2140
2141     if [ ! "$JAVA_HOME" ]; then
2142       if [ -n "$LEGACY_USE_JAVA7" ]; then
2143         echo Warning: Support for JDK 7 will be dropped. Switch to JDK 8.
2144         case `uname -s` in
2145             Darwin)
2146                 export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
2147                 ;;
2148             *)
2149                 export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
2150                 ;;
2151         esac
2152       else
2153         case `uname -s` in
2154             Darwin)
2155                 export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
2156                 ;;
2157             *)
2158                 export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
2159                 ;;
2160         esac
2161       fi
2162
2163       # Keep track of the fact that we set JAVA_HOME ourselves, so that
2164       # we can change it on the next envsetup.sh, if required.
2165       export ANDROID_SET_JAVA_HOME=true
2166     fi
2167 }
2168
2169 # Print colored exit condition
2170 function pez {
2171     "$@"
2172     local retval=$?
2173     if [ $retval -ne 0 ]
2174     then
2175         echo $'\E'"[0;31mFAILURE\e[00m"
2176     else
2177         echo $'\E'"[0;32mSUCCESS\e[00m"
2178     fi
2179     return $retval
2180 }
2181
2182 function get_make_command()
2183 {
2184   echo command make
2185 }
2186
2187 function make()
2188 {
2189     local start_time=$(date +"%s")
2190     $(get_make_command) "$@"
2191     local ret=$?
2192     local end_time=$(date +"%s")
2193     local tdiff=$(($end_time-$start_time))
2194     local hours=$(($tdiff / 3600 ))
2195     local mins=$((($tdiff % 3600) / 60))
2196     local secs=$(($tdiff % 60))
2197     local ncolors=$(tput colors 2>/dev/null)
2198     if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
2199         color_failed=$'\E'"[0;31m"
2200         color_success=$'\E'"[0;32m"
2201         color_reset=$'\E'"[00m"
2202     else
2203         color_failed=""
2204         color_success=""
2205         color_reset=""
2206     fi
2207     echo
2208     if [ $ret -eq 0 ] ; then
2209         echo -n "${color_success}#### make completed successfully "
2210     else
2211         echo -n "${color_failed}#### make failed to build some targets "
2212     fi
2213     if [ $hours -gt 0 ] ; then
2214         printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
2215     elif [ $mins -gt 0 ] ; then
2216         printf "(%02g:%02g (mm:ss))" $mins $secs
2217     elif [ $secs -gt 0 ] ; then
2218         printf "(%s seconds)" $secs
2219     fi
2220     echo " ####${color_reset}"
2221     echo
2222     return $ret
2223 }
2224
2225 function provision()
2226 {
2227     if [ ! "$ANDROID_PRODUCT_OUT" ]; then
2228         echo "Couldn't locate output files.  Try running 'lunch' first." >&2
2229         return 1
2230     fi
2231     if [ ! -e "$ANDROID_PRODUCT_OUT/provision-device" ]; then
2232         echo "There is no provisioning script for the device." >&2
2233         return 1
2234     fi
2235
2236     # Check if user really wants to do this.
2237     if [ "$1" = "--no-confirmation" ]; then
2238         shift 1
2239     else
2240         echo "This action will reflash your device."
2241         echo ""
2242         echo "ALL DATA ON THE DEVICE WILL BE IRREVOCABLY ERASED."
2243         echo ""
2244         echo -n "Are you sure you want to do this (yes/no)? "
2245         read
2246         if [[ "${REPLY}" != "yes" ]] ; then
2247             echo "Not taking any action. Exiting." >&2
2248             return 1
2249         fi
2250     fi
2251     "$ANDROID_PRODUCT_OUT/provision-device" "$@"
2252 }
2253
2254 if [ "x$SHELL" != "x/bin/bash" ]; then
2255     case `ps -o command -p $$` in
2256         *bash*)
2257             ;;
2258         *)
2259             echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
2260             ;;
2261     esac
2262 fi
2263
2264 # Execute the contents of any vendorsetup.sh files we can find.
2265 for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
2266          `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
2267          `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
2268 do
2269     echo "including $f"
2270     . $f
2271 done
2272 unset f
2273
2274 addcompletions