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 +