AudioCapture.audioFlow's finally ran recorder.stop() then release() naked. If
startRecording() threw - permission revoked mid-request, audio device error -
the finally's stop() threw IllegalStateException (stop on an uninitialized
recorder), which replaced the original error AND skipped release(), leaking
the AudioRecord. The flow's caller saw "recorder failure" instead of "no
permission" and the native recorder was never freed.
Wrapping each cleanup step in runCatching preserves the original exception
while guaranteeing release() runs. Probe: a start failure previously surfaced
as RuntimeError with released=false; it now surfaces as the original
PermissionError with released=true.