toolkit/crashreporter/google-breakpad/android/common-functions.sh

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/android/common-functions.sh	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,372 @@
     1.4 +# Copyright (c) 2012 Google Inc.
     1.5 +# All rights reserved.
     1.6 +#
     1.7 +# Redistribution and use in source and binary forms, with or without
     1.8 +# modification, are permitted provided that the following conditions are
     1.9 +# met:
    1.10 +#
    1.11 +#     * Redistributions of source code must retain the above copyright
    1.12 +# notice, this list of conditions and the following disclaimer.
    1.13 +#     * Redistributions in binary form must reproduce the above
    1.14 +# copyright notice, this list of conditions and the following disclaimer
    1.15 +# in the documentation and/or other materials provided with the
    1.16 +# distribution.
    1.17 +#     * Neither the name of Google Inc. nor the names of its
    1.18 +# contributors may be used to endorse or promote products derived from
    1.19 +# this software without specific prior written permission.
    1.20 +#
    1.21 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.22 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.23 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.24 +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.25 +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.26 +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.27 +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.28 +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.29 +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.30 +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.31 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.32 +
    1.33 +# Collection of common shell functions for 'run-checks.sh' et 'test-shell.sh'
    1.34 +
    1.35 +# All internal variables and functions use an underscore as a prefix
    1.36 +# (e.g. _VERBOSE, _ALL_CLEANUPS, etc..).
    1.37 +
    1.38 +# Sanitize the environment
    1.39 +export LANG=C
    1.40 +export LC_ALL=C
    1.41 +
    1.42 +if [ "$BASH_VERSION" ]; then
    1.43 +  set -o posix
    1.44 +fi
    1.45 +
    1.46 +# Utility functions
    1.47 +
    1.48 +_ALL_CLEANUPS=
    1.49 +
    1.50 +# Register a function to be called when the script exits, even in case of
    1.51 +# Ctrl-C, logout, etc.
    1.52 +# $1: function name.
    1.53 +atexit () {
    1.54 +  if [ -z "$_ALL_CLEANUPS" ]; then
    1.55 +    _ALL_CLEANUPS=$1
    1.56 +    # Ensure a clean exit when the script is:
    1.57 +    #  - Exiting normally (EXIT)
    1.58 +    #  - Interrupted by Ctrl-C (INT)
    1.59 +    #  - Interrupted by log out (HUP)
    1.60 +    #  - Being asked to quit nicely (TERM)
    1.61 +    #  - Being asked to quit and dump core (QUIT)
    1.62 +    trap "_exit_cleanups \$?" EXIT INT HUP QUIT TERM
    1.63 +  else
    1.64 +    _ALL_CLEANUPS="$_ALL_CLEANUPS $1"
    1.65 +  fi
    1.66 +}
    1.67 +
    1.68 +# Called on exit if at least one function was registered with atexit
    1.69 +# $1: final exit status code
    1.70 +_exit_cleanups () {
    1.71 +  local CLEANUP CLEANUPS
    1.72 +  # Ignore calls to atexit during cleanups
    1.73 +  CLEANUPS=$_ALL_CLEANUPS
    1.74 +  _ALL_CLEANUPS=
    1.75 +  for CLEANUP in $CLEANUPS; do
    1.76 +    ($CLEANUP)
    1.77 +  done
    1.78 +  exit "$@"
    1.79 +}
    1.80 +
    1.81 +
    1.82 +
    1.83 +
    1.84 +# Dump a panic message then exit.
    1.85 +# $1+: message
    1.86 +panic () {
    1.87 +  echo "ERROR: $@" >&2
    1.88 +  exit 1
    1.89 +}
    1.90 +
    1.91 +# If the previous command failed, dump a panic message then exit.
    1.92 +# $1+: message.
    1.93 +fail_panic () {
    1.94 +  if [ $? != 0 ]; then
    1.95 +    panic "$@"
    1.96 +  fi;
    1.97 +}
    1.98 +
    1.99 +_VERBOSE=0
   1.100 +
   1.101 +# Increase verbosity for dump/log/run/run2 functions
   1.102 +increase_verbosity () {
   1.103 +  _VERBOSE=$(( $_VERBOSE + 1 ))
   1.104 +}
   1.105 +
   1.106 +# Decrease verbosity
   1.107 +decrease_verbosity () {
   1.108 +  _VERBOSE=$(( $_VERBOSE - 1 ))
   1.109 +}
   1.110 +
   1.111 +# Returns success iff verbosity level is higher than a specific value
   1.112 +# $1: verbosity level
   1.113 +verbosity_is_higher_than () {
   1.114 +  [ "$_VERBOSE" -gt "$1" ]
   1.115 +}
   1.116 +
   1.117 +# Returns success iff verbosity level is lower than a specific value
   1.118 +# $1: verbosity level
   1.119 +verbosity_is_lower_than () {
   1.120 +  [ "$_VERBOSE" -le "$1" ]
   1.121 +}
   1.122 +
   1.123 +# Dump message to stdout, unless verbosity is < 0, i.e. --quiet was called
   1.124 +# $1+: message
   1.125 +dump () {
   1.126 +  if [ "$_VERBOSE" -ge 0 ]; then
   1.127 +    printf "%s\n" "$*"
   1.128 +  fi
   1.129 +}
   1.130 +
   1.131 +# If --verbose was used, dump a message to stdout.
   1.132 +# $1+: message
   1.133 +log () {
   1.134 +  if [ "$_VERBOSE" -ge 1 ]; then
   1.135 +    printf "%s\n" "$*"
   1.136 +  fi
   1.137 +}
   1.138 +
   1.139 +_RUN_LOG=
   1.140 +
   1.141 +# Set a run log file that can be used to collect the output of commands that
   1.142 +# are not displayed.
   1.143 +set_run_log () {
   1.144 +  _RUN_LOG=$1
   1.145 +}
   1.146 +
   1.147 +# Run a command. Output depends on $_VERBOSE:
   1.148 +#   $_VERBOSE <= 0:  Run command, store output into the run log
   1.149 +#   $_VERBOSE >= 1:  Dump command, run it, output goest to stdout
   1.150 +# Note: Ideally, the command's output would go to the run log for $_VERBOSE >= 1
   1.151 +#       but the 'tee' tool doesn't preserve the status code of its input pipe
   1.152 +#       in case of error.
   1.153 +run () {
   1.154 +  local LOGILE
   1.155 +  if [ "$_RUN_LOG" ]; then
   1.156 +    LOGFILE=$_RUN_LOG
   1.157 +  else
   1.158 +    LOGFILE=/dev/null
   1.159 +  fi
   1.160 +
   1.161 +  if [ "$_VERBOSE" -ge 1 ]; then
   1.162 +    echo "COMMAND: $@"
   1.163 +    "$@"
   1.164 +  else
   1.165 +    "$@" >>$LOGFILE 2>&1
   1.166 +  fi
   1.167 +}
   1.168 +
   1.169 +# Same as run(), but only dump command output for $_VERBOSE >= 2
   1.170 +run2 () {
   1.171 +  local LOGILE
   1.172 +  if [ "$_RUN_LOG" ]; then
   1.173 +    LOGFILE=$_RUN_LOG
   1.174 +  else
   1.175 +    LOGFILE=/dev/null
   1.176 +  fi
   1.177 +
   1.178 +  if [ "$_VERBOSE" -ge 1 ]; then
   1.179 +    echo "COMMAND: $@"
   1.180 +  fi
   1.181 +  if [ "$_VERBOSE" -ge 2 ]; then
   1.182 +    "$@"
   1.183 +  else
   1.184 +    "$@" >>$LOGFILE 2>&1
   1.185 +  fi
   1.186 +}
   1.187 +
   1.188 +# Extract number of cores to speed up the builds
   1.189 +# Out: number of CPU cores
   1.190 +get_core_count () {
   1.191 +  case $(uname -s) in
   1.192 +    Linux)
   1.193 +      grep -c -e '^processor' /proc/cpuinfo
   1.194 +      ;;
   1.195 +    Darwin)
   1.196 +      sysctl -n hw.ncpu
   1.197 +      ;;
   1.198 +    CYGWIN*|*_NT-*)
   1.199 +      echo $NUMBER_OF_PROCESSORS
   1.200 +      ;;
   1.201 +    *)
   1.202 +      echo 1
   1.203 +      ;;
   1.204 +  esac
   1.205 +}
   1.206 +
   1.207 +
   1.208 +# Check for the Android ADB program.
   1.209 +#
   1.210 +# On success, return nothing, but updates internal variables so later calls to
   1.211 +# adb_shell, adb_push, etc.. will work. You can get the path to the ADB program
   1.212 +# with adb_get_program if needed.
   1.213 +#
   1.214 +# On failure, returns 1, and updates the internal adb error message, which can
   1.215 +# be retrieved with adb_get_error.
   1.216 +#
   1.217 +# $1: optional ADB program path.
   1.218 +# Return: success or failure.
   1.219 +_ADB=
   1.220 +_ADB_STATUS=
   1.221 +_ADB_ERROR=
   1.222 +
   1.223 +adb_check () {
   1.224 +  # First, try to find the executable in the path, or the SDK install dir.
   1.225 +  _ADB=$1
   1.226 +  if [ -z "$_ADB" ]; then
   1.227 +    _ADB=$(which adb 2>/dev/null)
   1.228 +    if [ -z "$_ADB" -a "$ANDROID_SDK_ROOT" ]; then
   1.229 +      _ADB=$ANDROID_SDK_ROOT/platform-tools/adb
   1.230 +      if [ ! -f "$_ADB" ]; then
   1.231 +        _ADB=
   1.232 +      fi
   1.233 +    fi
   1.234 +    if [ -z "$_ADB" ]; then
   1.235 +      _ADB_STATUS=1
   1.236 +      _ADB_ERROR="The Android 'adb' tool is not in your path."
   1.237 +      return 1
   1.238 +    fi
   1.239 +  fi
   1.240 +
   1.241 +  log "Found ADB program: $_ADB"
   1.242 +
   1.243 +  # Check that it works correctly
   1.244 +  local ADB_VERSION
   1.245 +  ADB_VERSION=$("$_ADB" version 2>/dev/null)
   1.246 +  case $ADB_VERSION in
   1.247 +    "Android Debug Bridge "*) # Pass
   1.248 +      log "Found ADB version: $ADB_VERSION"
   1.249 +      ;;
   1.250 +    *) # Fail
   1.251 +      _ADB_ERROR="Your ADB binary reports a bad version ($ADB_VERSION): $_ADB"
   1.252 +      _ADB_STATUS=1
   1.253 +      return 1
   1.254 +  esac
   1.255 +
   1.256 +  _ADB_STATUS=0
   1.257 +  return 0
   1.258 +}
   1.259 +
   1.260 +
   1.261 +# Return the path to the Android ADB program, if correctly detected.
   1.262 +# On failure, return the empty string.
   1.263 +# Out: ADB program path (or empty on failure)
   1.264 +# Return: success or failure.
   1.265 +adb_get_program () {
   1.266 +  # Return cached value as soon as possible.
   1.267 +  if [ -z "$_ADB_STATUS" ]; then
   1.268 +    adb_check $1
   1.269 +  fi
   1.270 +  echo "$_ADB"
   1.271 +  return $_ADB_STATUS
   1.272 +}
   1.273 +
   1.274 +# Return the error corresponding to the last ADB function failure.
   1.275 +adb_get_error () {
   1.276 +  echo "$_ADB_ERROR"
   1.277 +}
   1.278 +
   1.279 +# Check that there is one device connected through ADB.
   1.280 +# In case of failure, use adb_get_error to know why this failed.
   1.281 +# $1: Optional adb program path
   1.282 +# Return: success or failure.
   1.283 +_ADB_DEVICE=
   1.284 +_ADB_DEVICE_STATUS=
   1.285 +adb_check_device () {
   1.286 +  if [ "$_ADB_DEVICE_STATUS" ]; then
   1.287 +    return $_ADB_DEVICE_STATUS
   1.288 +  fi
   1.289 +
   1.290 +  # Check for ADB.
   1.291 +  if ! adb_check $1; then
   1.292 +    _ADB_DEVICE_STATUS=$_ADB_STATUS
   1.293 +    return 1
   1.294 +  fi
   1.295 +
   1.296 +  local ADB_DEVICES NUM_DEVICES FINGERPRINT
   1.297 +
   1.298 +  # Count the number of connected devices.
   1.299 +  ADB_DEVICES=$("$_ADB" devices 2>/dev/null | awk '$2 == "device" { print $1; }')
   1.300 +  NUM_DEVICES=$(echo "$ADB_DEVICES" | wc -l)
   1.301 +  case $NUM_DEVICES in
   1.302 +    0)
   1.303 +      _ADB_ERROR="No Android device connected. Please connect one to your machine."
   1.304 +      _ADB_DEVICE_STATUS=1
   1.305 +      return 1
   1.306 +      ;;
   1.307 +    1) # Pass
   1.308 +      # Ensure the same device will be called in later adb_shell calls.
   1.309 +      export ANDROID_SERIAL=$ADB_DEVICES
   1.310 +      ;;
   1.311 +    *) # 2 or more devices.
   1.312 +      if [ "$ANDROID_SERIAL" ]; then
   1.313 +        ADB_DEVICES=$ANDROID_SERIAL
   1.314 +        NUM_DEVICES=1
   1.315 +      else
   1.316 +        _ADB_ERROR="More than one Android device connected. \
   1.317 +Please define ANDROID_SERIAL in your environment"
   1.318 +        _ADB_DEVICE_STATUS=1
   1.319 +        return 1
   1.320 +      fi
   1.321 +      ;;
   1.322 +  esac
   1.323 +
   1.324 +  _ADB_DEVICE_STATUS=0
   1.325 +  _ADB_DEVICE=$ADB_DEVICES
   1.326 +
   1.327 +  FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
   1.328 +  log "Using ADB device: $ANDROID_SERIAL ($FINGERPRINT)"
   1.329 +  return 0
   1.330 +}
   1.331 +
   1.332 +# The 'adb shell' command is pretty hopeless, try to make sense of it by:
   1.333 +#   1/ Removing trailing \r from line endings.
   1.334 +#   2/ Ensuring the function returns the command's status code.
   1.335 +#
   1.336 +# $1+: Command
   1.337 +# Out: command output (stdout + stderr combined)
   1.338 +# Return: command exit status
   1.339 +adb_shell () {
   1.340 +  local RET ADB_LOG
   1.341 +  # Check for ADB device.
   1.342 +  adb_check_device || return 1
   1.343 +  ADB_LOG=$(mktemp "${TMPDIR:-/tmp}/adb-XXXXXXXX")
   1.344 +  "$_ADB" shell "$@" ";" echo \$? > "$ADB_LOG" 2>&1
   1.345 +  sed -i -e 's![[:cntrl:]]!!g' "$ADB_LOG"  # Remove \r.
   1.346 +  RET=$(sed -e '$!d' "$ADB_LOG")           # Last line contains status code.
   1.347 +  sed -e '$d' "$ADB_LOG"                   # Print everything except last line.
   1.348 +  rm -f "$ADB_LOG"
   1.349 +  return $RET
   1.350 +}
   1.351 +
   1.352 +# Push a file to a device.
   1.353 +# $1: source file path
   1.354 +# $2: device target file path
   1.355 +# Return: success or failure.
   1.356 +adb_push () {
   1.357 +  adb_check_device || return 1
   1.358 +  run "$_ADB" push "$1" "$2"
   1.359 +}
   1.360 +
   1.361 +# Pull a file from a device
   1.362 +# $1: device file path
   1.363 +# $2: target host file path
   1.364 +# Return: success or failure.
   1.365 +adb_pull () {
   1.366 +  adb_check_device || return 1
   1.367 +  run "$_ADB" pull "$1" "$2"
   1.368 +}
   1.369 +
   1.370 +# Same as adb_push, but will panic if the operations didn't succeed.
   1.371 +adb_install () {
   1.372 +  adb_push "$@"
   1.373 +  fail_panic "Failed to install $1 to the Android device at $2"
   1.374 +}
   1.375 +

mercurial