run_emulator.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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) Ulefone Armor 30 (2460x1080)"
  85. echo " 8) Desktop (1920x1080)"
  86. echo " 9) Custom resolution"
  87. echo
  88. }
  89. # Get resolution choice
  90. get_resolution() {
  91. while true; do
  92. read -p "Enter choice (1-9): " choice
  93. case $choice in
  94. 1) WIDTH=360; HEIGHT=640; RESOLUTION_NAME="Phone_Small"; DPI=160; break ;;
  95. 2) WIDTH=411; HEIGHT=731; RESOLUTION_NAME="Phone_Medium"; DPI=240; break ;;
  96. 3) WIDTH=414; HEIGHT=896; RESOLUTION_NAME="Phone_Large"; DPI=320; break ;;
  97. 4) WIDTH=600; HEIGHT=960; RESOLUTION_NAME="Tablet_7"; DPI=213; break ;;
  98. 5) WIDTH=800; HEIGHT=1280; RESOLUTION_NAME="Tablet_10"; DPI=149; break ;;
  99. 6) WIDTH=673; HEIGHT=841; RESOLUTION_NAME="Foldable"; DPI=420; break ;;
  100. 7) WIDTH=2460; HEIGHT=1080; RESOLUTION_NAME="Ulefone_Armor30"; DPI=400; break ;;
  101. 8) WIDTH=1920; HEIGHT=1080; RESOLUTION_NAME="Desktop"; DPI=160; break ;;
  102. 9)
  103. read -p "Enter width: " WIDTH
  104. read -p "Enter height: " HEIGHT
  105. read -p "Enter DPI [320]: " custom_dpi
  106. DPI="${custom_dpi:-320}"
  107. RESOLUTION_NAME="Custom"
  108. if ! [[ "$WIDTH" =~ ^[0-9]+$ ]] || ! [[ "$HEIGHT" =~ ^[0-9]+$ ]] || ! [[ "$DPI" =~ ^[0-9]+$ ]]; then
  109. print_error "Invalid resolution or DPI values"
  110. continue
  111. fi
  112. break ;;
  113. *) print_error "Invalid choice" ;;
  114. esac
  115. done
  116. }
  117. # Get additional options
  118. get_options() {
  119. echo
  120. read -p "Cold boot (wipe data)? (y/N): " cold_boot
  121. [[ "$cold_boot" =~ ^[Yy] ]] && COLD_BOOT=true || COLD_BOOT=false
  122. read -p "Build mode (debug/release) [debug]: " build_mode
  123. BUILD_MODE="${build_mode:-debug}"
  124. read -p "Auto-launch app? (Y/n): " auto_launch
  125. [[ "$auto_launch" =~ ^[Nn] ]] && AUTO_LAUNCH=false || AUTO_LAUNCH=true
  126. }
  127. # List available AVDs
  128. list_avds() {
  129. print_status "Available AVDs:"
  130. "$EMULATOR_PATH" -list-avds | while read -r avd; do
  131. echo " - $avd"
  132. done
  133. }
  134. # Create AVD if it doesn't exist
  135. ensure_avd() {
  136. local avd_name="$1"
  137. if "$EMULATOR_PATH" -list-avds | grep -q "^$avd_name$"; then
  138. print_status "Using existing AVD: $avd_name"
  139. return 0
  140. fi
  141. print_status "Creating new AVD: $avd_name"
  142. # Try to find avdmanager
  143. local avdmanager_paths=(
  144. "$ANDROID_SDK/cmdline-tools/latest/bin/avdmanager"
  145. "$ANDROID_SDK/tools/bin/avdmanager"
  146. )
  147. local avdmanager=""
  148. for path in "${avdmanager_paths[@]}"; do
  149. if [[ -f "$path" ]]; then
  150. avdmanager="$path"
  151. break
  152. fi
  153. done
  154. if [[ -z "$avdmanager" ]]; then
  155. print_warning "avdmanager not found, using existing AVD"
  156. local existing_avds=($("$EMULATOR_PATH" -list-avds))
  157. if [[ ${#existing_avds[@]} -gt 0 ]]; then
  158. AVD_NAME="${existing_avds[0]}"
  159. print_status "Using first available AVD: $AVD_NAME"
  160. return 0
  161. else
  162. print_error "No AVDs available and cannot create new one"
  163. return 1
  164. fi
  165. fi
  166. # Create AVD
  167. echo "no" | "$avdmanager" create avd \
  168. -n "$avd_name" \
  169. -k "system-images;android-34;google_apis;x86_64" \
  170. -d "pixel" \
  171. --force >/dev/null 2>&1 || {
  172. print_warning "Failed to create AVD, will use existing one if available"
  173. return 1
  174. }
  175. print_success "AVD created: $avd_name"
  176. }
  177. # Launch emulator
  178. launch_emulator() {
  179. local avd_name="$1"
  180. print_status "Starting emulator: $avd_name"
  181. print_status "Resolution: ${WIDTH}x${HEIGHT} @ ${DPI}dpi"
  182. local cmd=("$EMULATOR_PATH" -avd "$avd_name")
  183. # Add resolution and DPI settings
  184. cmd+=(-skin "${WIDTH}x${HEIGHT}")
  185. cmd+=(-skindir "$ANDROID_SDK/platforms/android-34/skins")
  186. # Add performance options
  187. cmd+=(-gpu host -no-boot-anim -memory 2048)
  188. # Add DPI scaling
  189. cmd+=(-scale 1.0)
  190. # Add cold boot if requested
  191. if [[ "$COLD_BOOT" == "true" ]]; then
  192. cmd+=(-wipe-data)
  193. print_status "Cold boot enabled (wiping data)"
  194. fi
  195. print_status "Emulator command: ${cmd[*]}"
  196. # Start emulator in background
  197. "${cmd[@]}" &>/dev/null &
  198. local emulator_pid=$!
  199. # Wait a bit for emulator to start
  200. sleep 5
  201. # Check if emulator process is still running
  202. if ! kill -0 $emulator_pid 2>/dev/null; then
  203. print_error "Failed to start emulator"
  204. return 1
  205. fi
  206. print_success "Emulator started (PID: $emulator_pid)"
  207. return 0
  208. }
  209. # Wait for emulator to boot
  210. wait_for_emulator() {
  211. print_status "Waiting for emulator to boot..."
  212. local max_wait=120
  213. local elapsed=0
  214. while [[ $elapsed -lt $max_wait ]]; do
  215. if adb shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; then
  216. print_success "Emulator is ready!"
  217. return 0
  218. fi
  219. echo -n "."
  220. sleep 2
  221. ((elapsed += 2))
  222. done
  223. echo
  224. print_error "Timeout waiting for emulator to boot"
  225. return 1
  226. }
  227. # Build app
  228. build_app() {
  229. print_status "Building app in $BUILD_MODE mode..."
  230. cd "$PROJECT_ROOT"
  231. local build_cmd=(flutter build apk)
  232. if [[ "$BUILD_MODE" == "debug" ]]; then
  233. build_cmd+=(--debug)
  234. elif [[ "$BUILD_MODE" == "release" ]]; then
  235. build_cmd+=(--release)
  236. fi
  237. if "${build_cmd[@]}"; then
  238. print_success "Build completed successfully"
  239. return 0
  240. else
  241. print_error "Build failed"
  242. return 1
  243. fi
  244. }
  245. # Install app
  246. install_app() {
  247. print_status "Installing app on emulator..."
  248. local apk_path
  249. if [[ "$BUILD_MODE" == "debug" ]]; then
  250. apk_path="$PROJECT_ROOT/build/app/outputs/flutter-apk/app-debug.apk"
  251. else
  252. apk_path="$PROJECT_ROOT/build/app/outputs/flutter-apk/app-release.apk"
  253. fi
  254. if [[ ! -f "$apk_path" ]]; then
  255. print_error "APK not found: $apk_path"
  256. return 1
  257. fi
  258. if adb install -r "$apk_path"; then
  259. print_success "App installed successfully"
  260. return 0
  261. else
  262. print_error "Installation failed"
  263. return 1
  264. fi
  265. }
  266. # Launch app
  267. launch_app() {
  268. print_status "Launching ZenTap..."
  269. if adb shell am start -n "hu.fsociety.zentap/hu.fsociety.zentap.MainActivity"; then
  270. print_success "App launched successfully!"
  271. return 0
  272. else
  273. print_error "Failed to launch app"
  274. return 1
  275. fi
  276. }
  277. # Main execution
  278. main() {
  279. # Parse command line arguments
  280. while [[ $# -gt 0 ]]; do
  281. case $1 in
  282. --list-avds|-l)
  283. check_prerequisites
  284. list_avds
  285. exit 0
  286. ;;
  287. --width|-w)
  288. WIDTH="$2"
  289. shift 2
  290. ;;
  291. --height)
  292. HEIGHT="$2"
  293. shift 2
  294. ;;
  295. --dpi)
  296. DPI="$2"
  297. shift 2
  298. ;;
  299. --avd|-a)
  300. AVD_NAME="$2"
  301. shift 2
  302. ;;
  303. --cold-boot|-c)
  304. COLD_BOOT=true
  305. shift
  306. ;;
  307. --build-mode|-b)
  308. BUILD_MODE="$2"
  309. shift 2
  310. ;;
  311. --no-launch)
  312. AUTO_LAUNCH=false
  313. shift
  314. ;;
  315. --help)
  316. echo "Usage: $0 [OPTIONS]"
  317. echo "Options:"
  318. echo " --list-avds, -l List available AVDs"
  319. echo " --width, -w WIDTH Set width"
  320. echo " --height HEIGHT Set height"
  321. echo " --dpi DPI Set DPI (default: 320)"
  322. echo " --avd, -a NAME Use specific AVD"
  323. echo " --cold-boot, -c Cold boot (wipe data)"
  324. echo " --build-mode, -b debug|release"
  325. echo " --no-launch Don't auto-launch app"
  326. echo " --help Show this help"
  327. exit 0
  328. ;;
  329. *)
  330. print_error "Unknown option: $1"
  331. exit 1
  332. ;;
  333. esac
  334. done
  335. # Check prerequisites
  336. check_prerequisites
  337. # Interactive mode if no resolution specified
  338. if [[ -z "$WIDTH" || -z "$HEIGHT" ]]; then
  339. show_resolution_menu
  340. get_resolution
  341. get_options
  342. fi
  343. # Set defaults
  344. DPI="${DPI:-320}"
  345. AVD_NAME="${AVD_NAME:-ZenTap_${RESOLUTION_NAME}_${WIDTH}x${HEIGHT}}"
  346. BUILD_MODE="${BUILD_MODE:-debug}"
  347. AUTO_LAUNCH="${AUTO_LAUNCH:-true}"
  348. COLD_BOOT="${COLD_BOOT:-false}"
  349. # Create/ensure AVD exists
  350. ensure_avd "$AVD_NAME"
  351. # Launch emulator
  352. if ! launch_emulator "$AVD_NAME"; then
  353. exit 1
  354. fi
  355. # Wait for emulator to boot
  356. if ! wait_for_emulator; then
  357. exit 1
  358. fi
  359. # Build app
  360. if ! build_app; then
  361. exit 1
  362. fi
  363. # Install app
  364. if ! install_app; then
  365. exit 1
  366. fi
  367. # Launch app if requested
  368. if [[ "$AUTO_LAUNCH" == "true" ]]; then
  369. launch_app
  370. fi
  371. echo
  372. print_success "=== ZenTap is ready! ==="
  373. echo "Emulator: $AVD_NAME (${WIDTH}x${HEIGHT} @ ${DPI}dpi)"
  374. echo "Build mode: $BUILD_MODE"
  375. if [[ "$AUTO_LAUNCH" == "true" ]]; then
  376. echo "App: Launched automatically"
  377. else
  378. echo "App: Ready to launch manually"
  379. fi
  380. echo
  381. echo "Press Ctrl+C to stop the emulator when done."
  382. # Keep script running and handle cleanup
  383. trap 'echo; print_status "Stopping emulator..."; adb emu kill >/dev/null 2>&1; print_success "Emulator stopped."; exit 0' INT
  384. # Monitor emulator
  385. while true; do
  386. if ! adb devices | grep -q "emulator"; then
  387. print_warning "Emulator connection lost"
  388. break
  389. fi
  390. sleep 5
  391. done
  392. }
  393. # Run main function
  394. main "$@"