#!/usr/bin/env bash # lib/adb.sh — ADB wrapper functions for android-fs5 # shellcheck shell=bash # adb_check_device — validate device is connected; exit 2 if not adb_check_device() { local state state=$(adb -s "${DEVICE_SERIAL}" get-state 2>/dev/null || echo "offline") if [[ "${state}" != "device" ]]; then out_error "Device not found: ${DEVICE_SERIAL}" exit 2 fi } # adb_cmd ARGS... — run adb with the configured device serial adb_cmd() { adb -s "${DEVICE_SERIAL}" "$@" } # adb_get_prop KEY — read a device system property adb_get_prop() { local key="${1}" adb_cmd shell getprop "${key}" 2>/dev/null | tr -d '\r' } # adb_shell CMD — execute a shell command on the device adb_shell() { adb_cmd shell "$@" 2>&1 } # adb_file_exists DEVICE_PATH — return 0 if file exists on device, 1 otherwise adb_file_exists() { local path="${1}" local result result=$(adb_cmd shell "[ -e '${path}' ] && echo yes || echo no" 2>/dev/null | tr -d '\r') [[ "${result}" == "yes" ]] } # adb_push SRC DST [--force] — push local file to device # Skips if destination exists unless --force is set adb_push() { local src="${1}" local dst="${2}" local force="${3:-}" if [[ ! -e "${src}" ]]; then out_error "Source not found: ${src}" return 1 fi if adb_file_exists "${dst}" && [[ "${force}" != "--force" ]]; then out_warn "File exists on device, use --force to overwrite: ${dst}" return 0 fi adb_cmd push "${src}" "${dst}" local exit_code=$? if [[ ${exit_code} -eq 0 ]]; then adb_log_op "PUSH" "${src} -> ${dst}" out_success "Pushed: ${src} → ${dst}" else out_error "Push failed: ${src} → ${dst}" return 1 fi } # adb_pull SRC DST [--force] — pull file from device to local # Skips if local destination exists unless --force is set adb_pull() { local src="${1}" local dst="${2}" local force="${3:-}" if ! adb_file_exists "${src}"; then out_error "Source not found on device: ${src}" return 1 fi if [[ -e "${dst}" ]] && [[ "${force}" != "--force" ]]; then out_warn "Local file exists, use --force to overwrite: ${dst}" return 0 fi adb_cmd pull "${src}" "${dst}" local exit_code=$? if [[ ${exit_code} -eq 0 ]]; then adb_log_op "PULL" "${src} -> ${dst}" out_success "Pulled: ${src} → ${dst}" else out_error "Pull failed: ${src} → ${dst}" return 1 fi } # adb_log_op OPERATION DETAIL — append timestamped entry to LOG_FILE adb_log_op() { local op="${1}" local detail="${2}" local ts ts=$(date -Iseconds) echo "${ts} ${op} ${detail} [OK]" >> "${LOG_FILE:-./fs5.log}" } # adb_battery_level — return battery percentage as integer adb_battery_level() { adb_cmd shell dumpsys battery 2>/dev/null \ | grep -E '^\s+level:' \ | awk '{print $2}' \ | tr -d '\r' } # adb_battery_charging — return true/false string adb_battery_charging() { local status status=$(adb_cmd shell dumpsys battery 2>/dev/null \ | grep -E '^\s+status:' \ | awk '{print $2}' \ | tr -d '\r') # status 2 = charging if [[ "${status}" == "2" ]]; then echo "true" else echo "false" fi } # adb_storage_info — echo space-separated: total_kb used_kb free_kb percent_used adb_storage_info() { adb_cmd shell df /sdcard 2>/dev/null \ | tail -1 \ | awk '{print $2, $3, $4, $5}' \ | tr -d '\r%' }