ui: First card auto-focus, visible top-bar focus, account button
On launch and on every destination switch the first card of the content gets focus automatically - invisible focus on chrome confused 'Do I need to press DOWN first?'. The search button shows a white ring when focused, and the top bar gained a real account button (person icon + logged-in username) replacing the cryptic monitor icon. start-emulator.sh: headless-safe boot (no -gpuhost crash without a display), whitelists adb public keys headlessly (drop them into /tmp/jtube-adbkeys/), and starts the socat bridge itself.
This commit is contained in:
parent
b84be3e65e
commit
e55f7f53c1
5 changed files with 149 additions and 39 deletions
|
|
@ -5,8 +5,9 @@
|
|||
# be tested over scrcpy (ATD/system quirks make scrcpy fail against headless
|
||||
# in-container emulators) or when you simply want to watch it.
|
||||
#
|
||||
# The agent container bridges rutherford:5556 -> 127.0.0.1:5601 with socat, so after
|
||||
# this script the emulator is reachable as:
|
||||
# Boots on console :5600 (adbd :5601); the agent container bridges
|
||||
# rutherford:5556 -> 127.0.0.1:5601 with socat, so after this script the emulator is
|
||||
# reachable from anywhere as:
|
||||
#
|
||||
# adb connect rutherford:5556 && scrcpy -s rutherford:5556
|
||||
#
|
||||
|
|
@ -17,14 +18,34 @@ set -euo pipefail
|
|||
SDK="${ANDROID_SDK_ROOT:-$HOME/Android/Sdk}"
|
||||
EMU="$SDK/emulator/emulator"
|
||||
ADB="$SDK/platform-tools/adb"
|
||||
SDKM="$SDK/cmdline-tools/latest/bin/sdkmanager"
|
||||
AVDM="$SDK/cmdline-tools/latest/bin/avdmanager"
|
||||
AVD="${1:-jtubesc}"
|
||||
PORT=5600 # console port; adbd listens on 5601 (the container bridges 5556 -> 5601)
|
||||
PORT=5600
|
||||
IMAGE="system-images;android-36;android-tv;x86_64"
|
||||
|
||||
[ -x "$EMU" ] || { echo "emulator not found at $EMU"; exit 1; }
|
||||
[ -f "$HOME/.android/avd/$AVD.ini" ] || {
|
||||
echo "AVD $AVD not found; list: (ls ~/.android/avd)"; exit 1; }
|
||||
[ -x "$EMU" ] || { echo "emulator not found at $EMU — install Android SDK cmdline-tools first"; exit 1; }
|
||||
|
||||
# Free stale emulator instances holding our ports (only qemu from OUR SDK path).
|
||||
# --- bootstrap: java, system image, AVD -------------------------------------
|
||||
if ! command -v java >/dev/null; then
|
||||
echo "no java on PATH — required by sdkmanager/AVD tools"
|
||||
echo " install it (Arch): sudo pacman -S --noconfirm jdk21-openjdk"
|
||||
echo " then re-run this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! "$SDKM" --list_installed 2>/dev/null | grep -q "$IMAGE"; then
|
||||
echo "installing $IMAGE (~1.5 GB, once)…"
|
||||
yes | "$SDKM" "$IMAGE" > /dev/null
|
||||
echo "installed"
|
||||
fi
|
||||
|
||||
if [ ! -f "$HOME/.android/avd/$AVD.ini" ]; then
|
||||
echo "creating AVD '$AVD'…"
|
||||
echo no | "$AVDM" create avd -n "$AVD" -k "$IMAGE" -d tv_1080p > /dev/null
|
||||
fi
|
||||
|
||||
# --- free stale emulator instances holding our port --------------------------
|
||||
for pid in $(ps aux | awk '/[q]emu-system-x86_64/ {print $2}' 2>/dev/null); do
|
||||
if tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | grep -q "\-port $PORT"; then
|
||||
echo "Killing stale emulator pid $pid"
|
||||
|
|
@ -34,13 +55,20 @@ done
|
|||
sleep 1
|
||||
|
||||
ACCEL=()
|
||||
if [ -e /dev/kvm ]; then
|
||||
ACCEL+=(-accel kvm); echo "/dev/kvm found — hardware acceleration on"
|
||||
WINDOWED=1
|
||||
if [ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]; then
|
||||
echo "desktop session detected — emulator window + GPU host"
|
||||
else
|
||||
echo "no /dev/kvm — falling back to software rendering (slow)"
|
||||
WINDOWED=0
|
||||
ACCEL+=(-no-window)
|
||||
echo "headless (no display) — running without a window, swiftshader rendering"
|
||||
fi
|
||||
if [ -e /dev/kvm ]; then
|
||||
[ $WINDOWED -eq 1 ] && ACCEL+=(-accel kvm)
|
||||
echo "/dev/kvm found — hardware acceleration on"
|
||||
fi
|
||||
|
||||
echo "Booting AVD '$AVD' on console :$PORT (adbd :$((PORT+1))) …"
|
||||
echo "Booting AVD '$AVD' …"
|
||||
setsid nohup "$EMU" -avd "$AVD" -port "$PORT" -gpu host "${ACCEL[@]:-}" \
|
||||
-no-snapshot > /tmp/jtube-emu.log 2>&1 < /dev/null &
|
||||
echo "emulator PID $! — log: /tmp/jtube-emu.log"
|
||||
|
|
@ -51,6 +79,31 @@ for i in $(seq 1 90); do
|
|||
sleep 5
|
||||
done
|
||||
|
||||
# --- authorize remote adb clients headlessly ---------------------------------
|
||||
# The host console transport is always trusted; use it to whitelist client keys
|
||||
# so `adb connect rutherford:5556` from other machines works without a popup.
|
||||
# Drop extra public keys into /tmp/jtube-adbkeys/ (one per file), e.g. from
|
||||
# Chester: cat ~/.android/adbkey.pub > /tmp/jtube-adbkeys/chester.pub
|
||||
"$ADB" -s "emulator-$PORT" root > /dev/null 2>&1 || true
|
||||
for key_file in "$HOME/.android/adbkey.pub" /tmp/jtube-adbkeys/*.pub; do
|
||||
[ -f "$key_file" ] || continue
|
||||
"$ADB" -s "emulator-$PORT" push "$key_file" "/data/misc/adb/adb_keys" > /dev/null 2>&1 || \
|
||||
"$ADB" -s "emulator-$PORT" shell "cat > /data/misc/adb/adb_keys" < "$key_file" || {
|
||||
echo "could not whitelist $key_file";
|
||||
}
|
||||
done
|
||||
"$ADB" -s "emulator-$PORT" shell "setprop service.adb.tcp.port 5601; stop adbd; start adbd" > /dev/null 2>&1 || true
|
||||
|
||||
# --- the bridge: advertise adbd on the LAN as :5556 ---------------------------
|
||||
if ! ss -tln 2>/dev/null | grep -q ":5556"; then
|
||||
if command -v socat > /dev/null; then
|
||||
setsid nohup socat TCP-LISTEN:5556,bind=0.0.0.0,fork,reuseaddr TCP:127.0.0.1:$((PORT+1)) > /tmp/jtube-socat.log 2>&1 < /dev/null &
|
||||
echo "socat bridge listening on :5556 (pid $!)"
|
||||
else
|
||||
echo "install socat for the remote bridge: sudo pacman -S --noconfirm socat"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Keep the JTube TV app current + running so scrcpy lands on it.
|
||||
APK="$HOME/Projects/jtube-tv/app/build/outputs/apk/debug/app-debug.apk"
|
||||
if [ -f "$APK" ]; then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue