capture_demand
Asks a page for its camera or microphone only while the session reads the virtual device.
A device requested at connect is held until the session ends, so the indicator beside the
user's camera reports the session's length rather than the desktop's use. With
webcam_on_start or microphone_on_start set to demand, a CaptureDemand per device polls its
readers instead: the interposer's clients, PipeWire's consumers and a kernel device's openers
for the camera (webcam.VirtualWebcam.consumers), the sound server's recording streams for the
microphone (audio_control.AudioControl.recorders). A reader is passed on at the poll that
finds it; its absence only once it has lasted the device's hold-off, so an application's
probe-then-open never blinks the light.
The answer goes to one page, since every page that captures pushes into the same device: the
first candidate a transport offers, told to release before another is asked or once it may no
longer capture. A transport takes part with capture_candidates(), the pages that may
capture with the preferred one first, and async tell_capture(page, subject, wanted) -> bool;
it calls sync wherever that list changes and detach at shutdown. The wire verb is
CAPTURE_DEMAND <subject> <0|1> over WebSockets and the capture_demand,<subject>,<0|1>
system action over WebRTC, obeyed by the page unless the user toggled the device themselves.
Neither policy defaults to it, because a process on the desktop can then cause a permission
prompt; every transition is logged and audited as capture.demand with the reader's name.
attributelogger= logging.getLogger('capture_demand')attributeMSG_CAPTURE_DEMAND= 'CAPTURE_DEMAND'attributePOLL_SECONDS= 1.0attributeMIN_IDLE_POLLS= 3attributeWEBCAM_DEVICE_RECHECK_SECONDS= 4.0