diff --git a/tools/android/exercise-content.ps1 b/tools/android/exercise-content.ps1 index a31c8e7..335da7b 100644 --- a/tools/android/exercise-content.ps1 +++ b/tools/android/exercise-content.ps1 @@ -9,8 +9,8 @@ $result=[ordered]@{milestone='Content';sourceCommit=(& git rev-parse HEAD);sourc $result.rendererProjection=@{fieldOfView=62;fixedWorldPivot=@(0,.65,0);rawCamera='Saved Board.camera JSON remains canonical';viewport='Landscape wm size max/min; remaining UI and physical touch helper assume sole 2400x1080 AVD'} $networkBefore=$null; $musicBefore=$null function Adb([string[]]$Arguments) { - $output=& $adb -s $Serial @Arguments 2>&1; $code=$LASTEXITCODE - $commands.Add(@{command=('adb -s '+$Serial+' '+($Arguments -join ' '));exitCode=$code;output=($output -join "`n")}) + $started=[DateTime]::UtcNow.ToString('o'); $output=& $adb -s $Serial @Arguments 2>&1; $code=$LASTEXITCODE + $commands.Add(@{startedUtc=$started;finishedUtc=[DateTime]::UtcNow.ToString('o');command=('adb -s '+$Serial+' '+($Arguments -join ' '));exitCode=$code;output=($output -join "`n")}) if ($code -ne 0) { throw "ADB exit $code : $($Arguments -join ' ')" }; return ($output -join "`n").Trim() } function Check([string]$Id,[bool]$Passed,[string]$Actual) { @@ -136,7 +136,12 @@ try { Adb @('install','-r',$ApkPath) | Out-Null; Adb @('logcat','-c') | Out-Null; Adb @('shell','pm','clear',$package) | Out-Null $networkBefore=@{airplane=(Adb @('shell','settings','get','global','airplane_mode_on'));wifi=(Adb @('shell','settings','get','global','wifi_on'));data=(Adb @('shell','settings','get','global','mobile_data'))}; $result.networkBefore=$networkBefore Adb @('shell','cmd','connectivity','airplane-mode','enable') | Out-Null; Adb @('shell','svc','wifi','disable') | Out-Null; Adb @('shell','svc','data','disable') | Out-Null - Check 'offline-real-network' ((Adb @('shell','settings','get','global','airplane_mode_on')) -eq '1' -and (Adb @('shell','settings','get','global','wifi_on')) -eq '0' -and (Adb @('shell','settings','get','global','mobile_data')) -eq '0' -and (Adb @('shell','dumpsys','connectivity')) -match 'Active default network: none') 'airplane1 wifi0 data0 no active default network' + $offline=$false + for ($attempt=0; $attempt -lt 30; $attempt++) { + $offline=(Adb @('shell','settings','get','global','airplane_mode_on')) -eq '1' -and (Adb @('shell','settings','get','global','wifi_on')) -eq '0' -and (Adb @('shell','settings','get','global','mobile_data')) -eq '0' -and (Adb @('shell','dumpsys','connectivity')) -match 'Active default network: none' + if ($offline) { break }; Start-Sleep -Milliseconds 500 + } + Check 'offline-real-network' $offline 'airplane1 wifi0 data0 no active default network' StartHome 'fresh-home'; Step 'fresh-30-selection' @('shell','input','tap','1200','616') $two=StagePoint 2; Step 'fresh-locked-two' @('shell','input','tap',"$($two[0])","$($two[1])") $locked=Save 'fresh-locked'; Check 'fresh-only-one' ($locked.completedStageIds.Count -eq 0 -and $locked.puzzleStates.Count -eq 0) 'Locked Stage2 tap opens no puzzle' @@ -208,7 +213,21 @@ try { } catch { $result.error=$_.Exception.Message; Write-Host $result.error -ForegroundColor Red } finally { foreach ($recorder in $recorders) { - if (!$recorder.process.HasExited -and !$recorder.process.WaitForExit(($recorder.seconds+30)*1000)) { $result.status='failed'; $result.recorderError='Recorder did not finish before restoration' } + if (!$recorder.process.HasExited -and !$recorder.process.WaitForExit(($recorder.seconds+30)*1000)) { + $result.status='failed'; $result.recorderError='Recorder exceeded completion bound; own native process stopped before restoration' + $ready=Get-Content -LiteralPath (Join-Path $EvidenceDir "$($recorder.name).wav.ready.json") -Raw | ConvertFrom-Json + $native=Get-Process -Id $ready.recorderPid -ErrorAction SilentlyContinue + if ($native) { $native.Kill(); $native.WaitForExit() } + $recorder.process.WaitForExit(10000) | Out-Null + if (!$recorder.process.HasExited) { $recorder.process.Kill(); $recorder.process.WaitForExit() } + } + $readyPath=Join-Path $EvidenceDir "$($recorder.name).wav.ready.json" + if (Test-Path -LiteralPath $readyPath) { + $ready=Get-Content -LiteralPath $readyPath -Raw | ConvertFrom-Json + $native=Get-Process -Id $ready.recorderPid -ErrorAction SilentlyContinue + if ($native) { $native.WaitForExit() } + $commands.Add(@{command='recorder termination boundary';recorderPid=$ready.recorderPid;wrapperPid=$recorder.process.Id;nativeExited=$true;wrapperExited=$recorder.process.HasExited;utc=[DateTime]::UtcNow.ToString('o')}) + } } if ($musicBefore) { try { @@ -226,7 +245,10 @@ finally { Adb @('shell','cmd','connectivity','airplane-mode',$(if ($networkBefore.airplane -eq '1') {'enable'} else {'disable'})) | Out-Null Adb @('shell','svc','wifi',$(if ($networkBefore.wifi -eq '1') {'enable'} else {'disable'})) | Out-Null Adb @('shell','svc','data',$(if ($networkBefore.data -eq '1') {'enable'} else {'disable'})) | Out-Null - $result.networkAfter=@{airplane=(Adb @('shell','settings','get','global','airplane_mode_on'));wifi=(Adb @('shell','settings','get','global','wifi_on'));data=(Adb @('shell','settings','get','global','mobile_data'))} + for ($attempt=0; $attempt -lt 30; $attempt++) { + $result.networkAfter=@{airplane=(Adb @('shell','settings','get','global','airplane_mode_on'));wifi=(Adb @('shell','settings','get','global','wifi_on'));data=(Adb @('shell','settings','get','global','mobile_data'))} + if (Same $networkBefore $result.networkAfter) { break }; Start-Sleep -Milliseconds 500 + } Check 'network-restored' (Same $networkBefore $result.networkAfter) ($result.networkAfter | ConvertTo-Json -Compress) } catch { $result.status='failed'; $result.restoreError=$_.Exception.Message } } diff --git a/tools/android/record-native-audio.ps1 b/tools/android/record-native-audio.ps1 index 4924547..ca99fd9 100644 --- a/tools/android/record-native-audio.ps1 +++ b/tools/android/record-native-audio.ps1 @@ -31,7 +31,7 @@ try { Start-Sleep -Milliseconds 100 } if (!$ready) { if (!$process.HasExited) { $process.Kill(); $process.WaitForExit() }; throw 'Android PCM recorder did not report recording started' } - if (!$process.WaitForExit(($Seconds+20)*1000)) { $process.Kill();throw 'Android PCM 녹음 종료 시간 초과' } + if (!$process.WaitForExit(($Seconds+20)*1000)) { $process.Kill();$process.WaitForExit();throw 'Android PCM 녹음 종료 시간 초과' } $process.Refresh();$record.exitCode=$process.ExitCode if ($process.ExitCode -ne 0) { throw "Android PCM recorder exit $($process.ExitCode)" } Add-Type -TypeDefinition @'