OSDN Git Service

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