1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 03:18:32 +03:00
Files
android_cast/rebuild.sh
Anton Afanasyeu 4e74a92457 Fix rebuild.sh after Docker CI leaves stale app/.cxx paths.
Clear app/.cxx before gradlew clean (Docker uses /opt/android-sdk in CMake
cache on mounted repos). CI now removes .cxx after build; gitignore app/.cxx.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 22:19:51 +02:00

219 lines
6.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Rebuild debug APK, run unit tests, reconnect known wireless adb targets, install, relaunch.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"
RECONNECT_KNOWN_DEVICES=${RECONNECT_KNOWN_DEVICES:-no}
# Hints for wireless debugging. Edit as needed.
## CONNECTIONS_LIST_HINTS[IP_WITH_UNDERLINES]="hint string"
declare -A CONNECTIONS_LIST_HINTS
## android tv projector / android 13
CONNECTIONS_LIST_HINTS["192_168_33_153"]="[A13] Android Projector"
## tab g6 max / android 16
CONNECTIONS_LIST_HINTS["192_168_33_39"]="[A16] Doogee Tab G6 Max / P8_EEA"
## bl6000pro main / android 11
CONNECTIONS_LIST_HINTS["192_168_33_106"]="[A11] BlackView BL6000Pro / BL6000Pro_EEA"
## bl6000pro aux / android 11
CONNECTIONS_LIST_HINTS["192_168_33_173"]="[A11] BlackView BL6000Pro / BL6000Pro"
get_ip_for_hint_key() {
local ip=${1}
ip="$(echo "${ip}" | sed -e s'@_@\.@g' -e s'@:.*@@' | tr -d '\n' )"
printf "%s" "${ip}"
}
get_hint_key_for_ip() {
local ip=${1}
ip="$(echo "${ip}" | sed -e s'@\.@_@g' -e s'@:.*@@' | tr -d '\n' )"
printf "%s" "${ip}"
}
get_hint() {
local ip_mask="${1}"
local -n hint
ip_mask="$(get_hint_key_for_ip "${ip_mask}")"
hint=CONNECTIONS_LIST_HINTS[${ip_mask}]
printf "%s" "${hint}"
}
APK="$ROOT/app/build/outputs/apk/debug/app-debug.apk"
PACKAGE="com.foxx.androidcast"
LAUNCHER="$PACKAGE/.MainActivity"
RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}"
ADB_CONNECT_RETRIES="${ADB_CONNECT_RETRIES:-4}"
ADB_CONNECT_DELAY_SEC="${ADB_CONNECT_DELAY_SEC:-2}"
for arg in "$@"; do
case "$arg" in
--skip-tests) RUN_UNIT_TESTS=0 ;;
--no-tests) RUN_UNIT_TESTS=0 ;;
--java-home=*)
ANDROID_CAST_JAVA_HOME="${arg#--java-home=}"
;;
-h|--help)
echo "Usage: $0 [--skip-tests] [--java-home=PATH]"
echo " Builds debug APK, runs unit tests (unless skipped), reconnects devices in CONNECTIONS_LIST_HINTS,"
echo " installs on all adb devices in 'device' state, and launches the app."
exit 0
;;
esac
done
pick_java_home() {
if [[ -n "${ANDROID_CAST_JAVA_HOME:-}" && -x "${ANDROID_CAST_JAVA_HOME}/bin/java" ]]; then
echo "$ANDROID_CAST_JAVA_HOME"
return 0
fi
local c
for c in /usr/lib/jvm/openjdk-bin-21 /usr/lib/jvm/java-21-openjdk; do
if [[ -x "$c/bin/java" ]]; then
echo "$c"
return 0
fi
done
for c in /usr/lib/jvm/openjdk-bin-17 /usr/lib/jvm/java-17-openjdk; do
if [[ -x "$c/bin/java" ]]; then
echo "$c"
return 0
fi
done
return 1
}
if [[ -n "${JAVA_HOME:-}" && -x "${JAVA_HOME}/bin/java" ]]; then
jver="$("${JAVA_HOME}/bin/java" -version 2>&1 | head -1)"
if [[ "$jver" =~ version\ \"(2[5-9]|[3-9][0-9]) ]]; then
echo "WARN: JAVA_HOME is too new for Gradle 8.9 ($JAVA_HOME$jver)."
echo " Picking a supported JDK (1721). Set ANDROID_CAST_JAVA_HOME to override."
fi
fi
if ! picked="$(pick_java_home)"; then
echo "ERROR: No JDK 17 or 21 found. Install openjdk-bin-21 or set ANDROID_CAST_JAVA_HOME." >&2
exit 1
fi
export JAVA_HOME="$picked"
reconnect_endpoint() {
local endpoint="$1"
[[ -z "$endpoint" ]] && return 1
local attempt out
local hint=""
hint="$(get_hint "${endpoint}")"
[[ -n "${hint}" ]] && hint="(having hint: ${hint})"
echo " trying to connect to $endpoint ${hint}"
adb disconnect "$endpoint" >/dev/null 2>&1 || true
for (( attempt = 1; attempt <= ADB_CONNECT_RETRIES; attempt++ )); do
out="$(adb connect "$endpoint" 2>&1)" || true
if grep -qiE 'connected|already' <<<"$out"; then
if adb -s "$endpoint" get-state 2>/dev/null | grep -q '^device$'; then
echo " $endpoint — ready"
return 0
fi
fi
if [[ "$attempt" -lt "$ADB_CONNECT_RETRIES" ]]; then
sleep "$ADB_CONNECT_DELAY_SEC"
fi
done
echo " $endpoint — not reachable ($out)" >&2
return 1
}
reconnect_known_devices() {
echo "==> Reconnecting known wireless adb endpoints"
adb start-server >/dev/null 2>&1 || true
adb reconnect offline >/dev/null 2>&1 || true
local endpoint
for endpoint in "${!CONNECTIONS_LIST_HINTS[@]}"; do
reconnect_endpoint "$(get_ip_for_hint_key "$endpoint")" || true
done
adb devices -l
}
# shellcheck source=scripts/android-ndk.sh
source "$ROOT/scripts/android-ndk.sh"
# shellcheck source=scripts/native-build-cache.sh
source "$ROOT/scripts/native-build-cache.sh"
export ANDROIDCAST_ROOT="$ROOT"
export ANDROID_NDK_HOME="$(androidcast_find_ndk_root "$ROOT")"
export ANDROID_NDK_ROOT="$ANDROID_NDK_HOME"
echo "==> Using NDK: $ANDROID_NDK_HOME"
if androidcast_ccache_wanted 2>/dev/null; then
echo "==> Native ccache: enabled (ANDROIDCAST_CCACHE=${ANDROIDCAST_CCACHE:-auto})"
else
echo "==> Native ccache: disabled"
fi
# Match app/build.gradle defaultConfig.ndk.abiFilters
ARCH_ABIS="armeabi-v7a arm64-v8a x86_64"
echo "==> Building libvpx for: ${ARCH_ABIS}"
rm -rf "$ROOT/build/native"
mkdir -p "$ROOT/build/native"
for ARCH_ABI in ${ARCH_ABIS}; do
unset ANDROIDCAST_LIBVPX_LIB
LC_ALL=C ./scripts/build-native-codecs.sh "${ARCH_ABI}"
done
echo "==> Building debug APK (JAVA_HOME=$JAVA_HOME)"
# Docker CI on a mounted repo leaves app/.cxx with /opt/android-sdk paths; that breaks local clean/build.
rm -rf "$ROOT/app/.cxx"
if [[ -d "$ROOT/app/build" ]] && ! rm -rf "$ROOT/app/build" 2>/dev/null; then
echo "WARN: app/build is not writable (often root-owned after Docker). Run: sudo rm -rf app/build" >&2
fi
./gradlew --stop
./gradlew clean
./gradlew --build-cache assembleDebug
if [[ "$RUN_UNIT_TESTS" == "1" ]]; then
echo "==> Running unit tests (./gradlew testDebugUnitTest)"
./gradlew testDebugUnitTest
else
echo "==> Skipping unit tests (RUN_UNIT_TESTS=$RUN_UNIT_TESTS)"
fi
if [[ ! -f "$APK" ]]; then
echo "ERROR: APK not found at $APK" >&2
exit 1
fi
if [[ "${RECONNECT_KNOWN_DEVICES}" =~ "[yY]*" ]]; then
reconnect_known_devices
fi
mapfile -t DEVICES < <(adb devices | awk 'NR > 1 && $2 == "device" { print $1 }')
if [[ ${#DEVICES[@]} -eq 0 ]]; then
echo "ERROR: No adb devices in 'device' state after reconnect." >&2
echo " Wake devices, re-enable wireless debugging, or: adb connect HOST:5555" >&2
exit 1
fi
echo "==> Installing to ${#DEVICES[@]} device(s): ${DEVICES[*]}"
FAILED=0
for serial in "${DEVICES[@]}"; do
echo "--- $serial"
if adb -s "$serial" install -r "$APK"; then
echo " Installed"
if adb -s "$serial" shell am start -n "$LAUNCHER" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER; then
echo " Launched $LAUNCHER"
else
echo " WARN: launch failed (app may still be installed)" >&2
fi
else
echo " FAILED" >&2
FAILED=$((FAILED + 1))
fi
done
if [[ $FAILED -gt 0 ]]; then
echo "Done with $FAILED failure(s)." >&2
exit 1
fi
echo "Done. APK: $APK"
echo "Open this folder in Android Studio: $ROOT"