1#!/bin/bash 2 3# Copyright (C) 2023 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17function die() { 18 echo "${@}" >&2 19 exit 1; 20} 21 22function run_cmd_or_die() { 23 "${@}" > /dev/null || die "Command failed: ${*}" 24} 25 26function run_cmd_with_retries() { 27 echo "Executing ${@}..." 28 while true; do 29 "${@}" && break || { 30 echo " Retrying ${@}" 31 sleep 10; 32 } 33 done 34} 35 36function select_device() { 37 while :; do 38 read -r -p "Select a device to install the ${1} app (0-${DEVICE_COUNT}): " INDEX 39 [[ "${INDEX}" =~ ^[0-9]+$ ]] && ((INDEX >= 0 && INDEX <= DEVICE_COUNT)) && return "${INDEX}" 40 done 41} 42 43function install_app() { 44 if ! adb -s "${1}" install -r -d -g "${2}" > /dev/null; then 45 adb -s "${1}" uninstall "com.example.android.vdmdemo.${3}" > /dev/null 2>&1 46 run_cmd_or_die adb -s "${1}" install -r -d -g "${2}" 47 fi 48} 49 50function display_help() { 51 echo "Setup helper for the VirtualDeviceManager host and client applications." 52 echo "" 53 echo " -s, --host): Setup the host application on the only device connected via ADB." 54 echo " -c, --client): Setup the client application on the only device connected via ADB." 55 echo " -a, --all): Setup all available demo apps: host, client, and demos." 56 echo " -i, --install-only): Only install the selected application. Will not perform any build." 57 echo " -h, --help): Print this help." 58} 59 60function display_available_devices() { 61 echo 62 echo "Available devices:" 63 for i in "${!DEVICE_SERIALS[@]}"; do 64 echo -e "${i}: ${DEVICE_SERIALS[${i}]}\t${DEVICE_NAMES[${i}]}" 65 done 66 echo "${DEVICE_COUNT}: Do not install this app" 67 echo 68} 69 70function privileged_install() { 71 local TARGET_DEVICE_SERIAL="${1}" 72 local TARGET_DEVICE_NAME="${2}" 73 local APK_DIR="${3}" 74 local APK_FILENAME="${4}" 75 local PERM_SRC="${5}" 76 local PERM_DST="${6}" 77 local PKG_NAME="com.example.android.vdmdemo.${7}" 78 79 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root 80 if ! adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell touch /system/test_verity > /dev/null; then 81 echo "Disabling verity..." 82 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device disable-verity 83 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device reboot 84 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root 85 else 86 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell rm /system/test_verity 87 echo "Verity is already disabled" 88 fi 89 90 adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device uninstall "${PKG_NAME}" > /dev/null 2>&1 91 92 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device remount -R 93 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell stop 94 echo 'Copying privileged permissions and apk...' 95 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell mkdir -p "${APK_DIR}" 96 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${OUT}/${APK_DIR}/${APK_FILENAME}" "${APK_DIR}" 97 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${PERM_SRC}" "${PERM_DST}" 98 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell start 99 echo "Installing ${APK_FILENAME} as a privileged app to ${TARGET_DEVICE_NAME}..." 100 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell pm install -r -g -d "${APK_DIR}/${APK_FILENAME}" 101 echo 102} 103 104 105if [[ ! -f build/make/envsetup.sh ]] ; then 106 if [[ -n ${ANDROID_BUILD_TOP} ]] ; then 107 cd ${ANDROID_BUILD_TOP} 108 else 109 die "Run this script from the root of the tree." 110 fi 111fi 112 113INSTALL_HOST=true 114INSTALL_CLIENT=true 115PERFORM_BUILD=true 116while [[ "$#" -gt 0 ]]; do 117 case $1 in 118 -h|--help) display_help; exit ;; 119 -a|--all) shift ;; 120 -s|--host) INSTALL_CLIENT=false; shift ;; 121 -c|--client) INSTALL_HOST=false; shift ;; 122 -i|--install-only) PERFORM_BUILD=false; shift ;; 123 *) echo "Unknown parameter passed: $1"; display_help; exit ;; 124 esac 125done 126 127DEVICE_COUNT=$(adb devices -l | tail -n +2 | head -n -1 | wc -l) 128((DEVICE_COUNT > 0)) || die "No devices found" 129 130DEVICE_SERIALS=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $1 }') ) 131DEVICE_NAMES=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $4 }') ) 132HOST_SERIAL="" 133CLIENT_SERIAL="" 134CLIENT_INDEX=$DEVICE_COUNT 135HOST_INDEX=$DEVICE_COUNT 136 137if [[ ${INSTALL_HOST} == true ]]; then 138 if [[ ${DEVICE_COUNT} -eq 1 ]]; then 139 HOST_INDEX=0 140 else 141 display_available_devices 142 select_device "VDM Host" 143 HOST_INDEX=$? 144 fi 145fi 146if [[ ${INSTALL_CLIENT} == true ]]; then 147 if [[ ${DEVICE_COUNT} -eq 1 ]]; then 148 CLIENT_INDEX=0 149 else 150 display_available_devices 151 select_device "VDM Client" 152 CLIENT_INDEX=$? 153 fi 154fi 155 156if ((HOST_INDEX == DEVICE_COUNT)); then 157 echo "Not installing host app." 158else 159 HOST_SERIAL=${DEVICE_SERIALS[HOST_INDEX]} 160 HOST_NAME="${HOST_SERIAL} ${DEVICE_NAMES[HOST_INDEX]}" 161 echo "Installing VDM Host apps to ${HOST_NAME}." 162fi 163if ((CLIENT_INDEX == DEVICE_COUNT)); then 164 echo "Not installing client app." 165else 166 CLIENT_SERIAL=${DEVICE_SERIALS[CLIENT_INDEX]} 167 CLIENT_NAME="${CLIENT_SERIAL} ${DEVICE_NAMES[CLIENT_INDEX]}" 168 echo "Installing VDM Client app to ${CLIENT_NAME}." 169fi 170 171APKS_TO_BUILD="" 172[[ -n "${HOST_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmHost VdmDemos" 173[[ -n "${CLIENT_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmClient" 174[[ -n "${APKS_TO_BUILD}" ]] || exit 0 175 176if [[ ${PERFORM_BUILD} == true ]]; 177then 178 echo 179 echo "Building APKs:${APKS_TO_BUILD}..." 180 echo 181 182 source ./build/envsetup.sh || die "Failed to set up environment" 183 [[ -n "${ANDROID_BUILD_TOP}" ]] || run_cmd_or_die tapas "${APKS_TO_BUILD}" 184 UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m -j "${APKS_TO_BUILD}" || die "Build failed" 185else 186 echo "Skipping Build" 187fi 188 189if [[ -n "${CLIENT_SERIAL}" ]]; then 190 echo 191 echo "Installing VdmClient.apk to ${CLIENT_NAME}..." 192 install_app "${CLIENT_SERIAL}" "${OUT}/system/app/VdmClient/VdmClient.apk" client 193fi 194 195if [[ -n "${HOST_SERIAL}" ]]; then 196 echo 197 echo "Installing VdmDemos.apk to ${HOST_NAME}..." 198 install_app "${HOST_SERIAL}" "${OUT}/system/app/VdmDemos/VdmDemos.apk" demos 199 echo 200 201 readonly HOST_PERM_BASENAME=VdmHost.xml 202 readonly HOST_PERM_SRC="${OUT}/system/etc/permissions/${HOST_PERM_BASENAME}" 203 readonly HOST_PERM_DST="/system/etc/permissions/${HOST_PERM_BASENAME}" 204 readonly HOST_APK_DIR=/system/priv-app/VdmHost 205 206 echo "Preparing ${HOST_NAME} for privileged VdmHost installation..." 207 if adb -s "${HOST_SERIAL}" shell ls "${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1 \ 208 && adb -s "${HOST_SERIAL}" pull "${HOST_PERM_DST}" "/tmp/${HOST_PERM_BASENAME}" > /dev/null 2>&1 \ 209 && cmp --silent "/tmp/${HOST_PERM_BASENAME}" "${HOST_PERM_SRC}" \ 210 && (adb -s "${HOST_SERIAL}" uninstall com.example.android.vdmdemo.host > /dev/null 2>&1 || true) \ 211 && adb -s "${HOST_SERIAL}" install -r -d -g "${OUT}/${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1; then 212 echo "A privileged installation already found, installed VdmHost.apk to ${HOST_NAME}" 213 echo 214 else 215 privileged_install "${HOST_SERIAL}" "${HOST_NAME}" "${HOST_APK_DIR}" \ 216 "VdmHost.apk" "${HOST_PERM_SRC}" "${HOST_PERM_DST}" host 217 fi 218fi 219 220echo 221echo 'Success!' 222echo 223