OSDN Git Service

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