1e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Copyright (c) 2012 Google Inc.
2e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# All rights reserved.
3e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
4e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Redistribution and use in source and binary forms, with or without
5e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# modification, are permitted provided that the following conditions are
6e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# met:
7e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
8e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#     * Redistributions of source code must retain the above copyright
9e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# notice, this list of conditions and the following disclaimer.
10e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#     * Redistributions in binary form must reproduce the above
11e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# copyright notice, this list of conditions and the following disclaimer
12e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# in the documentation and/or other materials provided with the
13e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# distribution.
14e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#     * Neither the name of Google Inc. nor the names of its
15e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# contributors may be used to endorse or promote products derived from
16e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# this software without specific prior written permission.
17e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
18e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
30e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Collection of common shell functions for 'run-checks.sh' et 'test-shell.sh'
31e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
32e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# All internal variables and functions use an underscore as a prefix
33e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# (e.g. _VERBOSE, _ALL_CLEANUPS, etc..).
34e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
35e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Sanitize the environment
36e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgexport LANG=C
37e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgexport LC_ALL=C
38e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
39e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgif [ "$BASH_VERSION" ]; then
40e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  set -o posix
41e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgfi
42e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
43e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Utility functions
44e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
45e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ALL_CLEANUPS=
46e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
47e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Register a function to be called when the script exits, even in case of
48e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Ctrl-C, logout, etc.
49e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: function name.
50e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgatexit () {
51e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ -z "$_ALL_CLEANUPS" ]; then
52e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    _ALL_CLEANUPS=$1
53e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    # Ensure a clean exit when the script is:
54e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    #  - Exiting normally (EXIT)
55e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    #  - Interrupted by Ctrl-C (INT)
56e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    #  - Interrupted by log out (HUP)
57e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    #  - Being asked to quit nicely (TERM)
58e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    #  - Being asked to quit and dump core (QUIT)
59e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    trap "_exit_cleanups \$?" EXIT INT HUP QUIT TERM
60e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  else
61e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    _ALL_CLEANUPS="$_ALL_CLEANUPS $1"
62e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
63e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
64e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
65e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Called on exit if at least one function was registered with atexit
66e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: final exit status code
67e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_exit_cleanups () {
68e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local CLEANUP CLEANUPS
69e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Ignore calls to atexit during cleanups
70e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  CLEANUPS=$_ALL_CLEANUPS
71e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _ALL_CLEANUPS=
72e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  for CLEANUP in $CLEANUPS; do
73e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    ($CLEANUP)
74e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  done
75e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  exit "$@"
76e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
77e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
78e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
79e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
80e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
81e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Dump a panic message then exit.
82e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1+: message
83e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgpanic () {
84e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  echo "ERROR: $@" >&2
85e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  exit 1
86e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
87e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
88e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# If the previous command failed, dump a panic message then exit.
89e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1+: message.
90e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgfail_panic () {
91e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ $? != 0 ]; then
92e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    panic "$@"
93e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi;
94e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
95e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
96e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_VERBOSE=0
97e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
98e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Increase verbosity for dump/log/run/run2 functions
99e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgincrease_verbosity () {
100e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _VERBOSE=$(( $_VERBOSE + 1 ))
101e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
102e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
103e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Decrease verbosity
104e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgdecrease_verbosity () {
105e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _VERBOSE=$(( $_VERBOSE - 1 ))
106e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
107e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
108e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Returns success iff verbosity level is higher than a specific value
109e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: verbosity level
110e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgverbosity_is_higher_than () {
111e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  [ "$_VERBOSE" -gt "$1" ]
112e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
113e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
114e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Returns success iff verbosity level is lower than a specific value
115e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: verbosity level
116e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgverbosity_is_lower_than () {
117e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  [ "$_VERBOSE" -le "$1" ]
118e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
119e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
120e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Dump message to stdout, unless verbosity is < 0, i.e. --quiet was called
121e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1+: message
122e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgdump () {
123e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_VERBOSE" -ge 0 ]; then
124e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    printf "%s\n" "$*"
125e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
126e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
127e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
128e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# If --verbose was used, dump a message to stdout.
129e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1+: message
130e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orglog () {
131e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_VERBOSE" -ge 1 ]; then
132e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    printf "%s\n" "$*"
133e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
134e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
135e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
136e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_RUN_LOG=
137e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
138e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Set a run log file that can be used to collect the output of commands that
139e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# are not displayed.
140e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgset_run_log () {
141e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _RUN_LOG=$1
142e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
143e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
144e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Run a command. Output depends on $_VERBOSE:
145e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#   $_VERBOSE <= 0:  Run command, store output into the run log
146e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#   $_VERBOSE >= 1:  Dump command, run it, output goest to stdout
147e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Note: Ideally, the command's output would go to the run log for $_VERBOSE >= 1
148e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#       but the 'tee' tool doesn't preserve the status code of its input pipe
149e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#       in case of error.
150e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgrun () {
151e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local LOGILE
152e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_RUN_LOG" ]; then
153e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    LOGFILE=$_RUN_LOG
154e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  else
155e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    LOGFILE=/dev/null
156e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
157e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
158e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_VERBOSE" -ge 1 ]; then
159e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    echo "COMMAND: $@"
160e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    "$@"
161e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  else
162e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    "$@" >>$LOGFILE 2>&1
163e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
164e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
165e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
166e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Same as run(), but only dump command output for $_VERBOSE >= 2
167e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgrun2 () {
168e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local LOGILE
169e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_RUN_LOG" ]; then
170e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    LOGFILE=$_RUN_LOG
171e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  else
172e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    LOGFILE=/dev/null
173e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
174e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
175e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_VERBOSE" -ge 1 ]; then
176e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    echo "COMMAND: $@"
177e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
178e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_VERBOSE" -ge 2 ]; then
179e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    "$@"
180e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  else
181e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    "$@" >>$LOGFILE 2>&1
182e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
183e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
184e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
185e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Extract number of cores to speed up the builds
186e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Out: number of CPU cores
187e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgget_core_count () {
188e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  case $(uname -s) in
189e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    Linux)
190e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      grep -c -e '^processor' /proc/cpuinfo
191e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
192e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    Darwin)
193e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      sysctl -n hw.ncpu
194e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
195e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    CYGWIN*|*_NT-*)
196e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      echo $NUMBER_OF_PROCESSORS
197e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
198e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    *)
199e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      echo 1
200e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
201e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  esac
202e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
203e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
204e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
205e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Check for the Android ADB program.
206e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
207e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# On success, return nothing, but updates internal variables so later calls to
208e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# adb_shell, adb_push, etc.. will work. You can get the path to the ADB program
209e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# with adb_get_program if needed.
210e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
211e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# On failure, returns 1, and updates the internal adb error message, which can
212e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# be retrieved with adb_get_error.
213e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
214e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: optional ADB program path.
215e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: success or failure.
216e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ADB=
217e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ADB_STATUS=
218e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ADB_ERROR=
219e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
220e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_check () {
221e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # First, try to find the executable in the path, or the SDK install dir.
222e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _ADB=$1
223e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ -z "$_ADB" ]; then
224e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    _ADB=$(which adb 2>/dev/null)
225e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    if [ -z "$_ADB" -a "$ANDROID_SDK_ROOT" ]; then
226e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB=$ANDROID_SDK_ROOT/platform-tools/adb
227e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      if [ ! -f "$_ADB" ]; then
228e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        _ADB=
229e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      fi
230e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    fi
231e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    if [ -z "$_ADB" ]; then
232e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_STATUS=1
233e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_ERROR="The Android 'adb' tool is not in your path."
234e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      return 1
235e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    fi
236e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
237e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
238e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  log "Found ADB program: $_ADB"
239e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
240e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Check that it works correctly
241e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local ADB_VERSION
242e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  ADB_VERSION=$("$_ADB" version 2>/dev/null)
243e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  case $ADB_VERSION in
244e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    "Android Debug Bridge "*) # Pass
245e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      log "Found ADB version: $ADB_VERSION"
246e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
247e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    *) # Fail
248e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_ERROR="Your ADB binary reports a bad version ($ADB_VERSION): $_ADB"
249e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_STATUS=1
250e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      return 1
251e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  esac
252e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
253e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _ADB_STATUS=0
254e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  return 0
255e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
256e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
257e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
258e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return the path to the Android ADB program, if correctly detected.
259e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# On failure, return the empty string.
260e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Out: ADB program path (or empty on failure)
261e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: success or failure.
262e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_get_program () {
263e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Return cached value as soon as possible.
264e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ -z "$_ADB_STATUS" ]; then
265e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    adb_check $1
266e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
267e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  echo "$_ADB"
268e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  return $_ADB_STATUS
269e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
270e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
271e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return the error corresponding to the last ADB function failure.
272e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_get_error () {
273e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  echo "$_ADB_ERROR"
274e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
275e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
276e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Check that there is one device connected through ADB.
277e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# In case of failure, use adb_get_error to know why this failed.
278e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: Optional adb program path
279e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: success or failure.
280e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ADB_DEVICE=
281e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org_ADB_DEVICE_STATUS=
282e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_check_device () {
283e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if [ "$_ADB_DEVICE_STATUS" ]; then
284e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    return $_ADB_DEVICE_STATUS
285e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
286e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
287e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Check for ADB.
288e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  if ! adb_check $1; then
289e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    _ADB_DEVICE_STATUS=$_ADB_STATUS
290e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    return 1
291e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fi
292e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
293e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local ADB_DEVICES NUM_DEVICES FINGERPRINT
294e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
295e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Count the number of connected devices.
296e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  ADB_DEVICES=$("$_ADB" devices 2>/dev/null | awk '$2 == "device" { print $1; }')
297e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  NUM_DEVICES=$(echo "$ADB_DEVICES" | wc -l)
298e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  case $NUM_DEVICES in
299e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    0)
300e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_ERROR="No Android device connected. Please connect one to your machine."
301e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      _ADB_DEVICE_STATUS=1
302e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      return 1
303e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
304e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    1) # Pass
305e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      # Ensure the same device will be called in later adb_shell calls.
306e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      export ANDROID_SERIAL=$ADB_DEVICES
307e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
308e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org    *) # 2 or more devices.
309e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      if [ "$ANDROID_SERIAL" ]; then
310e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        ADB_DEVICES=$ANDROID_SERIAL
311e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        NUM_DEVICES=1
312e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      else
313e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        _ADB_ERROR="More than one Android device connected. \
314e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgPlease define ANDROID_SERIAL in your environment"
315e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        _ADB_DEVICE_STATUS=1
316e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org        return 1
317e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      fi
318e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org      ;;
319e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  esac
320e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
321e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _ADB_DEVICE_STATUS=0
322e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  _ADB_DEVICE=$ADB_DEVICES
323e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
324e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
325e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  log "Using ADB device: $ANDROID_SERIAL ($FINGERPRINT)"
326e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  return 0
327e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
328e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
329e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# The 'adb shell' command is pretty hopeless, try to make sense of it by:
330e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#   1/ Removing trailing \r from line endings.
331e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#   2/ Ensuring the function returns the command's status code.
332e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org#
333e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1+: Command
334e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Out: command output (stdout + stderr combined)
335e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: command exit status
336e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_shell () {
337e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  local RET ADB_LOG
338e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  # Check for ADB device.
339e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  adb_check_device || return 1
340e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  ADB_LOG=$(mktemp "${TMPDIR:-/tmp}/adb-XXXXXXXX")
341e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  "$_ADB" shell "$@" ";" echo \$? > "$ADB_LOG" 2>&1
342e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  sed -i -e 's![[:cntrl:]]!!g' "$ADB_LOG"  # Remove \r.
343e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  RET=$(sed -e '$!d' "$ADB_LOG")           # Last line contains status code.
344e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  sed -e '$d' "$ADB_LOG"                   # Print everything except last line.
345e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  rm -f "$ADB_LOG"
346e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  return $RET
347e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
348e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
349e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Push a file to a device.
350e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: source file path
351e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $2: device target file path
352e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: success or failure.
353e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_push () {
354e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  adb_check_device || return 1
355e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  run "$_ADB" push "$1" "$2"
356e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
357e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
358e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Pull a file from a device
359e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $1: device file path
360e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# $2: target host file path
361e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Return: success or failure.
362e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_pull () {
363e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  adb_check_device || return 1
364e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  run "$_ADB" pull "$1" "$2"
365e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
366e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
367e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org# Same as adb_push, but will panic if the operations didn't succeed.
368e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.orgadb_install () {
369e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  adb_push "$@"
370e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org  fail_panic "Failed to install $1 to the Android device at $2"
371e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org}
372e542fe298b636258c28459972e2cbdf28258ae85digit@chromium.org
373