mirror of
git://f0xx.org/android_cast
synced 2026-07-29 04:57:40 +03:00
179 lines
6.0 KiB
Bash
Executable File
179 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Rebuild debug APK, run unit tests, reconnect wireless adb targets, install, relaunch.
|
||
set -euo pipefail
|
||
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
cd "$ROOT"
|
||
|
||
RECONNECT_KNOWN_DEVICES=${RECONNECT_KNOWN_DEVICES:-yes}
|
||
|
||
# shellcheck source=scripts/adb-reconnect.sh
|
||
source "$ROOT/scripts/adb-reconnect.sh"
|
||
adb_reconnect_init_hints
|
||
|
||
APK="$ROOT/app/build/outputs/apk/debug/app-debug.apk"
|
||
PACKAGE="com.foxx.androidcast"
|
||
LAUNCHER="$PACKAGE/.MainActivity"
|
||
|
||
RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}"
|
||
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
--skip-tests) RUN_UNIT_TESTS=0 ;;
|
||
--no-tests) RUN_UNIT_TESTS=0 ;;
|
||
--no-reconnect) RECONNECT_KNOWN_DEVICES=no ;;
|
||
--java-home=*)
|
||
ANDROID_CAST_JAVA_HOME="${arg#--java-home=}"
|
||
;;
|
||
-h|--help)
|
||
echo "Usage: $0 [--skip-tests] [--no-reconnect] [--java-home=PATH]"
|
||
echo " Builds debug APK, runs unit tests (unless skipped), reconnects adb (mdns + HTTP"
|
||
echo " :5039/adb.json + known IPs), installs on all adb devices, and launches the app."
|
||
echo " Env: RECONNECT_KNOWN_DEVICES=yes|no, DEV_ADB_HTTP_PORT=5039, ADB_TCP_PROBE=yes"
|
||
echo " ANDROID_CAST_JAVA_HOME=/path/to/jdk-21 (avoids JDK 25 warning)"
|
||
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 (17–21). 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"
|
||
|
||
if [[ "${RECONNECT_KNOWN_DEVICES}" =~ [yY] ]]; then
|
||
echo "==> Pre-build adb reconnect (HTTP :${DEV_ADB_HTTP_PORT:-5039}/adb.json)"
|
||
adb_reconnect_all "pre-build" || true
|
||
fi
|
||
|
||
# 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"
|
||
|
||
bash "$ROOT/scripts/ensure-gradle-wrapper.sh"
|
||
echo "==> Initializing third-party git submodules (libvpx, opus, speex, wireguard-android)"
|
||
bash "$ROOT/scripts/init-third-party-submodules.sh"
|
||
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
|
||
|
||
WG_HEAD="$(git -C "$ROOT/third-party/wireguard-android" rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||
echo "==> Building wireguard-android (:tunnel) from third-party/wireguard-android @ $WG_HEAD"
|
||
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"
|
||
rm -rf "$ROOT/gradle/wireguard-tunnel/.cxx" "$ROOT/gradle/wireguard-tunnel/build" 2>/dev/null || true
|
||
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 :tunnel:assembleDebug :app: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
|
||
adb_reconnect_all "post-build" || true
|
||
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 " Empty curl = app/keeper not running on that device (install once via USB)." >&2
|
||
echo " Check: scripts/adb-reconnect.sh adb_http_status 192.168.33.39" >&2
|
||
for _hint_ip in 192.168.33.39 192.168.33.106 192.168.33.153 192.168.33.173; do
|
||
adb_http_status "$_hint_ip" 2>/dev/null || true
|
||
done
|
||
exit 1
|
||
fi
|
||
|
||
echo "==> Installing to ${#DEVICES[@]} device(s): ${DEVICES[*]}"
|
||
FAILED=0
|
||
for serial in "${DEVICES[@]}"; do
|
||
echo "--- $serial"
|
||
adb_prepare_device_for_deploy "$serial"
|
||
if adb -s "$serial" install -r "$APK"; then
|
||
echo " Installed"
|
||
adb_prepare_device_for_deploy "$serial"
|
||
adb -s "$serial" shell am broadcast \
|
||
-a com.foxx.androidcast.dev.REFRESH_ADB_WIFI \
|
||
-n com.foxx.androidcast/.dev.DevAdbWifiReceiver >/dev/null 2>&1 || true
|
||
if adb -s "$serial" shell am start -n "$LAUNCHER" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER --ez after_deploy true; 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
|
||
|
||
adb_update_connect_cache
|
||
|
||
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"
|