#!/bin/bash # Copyright (C) 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function die() { echo "${@}" >&2 exit 1; } function run_cmd_or_die() { "${@}" > /dev/null || die "Command failed: ${*}" } function run_cmd_with_retries() { echo "Executing ${@}..." while true; do "${@}" && break || { echo " Retrying ${@}" sleep 10; } done } function select_device() { while :; do read -r -p "Select a device to install the ${1} app (0-${DEVICE_COUNT}): " INDEX [[ "${INDEX}" =~ ^[0-9]+$ ]] && ((INDEX >= 0 && INDEX <= DEVICE_COUNT)) && return "${INDEX}" done } function install_app() { if ! adb -s "${1}" install -r -d -g "${2}" > /dev/null; then adb -s "${1}" uninstall "com.example.android.vdmdemo.${3}" > /dev/null 2>&1 run_cmd_or_die adb -s "${1}" install -r -d -g "${2}" fi } function display_help() { echo "Setup helper for the VirtualDeviceManager host and client applications." echo "" echo " -s, --host): Setup the host application on the only device connected via ADB." echo " -c, --client): Setup the client application on the only device connected via ADB." echo " -a, --all): Setup all available demo apps: host, client, and demos." echo " -i, --install-only): Only install the selected application. Will not perform any build." echo " -h, --help): Print this help." } function display_available_devices() { echo echo "Available devices:" for i in "${!DEVICE_SERIALS[@]}"; do echo -e "${i}: ${DEVICE_SERIALS[${i}]}\t${DEVICE_NAMES[${i}]}" done echo "${DEVICE_COUNT}: Do not install this app" echo } function privileged_install() { local TARGET_DEVICE_SERIAL="${1}" local TARGET_DEVICE_NAME="${2}" local APK_DIR="${3}" local APK_FILENAME="${4}" local PERM_SRC="${5}" local PERM_DST="${6}" local PKG_NAME="com.example.android.vdmdemo.${7}" run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root if ! adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell touch /system/test_verity > /dev/null; then echo "Disabling verity..." run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device disable-verity run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device reboot run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device root else run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell rm /system/test_verity echo "Verity is already disabled" fi adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device uninstall "${PKG_NAME}" > /dev/null 2>&1 run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device remount -R run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell stop echo 'Copying privileged permissions and apk...' run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell mkdir -p "${APK_DIR}" run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${OUT}/${APK_DIR}/${APK_FILENAME}" "${APK_DIR}" run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device push "${PERM_SRC}" "${PERM_DST}" run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell start echo "Installing ${APK_FILENAME} as a privileged app to ${TARGET_DEVICE_NAME}..." run_cmd_with_retries adb -s "${TARGET_DEVICE_SERIAL}" wait-for-device shell pm install -r -g -d "${APK_DIR}/${APK_FILENAME}" echo } if [[ ! -f build/make/envsetup.sh ]] ; then if [[ -n ${ANDROID_BUILD_TOP} ]] ; then cd ${ANDROID_BUILD_TOP} else die "Run this script from the root of the tree." fi fi INSTALL_HOST=true INSTALL_CLIENT=true PERFORM_BUILD=true while [[ "$#" -gt 0 ]]; do case $1 in -h|--help) display_help; exit ;; -a|--all) shift ;; -s|--host) INSTALL_CLIENT=false; shift ;; -c|--client) INSTALL_HOST=false; shift ;; -i|--install-only) PERFORM_BUILD=false; shift ;; *) echo "Unknown parameter passed: $1"; display_help; exit ;; esac done DEVICE_COUNT=$(adb devices -l | tail -n +2 | head -n -1 | wc -l) ((DEVICE_COUNT > 0)) || die "No devices found" DEVICE_SERIALS=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $1 }') ) DEVICE_NAMES=( $(adb devices -l | tail -n +2 | head -n -1 | awk '{ print $4 }') ) HOST_SERIAL="" CLIENT_SERIAL="" CLIENT_INDEX=$DEVICE_COUNT HOST_INDEX=$DEVICE_COUNT if [[ ${INSTALL_HOST} == true ]]; then if [[ ${DEVICE_COUNT} -eq 1 ]]; then HOST_INDEX=0 else display_available_devices select_device "VDM Host" HOST_INDEX=$? fi fi if [[ ${INSTALL_CLIENT} == true ]]; then if [[ ${DEVICE_COUNT} -eq 1 ]]; then CLIENT_INDEX=0 else display_available_devices select_device "VDM Client" CLIENT_INDEX=$? fi fi if ((HOST_INDEX == DEVICE_COUNT)); then echo "Not installing host app." else HOST_SERIAL=${DEVICE_SERIALS[HOST_INDEX]} HOST_NAME="${HOST_SERIAL} ${DEVICE_NAMES[HOST_INDEX]}" echo "Installing VDM Host apps to ${HOST_NAME}." fi if ((CLIENT_INDEX == DEVICE_COUNT)); then echo "Not installing client app." else CLIENT_SERIAL=${DEVICE_SERIALS[CLIENT_INDEX]} CLIENT_NAME="${CLIENT_SERIAL} ${DEVICE_NAMES[CLIENT_INDEX]}" echo "Installing VDM Client app to ${CLIENT_NAME}." fi APKS_TO_BUILD="" [[ -n "${HOST_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmHost VdmDemos" [[ -n "${CLIENT_SERIAL}" ]] && APKS_TO_BUILD="${APKS_TO_BUILD} VdmClient" [[ -n "${APKS_TO_BUILD}" ]] || exit 0 if [[ ${PERFORM_BUILD} == true ]]; then echo echo "Building APKs:${APKS_TO_BUILD}..." echo source ./build/envsetup.sh || die "Failed to set up environment" [[ -n "${ANDROID_BUILD_TOP}" ]] || run_cmd_or_die tapas "${APKS_TO_BUILD}" UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m -j "${APKS_TO_BUILD}" || die "Build failed" else echo "Skipping Build" fi if [[ -n "${CLIENT_SERIAL}" ]]; then echo echo "Installing VdmClient.apk to ${CLIENT_NAME}..." install_app "${CLIENT_SERIAL}" "${OUT}/system/app/VdmClient/VdmClient.apk" client fi if [[ -n "${HOST_SERIAL}" ]]; then echo echo "Installing VdmDemos.apk to ${HOST_NAME}..." install_app "${HOST_SERIAL}" "${OUT}/system/app/VdmDemos/VdmDemos.apk" demos echo readonly HOST_PERM_BASENAME=VdmHost.xml readonly HOST_PERM_SRC="${OUT}/system/etc/permissions/${HOST_PERM_BASENAME}" readonly HOST_PERM_DST="/system/etc/permissions/${HOST_PERM_BASENAME}" readonly HOST_APK_DIR=/system/priv-app/VdmHost echo "Preparing ${HOST_NAME} for privileged VdmHost installation..." if adb -s "${HOST_SERIAL}" shell ls "${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1 \ && adb -s "${HOST_SERIAL}" pull "${HOST_PERM_DST}" "/tmp/${HOST_PERM_BASENAME}" > /dev/null 2>&1 \ && cmp --silent "/tmp/${HOST_PERM_BASENAME}" "${HOST_PERM_SRC}" \ && (adb -s "${HOST_SERIAL}" uninstall com.example.android.vdmdemo.host > /dev/null 2>&1 || true) \ && adb -s "${HOST_SERIAL}" install -r -d -g "${OUT}/${HOST_APK_DIR}/VdmHost.apk" > /dev/null 2>&1; then echo "A privileged installation already found, installed VdmHost.apk to ${HOST_NAME}" echo else privileged_install "${HOST_SERIAL}" "${HOST_NAME}" "${HOST_APK_DIR}" \ "VdmHost.apk" "${HOST_PERM_SRC}" "${HOST_PERM_DST}" host fi fi echo echo 'Success!' echo