run_emulator.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. #!/bin/bash
  2. # ZenTap Android Emulator Launcher (Bash Version)
  3. # Simple script to launch ZenTap in Android emulator with resolution selection
  4. set -e
  5. # Colors for output
  6. RED='\033[0;31m'
  7. GREEN='\033[0;32m'
  8. YELLOW='\033[0;33m'
  9. BLUE='\033[0;34m'
  10. NC='\033[0m' # No Color
  11. # Script directory and project root
  12. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  13. PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
  14. # Find Android SDK
  15. find_android_sdk() {
  16. local paths=(
  17. "$ANDROID_SDK_ROOT"
  18. "$ANDROID_HOME"
  19. "$HOME/Android/Sdk"
  20. "$HOME/Library/Android/sdk"
  21. "/opt/android-sdk"
  22. "/usr/local/android-sdk"
  23. )
  24. for path in "${paths[@]}"; do
  25. if [[ -n "$path" && -d "$path" ]]; then
  26. echo "$path"
  27. return 0
  28. fi
  29. done
  30. return 1
  31. }
  32. # Print colored output
  33. print_status() {
  34. echo -e "${BLUE}[INFO]${NC} $1"
  35. }
  36. print_success() {
  37. echo -e "${GREEN}[SUCCESS]${NC} $1"
  38. }
  39. print_error() {
  40. echo -e "${RED}[ERROR]${NC} $1"
  41. }
  42. print_warning() {
  43. echo -e "${YELLOW}[WARNING]${NC} $1"
  44. }
  45. # Check prerequisites
  46. check_prerequisites() {
  47. print_status "Checking prerequisites..."
  48. # Check Flutter
  49. if ! command -v flutter &> /dev/null; then
  50. print_error "Flutter not found in PATH"
  51. exit 1
  52. fi
  53. # Check Android SDK
  54. if ! ANDROID_SDK=$(find_android_sdk); then
  55. print_error "Android SDK not found"
  56. print_error "Please install Android SDK and set ANDROID_SDK_ROOT or ANDROID_HOME"
  57. exit 1
  58. fi
  59. # Check emulator
  60. EMULATOR_PATH="$ANDROID_SDK/emulator/emulator"
  61. if [[ ! -f "$EMULATOR_PATH" ]]; then
  62. print_error "Android emulator not found at $EMULATOR_PATH"
  63. exit 1
  64. fi
  65. # Check ADB
  66. if ! command -v adb &> /dev/null; then
  67. print_error "ADB not found in PATH"
  68. exit 1
  69. fi
  70. print_success "All prerequisites satisfied"
  71. }
  72. # Show resolution menu
  73. show_resolution_menu() {
  74. echo
  75. echo "=== ZenTap Android Emulator Launcher ==="
  76. echo
  77. echo "Select target resolution:"
  78. echo " 1) Phone Small (360x640)"
  79. echo " 2) Phone Medium (411x731)"
  80. echo " 3) Phone Large (414x896)"
  81. echo " 4) Tablet 7\" (600x960)"
  82. echo " 5) Tablet 10\" (800x1280)"
  83. echo " 6) Foldable (673x841)"
  84. echo " 7) Desktop (1920x1080)"
  85. echo " 8) Custom resolution"
  86. echo
  87. }
  88. # Get resolution choice
  89. get_resolution() {
  90. while true; do
  91. read -p "Enter choice (1-8): " choice
  92. case $choice in
  93. 1) WIDTH=360; HEIGHT=640; RESOLUTION_NAME="Phone_Small"; break ;;
  94. 2) WIDTH=411; HEIGHT=731; RESOLUTION_NAME="Phone_Medium"; break ;;
  95. 3) WIDTH=414; HEIGHT=896; RESOLUTION_NAME="Phone_Large"; break ;;
  96. 4) WIDTH=600; HEIGHT=960; RESOLUTION_NAME="Tablet_7"; break ;;
  97. 5) WIDTH=800; HEIGHT=1280; RESOLUTION_NAME="Tablet_10"; break ;;
  98. 6) WIDTH=673; HEIGHT=841; RESOLUTION_NAME="Foldable"; break ;;
  99. 7) WIDTH=1920; HEIGHT=1080; RESOLUTION_NAME="Desktop"; break ;;
  100. 8)
  101. read -p "Enter width: " WIDTH
  102. read -p "Enter height: " HEIGHT
  103. RESOLUTION_NAME="Custom"
  104. if ! [[ "$WIDTH" =~ ^[0-9]+$ ]] || ! [[ "$HEIGHT" =~ ^[0-9]+$ ]]; then
  105. print_error "Invalid resolution values"
  106. continue
  107. fi
  108. break ;;
  109. *) print_error "Invalid choice" ;;
  110. esac
  111. done
  112. }
  113. # Get additional options
  114. get_options() {
  115. echo
  116. read -p "Cold boot (wipe data)? (y/N): " cold_boot
  117. [[ "$cold_boot" =~ ^[Yy] ]] && COLD_BOOT=true || COLD_BOOT=false
  118. read -p "Build mode (debug/release) [debug]: " build_mode
  119. BUILD_MODE="${build_mode:-debug}"
  120. read -p "Auto-launch app? (Y/n): " auto_launch
  121. [[ "$auto_launch" =~ ^[Nn] ]] && AUTO_LAUNCH=false || AUTO_LAUNCH=true
  122. }
  123. # List available AVDs
  124. list_avds() {
  125. print_status "Available AVDs:"
  126. "$EMULATOR_PATH" -list-avds | while read -r avd; do
  127. echo " - $avd"
  128. done
  129. }
  130. # Create AVD if it doesn't exist
  131. ensure_avd() {
  132. local avd_name="$1"
  133. if "$EMULATOR_PATH" -list-avds | grep -q "^$avd_name$"; then
  134. print_status "Using existing AVD: $avd_name"
  135. return 0
  136. fi
  137. print_status "Creating new AVD: $avd_name"
  138. # Try to find avdmanager
  139. local avdmanager_paths=(
  140. "$ANDROID_SDK/cmdline-tools/latest/bin/avdmanager"
  141. "$ANDROID_SDK/tools/bin/avdmanager"
  142. )
  143. local avdmanager=""
  144. for path in "${avdmanager_paths[@]}"; do
  145. if [[ -f "$path" ]]; then
  146. avdmanager="$path"
  147. break
  148. fi
  149. done
  150. if [[ -z "$avdmanager" ]]; then
  151. print_warning "avdmanager not found, using existing AVD"
  152. local existing_avds=($("$EMULATOR_PATH" -list-avds))
  153. if [[ ${#existing_avds[@]} -gt 0 ]]; then
  154. AVD_NAME="${existing_avds[0]}"
  155. print_status "Using first available AVD: $AVD_NAME"
  156. return 0
  157. else
  158. print_error "No AVDs available and cannot create new one"
  159. return 1
  160. fi
  161. fi
  162. # Create AVD
  163. echo "no" | "$avdmanager" create avd \
  164. -n "$avd_name" \
  165. -k "system-images;android-34;google_apis;x86_64" \
  166. -d "pixel" \
  167. --force >/dev/null 2>&1 || {
  168. print_warning "Failed to create AVD, will use existing one if available"
  169. return 1
  170. }
  171. print_success "AVD created: $avd_name"
  172. }
  173. # Launch emulator
  174. launch_emulator() {
  175. local avd_name="$1"
  176. print_status "Starting emulator: $avd_name"
  177. print_status "Resolution: ${WIDTH}x${HEIGHT}"
  178. local cmd=("$EMULATOR_PATH" -avd "$avd_name")
  179. # Add resolution
  180. cmd+=(-skin "${WIDTH}x${HEIGHT}")
  181. # Add performance options
  182. cmd+=(-gpu host -no-boot-anim -memory 2048)
  183. # Add cold boot if requested
  184. if [[ "$COLD_BOOT" == "true" ]]; then
  185. cmd+=(-wipe-data)
  186. print_status "Cold boot enabled (wiping data)"
  187. fi
  188. print_status "Emulator command: ${cmd[*]}"
  189. # Start emulator in background
  190. "${cmd[@]}" &>/dev/null &
  191. local emulator_pid=$!
  192. # Wait a bit for emulator to start
  193. sleep 5
  194. # Check if emulator process is still running
  195. if ! kill -0 $emulator_pid 2>/dev/null; then
  196. print_error "Failed to start emulator"
  197. return 1
  198. fi
  199. print_success "Emulator started (PID: $emulator_pid)"
  200. return 0
  201. }
  202. # Wait for emulator to boot
  203. wait_for_emulator() {
  204. print_status "Waiting for emulator to boot..."
  205. local max_wait=120
  206. local elapsed=0
  207. while [[ $elapsed -lt $max_wait ]]; do
  208. if adb shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; then
  209. print_success "Emulator is ready!"
  210. return 0
  211. fi
  212. echo -n "."
  213. sleep 2
  214. ((elapsed += 2))
  215. done
  216. echo
  217. print_error "Timeout waiting for emulator to boot"
  218. return 1
  219. }
  220. # Build app
  221. build_app() {
  222. print_status "Building app in $BUILD_MODE mode..."
  223. cd "$PROJECT_ROOT"
  224. local build_cmd=(flutter build apk)
  225. if [[ "$BUILD_MODE" == "debug" ]]; then
  226. build_cmd+=(--debug)
  227. elif [[ "$BUILD_MODE" == "release" ]]; then
  228. build_cmd+=(--release)
  229. fi
  230. if "${build_cmd[@]}"; then
  231. print_success "Build completed successfully"
  232. return 0
  233. else
  234. print_error "Build failed"
  235. return 1
  236. fi
  237. }
  238. # Install app
  239. install_app() {
  240. print_status "Installing app on emulator..."
  241. local apk_path
  242. if [[ "$BUILD_MODE" == "debug" ]]; then
  243. apk_path="$PROJECT_ROOT/build/app/outputs/flutter-apk/app-debug.apk"
  244. else
  245. apk_path="$PROJECT_ROOT/build/app/outputs/flutter-apk/app-release.apk"
  246. fi
  247. if [[ ! -f "$apk_path" ]]; then
  248. print_error "APK not found: $apk_path"
  249. return 1
  250. fi
  251. if adb install -r "$apk_path"; then
  252. print_success "App installed successfully"
  253. return 0
  254. else
  255. print_error "Installation failed"
  256. return 1
  257. fi
  258. }
  259. # Launch app
  260. launch_app() {
  261. print_status "Launching ZenTap..."
  262. if adb shell am start -n "hu.fsociety.zentap/hu.fsociety.zentap.MainActivity"; then
  263. print_success "App launched successfully!"
  264. return 0
  265. else
  266. print_error "Failed to launch app"
  267. return 1
  268. fi
  269. }
  270. # Main execution
  271. main() {
  272. # Parse command line arguments
  273. while [[ $# -gt 0 ]]; do
  274. case $1 in
  275. --list-avds|-l)
  276. check_prerequisites
  277. list_avds
  278. exit 0
  279. ;;
  280. --width|-w)
  281. WIDTH="$2"
  282. shift 2
  283. ;;
  284. --height)
  285. HEIGHT="$2"
  286. shift 2
  287. ;;
  288. --avd|-a)
  289. AVD_NAME="$2"
  290. shift 2
  291. ;;
  292. --cold-boot|-c)
  293. COLD_BOOT=true
  294. shift
  295. ;;
  296. --build-mode|-b)
  297. BUILD_MODE="$2"
  298. shift 2
  299. ;;
  300. --no-launch)
  301. AUTO_LAUNCH=false
  302. shift
  303. ;;
  304. --help)
  305. echo "Usage: $0 [OPTIONS]"
  306. echo "Options:"
  307. echo " --list-avds, -l List available AVDs"
  308. echo " --width, -w WIDTH Set width"
  309. echo " --height HEIGHT Set height"
  310. echo " --avd, -a NAME Use specific AVD"
  311. echo " --cold-boot, -c Cold boot (wipe data)"
  312. echo " --build-mode, -b debug|release"
  313. echo " --no-launch Don't auto-launch app"
  314. echo " --help Show this help"
  315. exit 0
  316. ;;
  317. *)
  318. print_error "Unknown option: $1"
  319. exit 1
  320. ;;
  321. esac
  322. done
  323. # Check prerequisites
  324. check_prerequisites
  325. # Interactive mode if no resolution specified
  326. if [[ -z "$WIDTH" || -z "$HEIGHT" ]]; then
  327. show_resolution_menu
  328. get_resolution
  329. get_options
  330. fi
  331. # Set defaults
  332. AVD_NAME="${AVD_NAME:-ZenTap_${RESOLUTION_NAME}_${WIDTH}x${HEIGHT}}"
  333. BUILD_MODE="${BUILD_MODE:-debug}"
  334. AUTO_LAUNCH="${AUTO_LAUNCH:-true}"
  335. COLD_BOOT="${COLD_BOOT:-false}"
  336. # Create/ensure AVD exists
  337. ensure_avd "$AVD_NAME"
  338. # Launch emulator
  339. if ! launch_emulator "$AVD_NAME"; then
  340. exit 1
  341. fi
  342. # Wait for emulator to boot
  343. if ! wait_for_emulator; then
  344. exit 1
  345. fi
  346. # Build app
  347. if ! build_app; then
  348. exit 1
  349. fi
  350. # Install app
  351. if ! install_app; then
  352. exit 1
  353. fi
  354. # Launch app if requested
  355. if [[ "$AUTO_LAUNCH" == "true" ]]; then
  356. launch_app
  357. fi
  358. echo
  359. print_success "=== ZenTap is ready! ==="
  360. echo "Emulator: $AVD_NAME (${WIDTH}x${HEIGHT})"
  361. echo "Build mode: $BUILD_MODE"
  362. if [[ "$AUTO_LAUNCH" == "true" ]]; then
  363. echo "App: Launched automatically"
  364. else
  365. echo "App: Ready to launch manually"
  366. fi
  367. echo
  368. echo "Press Ctrl+C to stop the emulator when done."
  369. # Keep script running and handle cleanup
  370. trap 'echo; print_status "Stopping emulator..."; adb emu kill >/dev/null 2>&1; print_success "Emulator stopped."; exit 0' INT
  371. # Monitor emulator
  372. while true; do
  373. if ! adb devices | grep -q "emulator"; then
  374. print_warning "Emulator connection lost"
  375. break
  376. fi
  377. sleep 5
  378. done
  379. }
  380. # Run main function
  381. main "$@"