1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Capability / permission probing for the Android backend. See
//! [`mediaway-device` ADR-0003](../../mediaway-device/adr/0003-capability-and-permission-probe.md).
//!
//! **Zero runtime verification**: like the rest of `android/`, neither [`support`] nor
//! [`request_permission`]'s real-probe branches has been exercised against a real device —
//! compile-checked only (and not even that, without an NDK toolchain in this dev environment).
use crateAndroidCameraCapture;
use crate;
use crate::;
use Rational;
/// Live support probe for `kind` on this device.
///
/// [`DeviceKind::Camera`] enumerates real Camera2 NDK camera IDs (`ACameraManager_getCameraIdList`,
/// no device opened). [`DeviceKind::Microphone`] has no cheap AAudio-level "is a mic present"
/// query (unlike `PipeWire`'s daemon-connect probe on Linux) — every real Android device ships at
/// least one microphone, so this reports [`Support::Supported`] unconditionally rather than
/// pretending an unavailable probe exists. [`DeviceKind::Screen`]/[`DeviceKind::Window`]/
/// [`DeviceKind::Loopback`]/[`DeviceKind::ProcessLoopback`] have no backend reachable from this
/// parameterless probe — `MediaProjection` availability can only be determined by the host app's
/// own JNI-attached consent flow (see `screencast.rs` module docs), which this function has no
/// `JavaVM`/`Env` to attempt; `Window`/`Loopback`/`ProcessLoopback` have no Android backend at
/// all this session.
/// Real `ACameraManager_getCameraIdList` count, no device opened — mirrors
/// `linux::camera::enumerate_camera_paths`'s "cheaper than a real open" cost class.
/// Best-effort permission probe for `kind`.
///
/// # Cost
///
/// [`DeviceKind::Camera`] opens a **real Camera2 NDK session** (the same path
/// [`AndroidCameraCapture::open`] takes) purely to observe whether
/// `ACAMERA_ERROR_PERMISSION_DENIED` comes back, then closes it — Camera2 NDK has no
/// separate cheap consent-probe API; opening is the only way to observe the CAMERA runtime
/// permission. Callers must not call this per frame; cache the result, and call [`support`]
/// first.
///
/// [`DeviceKind::Microphone`] returns [`PermissionState::Unknown`] rather than attempting a
/// real open: unlike Camera2's distinct `ACAMERA_ERROR_PERMISSION_DENIED` status, `AAudio` has no
/// documented, reliable way to distinguish a `RECORD_AUDIO` permission denial from any other
/// `open_stream` failure (see `mic.rs`'s `open_stream`, which maps all such failures to the
/// same [`CaptureError::Backend`]) — reporting [`PermissionState::Denied`] or
/// [`PermissionState::Granted`] here would claim a distinction this backend cannot actually
/// make. This is the documented purpose of [`PermissionState::Unknown`]: "no cheap probe
/// exists for this kind/platform; the caller must attempt to open a real session and handle
/// [`CaptureError::AccessDenied`]" — except this backend cannot even map that case to
/// `AccessDenied` today, so callers must treat any `mic.rs` open failure as ambiguous.
///
/// [`DeviceKind::Screen`] (and every other kind [`support`] reports
/// [`Support::Unavailable`] for) returns [`PermissionState::NotSupported`] — same reasoning as
/// [`support`]'s own doc comment.
///
/// # Errors
///
/// Returns the underlying [`CaptureError`] when a probe itself fails for a reason other than
/// access denial.