# start-emulators.ps1 # Lance Pixel_5 (emulator-5554) et Pixel_5_2 (emulator-5556) puis Flutter sur chacun. $emulatorExe = "$env:LOCALAPPDATA\Android\Sdk\emulator\emulator.exe" $avds = @("Pixel_5", "Pixel_5_2") $devices = @("emulator-5554", "emulator-5556") $flutterEnv = "ENV=dev" $bootTimeoutSec = 120 $dir = Split-Path -Parent (Resolve-Path $MyInvocation.MyCommand.Path) # --- Helpers ---------------------------------------------------------------- function Is-EmulatorRunning($device) { $list = adb devices 2>$null return ($list -match "^$device\s+device") } function Wait-BootCompleted($device, $timeoutSec) { $deadline = (Get-Date).AddSeconds($timeoutSec) do { if ((Get-Date) -gt $deadline) { Write-Host " TIMEOUT : $device n'a pas boote en ${timeoutSec}s." -ForegroundColor Red return $false } Start-Sleep -Seconds 2 $val = (adb -s $device shell getprop sys.boot_completed 2>$null).Trim() } while ($val -ne "1") return $true } # --- 1. Lancer uniquement les emulateurs non demarres ---------------------- for ($i = 0; $i -lt 2; $i++) { $avd = $avds[$i] $device = $devices[$i] if (Is-EmulatorRunning $device) { Write-Host ">>> $avd ($device) deja demarre, skip." -ForegroundColor Cyan } else { Write-Host ">>> Demarrage de $avd..." Start-Process $emulatorExe -ArgumentList "-avd $avd -gpu swiftshader_indirect -no-snapshot-load -no-audio" } } # --- 2. Attendre le boot en parallele -------------------------------------- Write-Host ">>> Attente du boot..." $jobs = $devices | ForEach-Object { $d = $_ Start-Job -ScriptBlock { param($device, $timeout) $deadline = (Get-Date).AddSeconds($timeout) adb -s $device wait-for-device 2>$null do { if ((Get-Date) -gt $deadline) { return "TIMEOUT:$device" } Start-Sleep -Seconds 2 $val = (adb -s $device shell getprop sys.boot_completed 2>$null).Trim() } while ($val -ne "1") return "OK:$device" } -ArgumentList $d, $bootTimeoutSec } $results = $jobs | Wait-Job | Receive-Job $jobs | Remove-Job foreach ($r in $results) { if ($r -like "TIMEOUT:*") { Write-Host " TIMEOUT : $($r.Split(':')[1])" -ForegroundColor Red exit 1 } Write-Host " OK : $($r.Split(':')[1]) pret." -ForegroundColor Green } # --- 3. ADB reverse : localhost sur l'emulateur → host machine --------------- Write-Host ">>> Configuration ADB reverse port forwarding..." foreach ($device in $devices) { adb -s $device reverse tcp:8085 tcp:8085 2>$null # API backend adb -s $device reverse tcp:8180 tcp:8180 2>$null # Keycloak Write-Host " $device : ports 8085 et 8180 forwarded." -ForegroundColor Green } # --- 5. Flutter pub get (restaure le cache pub si nécessaire) -------------- Write-Host "" Write-Host ">>> flutter pub get..." -ForegroundColor Yellow Push-Location $dir flutter pub get Pop-Location # --- 6. Pré-build Gradle sur le premier device (évite le lock parallèle) --- Write-Host "" Write-Host ">>> Pre-build Gradle sur $($devices[0])..." -ForegroundColor Yellow Push-Location $dir flutter build apk --debug --dart-define=$flutterEnv | Out-Null Pop-Location Write-Host ">>> Pre-build termine." -ForegroundColor Green # --- 7. Flutter sur chaque emulateur (EncodedCommand — bulletproof) -------- Write-Host "" Write-Host ">>> Lancement Flutter..." -ForegroundColor Yellow foreach ($device in $devices) { $script = @" `$host.UI.RawUI.WindowTitle = 'Flutter - $device' Write-Host 'Device : $device' -ForegroundColor Cyan Write-Host 'Dossier: $dir' -ForegroundColor Cyan Write-Host '' Set-Location '$dir' flutter run -d $device --dart-define=$flutterEnv --no-pub Write-Host '' Write-Host 'Flutter termine. Fermeture manuelle uniquement.' -ForegroundColor Yellow Read-Host 'Appuyer sur Entree pour fermer' "@ $bytes = [System.Text.Encoding]::Unicode.GetBytes($script) $encoded = [Convert]::ToBase64String($bytes) Start-Process powershell -ArgumentList "-ExecutionPolicy","Bypass","-NoExit","-EncodedCommand",$encoded Start-Sleep -Seconds 5 } Write-Host "Done. Deux fenetres PowerShell ouvertes."