Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/./../../../dom/media/MediaManager.cpp
Warning:line 2950, column 12
Value stored to 'rv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_media3.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_UINT64_T -D WEBRTC_MOZILLA_BUILD -D RTC_ENABLE_VP9 -D WEBRTC_POSIX -D WEBRTC_BUILD_LIBEVENT -D WEBRTC_LINUX -D WEBRTC_USE_PIPEWIRE -D WEBRTC_USE_X11 -D MOZILLA_INTERNAL_API -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libsoundtouch/src -I /root/firefox-clang/caps -I /root/firefox-clang/config/external/rlbox_wasm2c_sandbox -I /root/firefox-clang/docshell/base -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/media/webrtc -I /root/firefox-clang/layout/generic -I /root/firefox-clang/layout/xul -I /root/firefox-clang/media/libyuv/libyuv/include -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/toolkit/content/tests/browser -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/libwebrtc_overrides -I /root/firefox-clang/dom/media/webrtc/common -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/third_party/libwebrtc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/gfx/skia -I /root/firefox-clang/gfx/skia/skia -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-error=attributes -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_dom_media3.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "MediaManager.h"
6
7#include "AudioCaptureTrack.h"
8#include "AudioDeviceInfo.h"
9#include "AudioStreamTrack.h"
10#include "CubebDeviceEnumerator.h"
11#include "CubebInputStream.h"
12#include "MediaTimer.h"
13#include "MediaTrackConstraints.h"
14#include "MediaTrackGraph.h"
15#include "MediaTrackListener.h"
16#include "Tracing.h"
17#include "VideoStreamTrack.h"
18#include "VideoUtils.h"
19#include "mozilla/Base64.h"
20#include "mozilla/EventTargetCapability.h"
21#include "mozilla/MozPromise.h"
22#include "mozilla/NullPrincipal.h"
23#include "mozilla/PeerIdentity.h"
24#include "mozilla/PermissionDelegateHandler.h"
25#include "mozilla/Sprintf.h"
26#include "mozilla/StaticPrefs_media.h"
27#include "mozilla/dom/BindingDeclarations.h"
28#include "mozilla/dom/Document.h"
29#include "mozilla/dom/Element.h"
30#include "mozilla/dom/FeaturePolicyUtils.h"
31#include "mozilla/dom/File.h"
32#include "mozilla/dom/GetUserMediaRequestBinding.h"
33#include "mozilla/dom/MediaDeviceInfo.h"
34#include "mozilla/dom/MediaDevices.h"
35#include "mozilla/dom/MediaDevicesBinding.h"
36#include "mozilla/dom/MediaStreamBinding.h"
37#include "mozilla/dom/MediaStreamTrackBinding.h"
38#include "mozilla/dom/Promise.h"
39#include "mozilla/dom/UserActivation.h"
40#include "mozilla/dom/WindowContext.h"
41#include "mozilla/dom/WindowGlobalChild.h"
42#include "mozilla/glean/DomMediaWebrtcMetrics.h"
43#include "mozilla/ipc/BackgroundChild.h"
44#include "mozilla/ipc/PBackgroundChild.h"
45#include "mozilla/media/CamerasTypes.h"
46#include "mozilla/media/MediaChild.h"
47#include "mozilla/media/MediaTaskUtils.h"
48#include "nsAppDirectoryServiceDefs.h"
49#include "nsArray.h"
50#include "nsContentUtils.h"
51#include "nsGlobalWindowInner.h"
52#include "nsHashPropertyBag.h"
53#include "nsIEventTarget.h"
54#include "nsIPermissionManager.h"
55#include "nsIUUIDGenerator.h"
56#include "nsJSUtils.h"
57#include "nsNetCID.h"
58#include "nsNetUtil.h"
59#include "nsProxyRelease.h"
60#include "nspr.h"
61#include "nss.h"
62#include "pk11pub.h"
63
64/* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
65#include "MediaEngineFake.h"
66#include "MediaEngineSource.h"
67#if defined(MOZ_WEBRTC1)
68# include "MediaEngineWebRTC.h"
69# include "MediaEngineWebRTCAudio.h"
70# include "browser_logging/WebRtcLog.h"
71# include "libwebrtcglue/WebrtcTaskQueueWrapper.h"
72# include "modules/audio_processing/include/audio_processing.h"
73#endif
74
75#if defined(XP_WIN)
76# include <objbase.h>
77#endif
78
79// A specialization of nsMainThreadPtrHolder for
80// mozilla::dom::CallbackObjectHolder. See documentation for
81// nsMainThreadPtrHolder in nsProxyRelease.h. This specialization lets us avoid
82// wrapping the CallbackObjectHolder into a separate refcounted object.
83template <class WebIDLCallbackT, class XPCOMCallbackT>
84class nsMainThreadPtrHolder<
85 mozilla::dom::CallbackObjectHolder<WebIDLCallbackT, XPCOMCallbackT>>
86 final {
87 typedef mozilla::dom::CallbackObjectHolder<WebIDLCallbackT, XPCOMCallbackT>
88 Holder;
89
90 public:
91 nsMainThreadPtrHolder(const char* aName, Holder&& aHolder)
92 : mHolder(std::move(aHolder))
93#ifndef RELEASE_OR_BETA
94 ,
95 mName(aName)
96#endif
97 {
98 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 98); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 98); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
99 }
100
101 private:
102 // We can be released on any thread.
103 ~nsMainThreadPtrHolder() {
104 if (NS_IsMainThread()) {
105 mHolder.Reset();
106 } else if (mHolder.GetISupports()) {
107 nsCOMPtr<nsIEventTarget> target = do_GetMainThread();
108 MOZ_ASSERT(target)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(target)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(target))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("target", "./../../../dom/media/MediaManager.cpp"
, 108); AnnotateMozCrashReason("MOZ_ASSERT" "(" "target" ")")
; do { MOZ_CrashSequence(__null, 108); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
109 NS_ProxyRelease(
110#ifdef RELEASE_OR_BETA
111 nullptr,
112#else
113 mName,
114#endif
115 target, mHolder.Forget());
116 }
117 }
118
119 public:
120 Holder* get() {
121 // Nobody should be touching the raw pointer off-main-thread.
122 if (MOZ_UNLIKELY(!NS_IsMainThread())(__builtin_expect(!!(!NS_IsMainThread()), 0))) {
123 NS_ERROR("Can't dereference nsMainThreadPtrHolder off main thread")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Can't dereference nsMainThreadPtrHolder off main thread"
, "Error", "./../../../dom/media/MediaManager.cpp", 123); MOZ_PretendNoReturn
(); } while (0)
;
124 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "./../../../dom/media/MediaManager.cpp"
, 124); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { MOZ_CrashSequence
(__null, 124); __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
125 }
126 return &mHolder;
127 }
128
129 bool operator!() const { return !mHolder; }
130
131 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsMainThreadPtrHolder<Holder>)public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<nsMainThreadPtrHolder<Holder>
>, "Reference-counted class " "nsMainThreadPtrHolder<Holder>"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 131
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("nsMainThreadPtrHolder<Holder>"), (uint32_t)(sizeof
(*this))); return (nsrefcnt)count; } MozExternalRefCountType Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 131
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("nsMainThreadPtrHolder<Holder>")); if (count ==
0) { delete (this); return 0; } return count; } using HasThreadSafeRefCnt
= std::true_type; protected: ::mozilla::ThreadSafeAutoRefCnt
mRefCnt; public:
132
133 // Copy constructor and operator= not implemented. Once constructed, the
134 // holder is immutable.
135 Holder& operator=(const nsMainThreadPtrHolder& aOther) = delete;
136 nsMainThreadPtrHolder(const nsMainThreadPtrHolder& aOther) = delete;
137
138 private:
139 // Our holder.
140 Holder mHolder;
141
142#ifndef RELEASE_OR_BETA
143 const char* mName = nullptr;
144#endif
145};
146
147namespace mozilla {
148
149LazyLogModule gMediaManagerLog("MediaManager");
150#define LOG(...)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, ...)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, ..., MOZ_LOG_EXPAND_ARGS); } } while (0)
MOZ_LOG_FMT(gMediaManagerLog, LogLevel::Debug, __VA_ARGS__)do { const ::mozilla::LogModule* moz_real_module = gMediaManagerLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, LogLevel::Debug, __VA_ARGS__); } } while (0)
151
152class GetUserMediaStreamTask;
153class LocalTrackSource;
154class SelectAudioOutputTask;
155
156using camera::CamerasAccessStatus;
157using dom::BFCacheStatus;
158using dom::CallerType;
159using dom::ConstrainDOMStringParameters;
160using dom::ConstrainDoubleRange;
161using dom::ConstrainLongRange;
162using dom::DisplayMediaStreamConstraints;
163using dom::Document;
164using dom::Element;
165using dom::FeaturePolicyUtils;
166using dom::File;
167using dom::GetUserMediaRequest;
168using dom::MediaDeviceKind;
169using dom::MediaDevices;
170using dom::MediaSourceEnum;
171using dom::MediaStreamConstraints;
172using dom::MediaStreamError;
173using dom::MediaStreamTrack;
174using dom::MediaStreamTrackSource;
175using dom::MediaTrackCapabilities;
176using dom::MediaTrackConstraints;
177using dom::MediaTrackConstraintSet;
178using dom::MediaTrackSettings;
179using dom::OwningBooleanOrMediaTrackConstraints;
180using dom::OwningStringOrStringSequence;
181using dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters;
182using dom::Promise;
183using dom::Sequence;
184using dom::UserActivation;
185using dom::VideoResizeModeEnum;
186using dom::WindowGlobalChild;
187using ConstDeviceSetPromise = MediaManager::ConstDeviceSetPromise;
188using DeviceSetPromise = MediaManager::DeviceSetPromise;
189using LocalDevicePromise = MediaManager::LocalDevicePromise;
190using LocalDeviceSetPromise = MediaManager::LocalDeviceSetPromise;
191using LocalMediaDeviceSetRefCnt = MediaManager::LocalMediaDeviceSetRefCnt;
192using MediaDeviceSetRefCnt = MediaManager::MediaDeviceSetRefCnt;
193using media::NewRunnableFrom;
194using media::NewTaskFrom;
195using media::Refcountable;
196
197// Whether main thread actions of MediaManager shutdown (except for clearing
198// of sSingleton) have completed.
199static bool sHasMainThreadShutdown;
200
201struct DeviceState {
202 DeviceState(RefPtr<LocalMediaDevice> aDevice,
203 RefPtr<LocalTrackSource> aTrackSource, bool aOffWhileDisabled)
204 : mOffWhileDisabled(aOffWhileDisabled),
205 mDevice(std::move(aDevice)),
206 mTrackSource(std::move(aTrackSource)) {
207 MOZ_ASSERT(mDevice)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDevice)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDevice))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mDevice", "./../../../dom/media/MediaManager.cpp"
, 207); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDevice" ")"
); do { MOZ_CrashSequence(__null, 207); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
208 MOZ_ASSERT(mTrackSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mTrackSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mTrackSource))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mTrackSource", "./../../../dom/media/MediaManager.cpp"
, 208); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTrackSource"
")"); do { MOZ_CrashSequence(__null, 208); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
209 }
210
211 // true if we have allocated mDevice. When not allocated, we may not stop or
212 // deallocate.
213 // MainThread only.
214 bool mAllocated = false;
215
216 // true if we have stopped mDevice, this is a terminal state.
217 // MainThread only.
218 bool mStopped = false;
219
220 // true if mDevice is currently enabled.
221 // A device must be both enabled and unmuted to be turned on and capturing.
222 // MainThread only.
223 bool mDeviceEnabled = false;
224
225 // true if mDevice is currently muted.
226 // A device that is either muted or disabled is turned off and not capturing.
227 // MainThread only.
228 bool mDeviceMuted = false;
229
230 // true if the application has currently enabled mDevice.
231 // MainThread only.
232 bool mTrackEnabled = false;
233
234 // Time when the application last enabled mDevice.
235 // MainThread only.
236 TimeStamp mTrackEnabledTime;
237
238 // true if an operation to Start() or Stop() mDevice has been dispatched to
239 // the media thread and is not finished yet.
240 // MainThread only.
241 bool mOperationInProgress = false;
242
243 // true if we are allowed to turn off the underlying source while all tracks
244 // are disabled or muted.
245 // MainThread only.
246 bool mOffWhileDisabled = false;
247
248 // Timer triggered by a MediaStreamTrackSource signaling that all tracks got
249 // disabled. When the timer fires we initiate Stop()ing mDevice.
250 // If set we allow dynamically stopping and starting mDevice.
251 // Any thread.
252 const RefPtr<MediaTimer<TimeStamp>> mDisableTimer =
253 new MediaTimer<TimeStamp>();
254
255 // The underlying device we keep state for. Always non-null.
256 // Threadsafe access, but see method declarations for individual constraints.
257 const RefPtr<LocalMediaDevice> mDevice;
258
259 // The MediaStreamTrackSource for any tracks (original and clones) originating
260 // from this device. Always non-null. Threadsafe access, but see method
261 // declarations for individual constraints.
262 const RefPtr<LocalTrackSource> mTrackSource;
263};
264
265/**
266 * This mimics the capture state from nsIMediaManagerService.
267 */
268enum class CaptureState : uint16_t {
269 Off = nsIMediaManagerService::STATE_NOCAPTURE,
270 Enabled = nsIMediaManagerService::STATE_CAPTURE_ENABLED,
271 Disabled = nsIMediaManagerService::STATE_CAPTURE_DISABLED,
272};
273
274static CaptureState CombineCaptureState(CaptureState aFirst,
275 CaptureState aSecond) {
276 if (aFirst == CaptureState::Enabled || aSecond == CaptureState::Enabled) {
277 return CaptureState::Enabled;
278 }
279 if (aFirst == CaptureState::Disabled || aSecond == CaptureState::Disabled) {
280 return CaptureState::Disabled;
281 }
282 MOZ_ASSERT(aFirst == CaptureState::Off)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aFirst == CaptureState::Off)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aFirst == CaptureState::Off)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("aFirst == CaptureState::Off"
, "./../../../dom/media/MediaManager.cpp", 282); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aFirst == CaptureState::Off" ")"); do { MOZ_CrashSequence
(__null, 282); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
283 MOZ_ASSERT(aSecond == CaptureState::Off)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecond == CaptureState::Off)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecond == CaptureState::Off
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aSecond == CaptureState::Off", "./../../../dom/media/MediaManager.cpp"
, 283); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSecond == CaptureState::Off"
")"); do { MOZ_CrashSequence(__null, 283); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
284 return CaptureState::Off;
285}
286
287static uint16_t FromCaptureState(CaptureState aState) {
288 MOZ_ASSERT(aState == CaptureState::Off || aState == CaptureState::Enabled ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aState == CaptureState::Off || aState == CaptureState
::Enabled || aState == CaptureState::Disabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aState == CaptureState::Off ||
aState == CaptureState::Enabled || aState == CaptureState::Disabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
, "./../../../dom/media/MediaManager.cpp", 289); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
")"); do { MOZ_CrashSequence(__null, 289); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
289 aState == CaptureState::Disabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aState == CaptureState::Off || aState == CaptureState
::Enabled || aState == CaptureState::Disabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aState == CaptureState::Off ||
aState == CaptureState::Enabled || aState == CaptureState::Disabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
, "./../../../dom/media/MediaManager.cpp", 289); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
")"); do { MOZ_CrashSequence(__null, 289); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
290 return static_cast<uint16_t>(aState);
291}
292
293void MediaManager::CallOnError(GetUserMediaErrorCallback& aCallback,
294 MediaStreamError& aError) {
295 aCallback.Call(aError);
296}
297
298void MediaManager::CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
299 DOMMediaStream& aStream) {
300 aCallback.Call(aStream);
301}
302
303enum class PersistentPermissionState : uint32_t {
304 Unknown = nsIPermissionManager::UNKNOWN_ACTION,
305 Allow = nsIPermissionManager::ALLOW_ACTION,
306 Deny = nsIPermissionManager::DENY_ACTION,
307 Prompt = nsIPermissionManager::PROMPT_ACTION,
308};
309
310static PersistentPermissionState CheckPermission(
311 PersistentPermissionState aPermission) {
312 switch (aPermission) {
313 case PersistentPermissionState::Unknown:
314 case PersistentPermissionState::Allow:
315 case PersistentPermissionState::Deny:
316 case PersistentPermissionState::Prompt:
317 return aPermission;
318 }
319 MOZ_CRASH("Unexpected permission value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected permission value"
, "./../../../dom/media/MediaManager.cpp", 319); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected permission value" ")"); do { MOZ_CrashSequence
(__null, 319); __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
320}
321
322struct WindowPersistentPermissionState {
323 PersistentPermissionState mCameraPermission;
324 PersistentPermissionState mMicrophonePermission;
325};
326
327static Result<WindowPersistentPermissionState, nsresult>
328GetPersistentPermissions(uint64_t aWindowId) {
329 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
330 if (NS_WARN_IF(!window)NS_warn_if_impl(!window, "!window", "./../../../dom/media/MediaManager.cpp"
, 330)
|| NS_WARN_IF(!window->GetPrincipal())NS_warn_if_impl(!window->GetPrincipal(), "!window->GetPrincipal()"
, "./../../../dom/media/MediaManager.cpp", 330)
) {
331 return Err(NS_ERROR_INVALID_ARG);
332 }
333
334 Document* doc = window->GetExtantDoc();
335 if (NS_WARN_IF(!doc)NS_warn_if_impl(!doc, "!doc", "./../../../dom/media/MediaManager.cpp"
, 335)
) {
336 return Err(NS_ERROR_INVALID_ARG);
337 }
338
339 nsIPrincipal* principal = window->GetPrincipal();
340 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "./../../../dom/media/MediaManager.cpp"
, 340)
) {
341 return Err(NS_ERROR_INVALID_ARG);
342 }
343
344 nsresult rv;
345 RefPtr<PermissionDelegateHandler> permDelegate =
346 doc->GetPermissionDelegateHandler();
347 if (NS_WARN_IF(!permDelegate)NS_warn_if_impl(!permDelegate, "!permDelegate", "./../../../dom/media/MediaManager.cpp"
, 347)
) {
348 return Err(NS_ERROR_INVALID_ARG);
349 }
350
351 uint32_t audio = nsIPermissionManager::UNKNOWN_ACTION;
352 uint32_t video = nsIPermissionManager::UNKNOWN_ACTION;
353 {
354 rv = permDelegate->GetPermission("microphone"_ns, &audio, true);
355 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 355)
) {
356 return Err(rv);
357 }
358 rv = permDelegate->GetPermission("camera"_ns, &video, true);
359 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 359)
) {
360 return Err(rv);
361 }
362 }
363
364 return WindowPersistentPermissionState{
365 CheckPermission(static_cast<PersistentPermissionState>(video)),
366 CheckPermission(static_cast<PersistentPermissionState>(audio))};
367}
368
369/**
370 * DeviceListener has threadsafe refcounting for use across the main, media and
371 * MTG threads. But it has a non-threadsafe SupportsWeakPtr for WeakPtr usage
372 * only from main thread, to ensure that garbage- and cycle-collected objects
373 * don't hold a reference to it during late shutdown.
374 */
375class DeviceListener : public SupportsWeakPtr {
376 public:
377 typedef MozPromise<bool /* aIgnored */, RefPtr<MediaMgrError>, false>
378 DeviceListenerPromise;
379
380 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<DeviceListener>, "Reference-counted class "
"DeviceListener" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 381
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("DeviceListener"), (uint32_t)(sizeof(*this))); return (nsrefcnt
)count; } MozExternalRefCountType Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 381
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("DeviceListener")); if (count == 0) { ::mozilla::detail
::ProxyDeleteMainVoid( "ProxyDelete " "DeviceListener", this,
[](void* self) { delete static_cast<DeviceListener*>(self
); }); return 0; } return count; } using HasThreadSafeRefCnt =
std::true_type; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt
; public:
381 DeviceListener)public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<DeviceListener>, "Reference-counted class "
"DeviceListener" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 381
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("DeviceListener"), (uint32_t)(sizeof(*this))); return (nsrefcnt
)count; } MozExternalRefCountType Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 381
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("DeviceListener")); if (count == 0) { ::mozilla::detail
::ProxyDeleteMainVoid( "ProxyDelete " "DeviceListener", this,
[](void* self) { delete static_cast<DeviceListener*>(self
); }); return 0; } return count; } using HasThreadSafeRefCnt =
std::true_type; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt
; public:
382
383 DeviceListener();
384
385 /**
386 * Registers this device listener as belonging to the given window listener.
387 * Stop() must be called on registered DeviceListeners before destruction.
388 */
389 void Register(GetUserMediaWindowListener* aListener);
390
391 /**
392 * Marks this listener as active and creates the internal device state.
393 */
394 void Activate(RefPtr<LocalMediaDevice> aDevice,
395 RefPtr<LocalTrackSource> aTrackSource, bool aStartMuted,
396 bool aIsAllocated);
397
398 /**
399 * Posts a task to initialize and start the associated device.
400 */
401 RefPtr<DeviceListenerPromise> InitializeAsync();
402
403 private:
404 /**
405 * Initializes synchronously. Must be called on the media thread.
406 */
407 nsresult Initialize(PrincipalHandle aPrincipal, LocalMediaDevice* aDevice,
408 MediaTrack* aTrack, bool aStartDevice);
409
410 public:
411 /**
412 * Synchronously clones this device listener, setting up the device to match
413 * our current device state asynchronously. Settings, constraints and other
414 * main thread state starts applying immediately.
415 */
416 already_AddRefed<DeviceListener> Clone() const;
417
418 /**
419 * Posts a task to stop the device associated with this DeviceListener and
420 * notifies the associated window listener that a track was stopped.
421 *
422 * This will also clean up the weak reference to the associated window
423 * listener, and tell the window listener to remove its hard reference to this
424 * DeviceListener, so any caller will need to keep its own hard ref.
425 */
426 void Stop();
427
428 /**
429 * Gets the main thread MediaTrackSettings from the MediaEngineSource
430 * associated with aTrack.
431 */
432 void GetSettings(MediaTrackSettings& aOutSettings) const;
433
434 /**
435 * Gets the main thread MediaTrackCapabilities from the MediaEngineSource
436 * associated with aTrack.
437 */
438 void GetCapabilities(MediaTrackCapabilities& aOutCapabilities) const;
439
440 /**
441 * Posts a task to set the enabled state of the device associated with this
442 * DeviceListener to aEnabled and notifies the associated window listener that
443 * a track's state has changed.
444 *
445 * Turning the hardware off while the device is disabled is supported for:
446 * - Camera (enabled by default, controlled by pref
447 * "media.getusermedia.camera.off_while_disabled.enabled")
448 * - Microphone (disabled by default, controlled by pref
449 * "media.getusermedia.microphone.off_while_disabled.enabled")
450 * Screen-, app-, or windowsharing is not supported at this time.
451 *
452 * The behavior is also different between disabling and enabling a device.
453 * While enabling is immediate, disabling only happens after a delay.
454 * This is now defaulting to 3 seconds but can be overriden by prefs:
455 * - "media.getusermedia.camera.off_while_disabled.delay_ms" and
456 * - "media.getusermedia.microphone.off_while_disabled.delay_ms".
457 *
458 * The delay is in place to prevent misuse by malicious sites. If a track is
459 * re-enabled before the delay has passed, the device will not be touched
460 * until another disable followed by the full delay happens.
461 */
462 void SetDeviceEnabled(bool aEnabled);
463
464 /**
465 * Posts a task to set the muted state of the device associated with this
466 * DeviceListener to aMuted and notifies the associated window listener that a
467 * track's state has changed.
468 *
469 * Turning the hardware off while the device is muted is supported for:
470 * - Camera (enabled by default, controlled by pref
471 * "media.getusermedia.camera.off_while_disabled.enabled")
472 * - Microphone (disabled by default, controlled by pref
473 * "media.getusermedia.microphone.off_while_disabled.enabled")
474 * Screen-, app-, or windowsharing is not supported at this time.
475 */
476 void SetDeviceMuted(bool aMuted);
477
478 /**
479 * Mutes or unmutes the associated video device if it is a camera.
480 */
481 void MuteOrUnmuteCamera(bool aMute);
482 void MuteOrUnmuteMicrophone(bool aMute);
483
484 LocalMediaDevice* GetDevice() const {
485 return mDeviceState ? mDeviceState->mDevice.get() : nullptr;
486 }
487
488 LocalTrackSource* GetTrackSource() const {
489 return mDeviceState ? mDeviceState->mTrackSource.get() : nullptr;
490 }
491
492 bool Activated() const { return static_cast<bool>(mDeviceState); }
493
494 bool Stopped() const { return mStopped; }
495
496 bool CapturingVideo() const;
497
498 bool CapturingAudio() const;
499
500 CaptureState CapturingSource(MediaSourceEnum aSource) const;
501
502 RefPtr<DeviceListenerPromise> ApplyConstraints(
503 const MediaTrackConstraints& aConstraints, CallerType aCallerType);
504
505 PrincipalHandle GetPrincipalHandle() const;
506
507 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
508 size_t amount = aMallocSizeOf(this);
509 // Assume mPrincipalHandle refers to a principal owned elsewhere.
510 // DeviceState does not have support for memory accounting.
511 return amount;
512 }
513
514 private:
515 virtual ~DeviceListener() {
516 MOZ_ASSERT(mStopped)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mStopped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mStopped))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mStopped", "./../../../dom/media/MediaManager.cpp"
, 516); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStopped" ")"
); do { MOZ_CrashSequence(__null, 516); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
517 MOZ_ASSERT(!mWindowListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWindowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWindowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mWindowListener"
, "./../../../dom/media/MediaManager.cpp", 517); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mWindowListener" ")"); do { MOZ_CrashSequence
(__null, 517); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
518 }
519
520 using DeviceOperationPromise =
521 MozPromise<nsresult, bool, /* IsExclusive = */ true>;
522
523 /**
524 * Posts a task to start or stop the device associated with aTrack, based on
525 * a passed-in boolean. Private method used by SetDeviceEnabled and
526 * SetDeviceMuted.
527 */
528 RefPtr<DeviceOperationPromise> UpdateDevice(bool aOn);
529
530 // true after this listener has had all devices stopped. MainThread only.
531 bool mStopped;
532
533 // never ever indirect off this; just for assertions
534 PRThread* mMainThreadCheck;
535
536 // Set in Register() on main thread, then read from any thread.
537 PrincipalHandle mPrincipalHandle;
538
539 // Weak pointer to the window listener that owns us. MainThread only.
540 GetUserMediaWindowListener* mWindowListener;
541
542 // Accessed from MediaTrackGraph thread, MediaManager thread, and MainThread
543 // No locking needed as it's set on Activate() and never assigned to again.
544 UniquePtr<DeviceState> mDeviceState;
545
546 MediaEventListener mCaptureEndedListener;
547};
548
549/**
550 * This class represents a WindowID and handles all MediaTrackListeners
551 * (here subclassed as DeviceListeners) used to feed GetUserMedia tracks.
552 * It proxies feedback from them into messages for browser chrome.
553 * The DeviceListeners are used to Start() and Stop() the underlying
554 * MediaEngineSource when MediaStreams are assigned and deassigned in content.
555 */
556class GetUserMediaWindowListener {
557 friend MediaManager;
558
559 public:
560 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GetUserMediaWindowListener)public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<GetUserMediaWindowListener>, "Reference-counted class "
"GetUserMediaWindowListener" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 560); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 560
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("GetUserMediaWindowListener"), (uint32_t)(sizeof(*this)))
; return (nsrefcnt)count; } MozExternalRefCountType Release(void
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 560); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 560
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("GetUserMediaWindowListener")); if (count == 0) { delete
(this); return 0; } return count; } using HasThreadSafeRefCnt
= std::true_type; protected: ::mozilla::ThreadSafeAutoRefCnt
mRefCnt; public:
561
562 // Create in an inactive state
563 GetUserMediaWindowListener(uint64_t aWindowID,
564 const PrincipalHandle& aPrincipalHandle)
565 : mWindowID(aWindowID),
566 mPrincipalHandle(aPrincipalHandle),
567 mChromeNotificationTaskPosted(false) {}
568
569 /**
570 * Registers an inactive gUM device listener for this WindowListener.
571 */
572 void Register(RefPtr<DeviceListener> aListener) {
573 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 573); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 573); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
574 MOZ_ASSERT(aListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aListener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aListener", "./../../../dom/media/MediaManager.cpp"
, 574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aListener" ")"
); do { MOZ_CrashSequence(__null, 574); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
575 MOZ_ASSERT(!aListener->Activated())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aListener->Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aListener->Activated()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!aListener->Activated()"
, "./../../../dom/media/MediaManager.cpp", 575); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!aListener->Activated()" ")"); do { MOZ_CrashSequence
(__null, 575); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
576 MOZ_ASSERT(!mInactiveListeners.Contains(aListener), "Already registered")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mInactiveListeners.Contains(aListener)"
" (" "Already registered" ")", "./../../../dom/media/MediaManager.cpp"
, 576); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)"
") (" "Already registered" ")"); do { MOZ_CrashSequence(__null
, 576); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
577 MOZ_ASSERT(!mActiveListeners.Contains(aListener), "Already activated")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mActiveListeners.Contains(aListener))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!mActiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mActiveListeners.Contains(aListener)"
" (" "Already activated" ")", "./../../../dom/media/MediaManager.cpp"
, 577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 577); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
578
579 aListener->Register(this);
580 mInactiveListeners.AppendElement(std::move(aListener));
581 }
582
583 /**
584 * Activates an already registered and inactive gUM device listener for this
585 * WindowListener.
586 */
587 void Activate(RefPtr<DeviceListener> aListener,
588 RefPtr<LocalMediaDevice> aDevice,
589 RefPtr<LocalTrackSource> aTrackSource, bool aIsAllocated) {
590 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 590); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 590); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
591 MOZ_ASSERT(aListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aListener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aListener", "./../../../dom/media/MediaManager.cpp"
, 591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aListener" ")"
); do { MOZ_CrashSequence(__null, 591); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
592 MOZ_ASSERT(!aListener->Activated())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aListener->Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aListener->Activated()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!aListener->Activated()"
, "./../../../dom/media/MediaManager.cpp", 592); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!aListener->Activated()" ")"); do { MOZ_CrashSequence
(__null, 592); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
593 MOZ_ASSERT(mInactiveListeners.Contains(aListener),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mInactiveListeners.Contains(aListener)"
" (" "Must be registered to activate" ")", "./../../../dom/media/MediaManager.cpp"
, 594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Contains(aListener)"
") (" "Must be registered to activate" ")"); do { MOZ_CrashSequence
(__null, 594); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
594 "Must be registered to activate")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mInactiveListeners.Contains(aListener)"
" (" "Must be registered to activate" ")", "./../../../dom/media/MediaManager.cpp"
, 594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Contains(aListener)"
") (" "Must be registered to activate" ")"); do { MOZ_CrashSequence
(__null, 594); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
595 MOZ_ASSERT(!mActiveListeners.Contains(aListener), "Already activated")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mActiveListeners.Contains(aListener))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!mActiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mActiveListeners.Contains(aListener)"
" (" "Already activated" ")", "./../../../dom/media/MediaManager.cpp"
, 595); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 595); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
596
597 bool muted = false;
598 if (aDevice->Kind() == MediaDeviceKind::Videoinput) {
599 muted = mCamerasAreMuted;
600 } else if (aDevice->Kind() == MediaDeviceKind::Audioinput) {
601 muted = mMicrophonesAreMuted;
602 } else {
603 MOZ_CRASH("Unexpected device kind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected device kind"
, "./../../../dom/media/MediaManager.cpp", 603); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected device kind" ")"); do { MOZ_CrashSequence
(__null, 603); __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
604 }
605
606 mInactiveListeners.RemoveElement(aListener);
607 aListener->Activate(std::move(aDevice), std::move(aTrackSource), muted,
608 aIsAllocated);
609 mActiveListeners.AppendElement(std::move(aListener));
610 }
611
612 /**
613 * Removes all DeviceListeners from this window listener.
614 * Removes this window listener from the list of active windows, so callers
615 * need to make sure to hold a strong reference.
616 */
617 void RemoveAll() {
618 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 618); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 618); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
619
620 for (auto& l : mInactiveListeners.Clone()) {
621 Remove(l);
622 }
623 for (auto& l : mActiveListeners.Clone()) {
624 Remove(l);
625 }
626 MOZ_ASSERT(mInactiveListeners.Length() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInactiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInactiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mInactiveListeners.Length() == 0", "./../../../dom/media/MediaManager.cpp"
, 626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0"
")"); do { MOZ_CrashSequence(__null, 626); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
627 MOZ_ASSERT(mActiveListeners.Length() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mActiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mActiveListeners.Length() == 0", "./../../../dom/media/MediaManager.cpp"
, 627); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0"
")"); do { MOZ_CrashSequence(__null, 627); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
628
629 MediaManager* mgr = MediaManager::GetIfExists();
630 if (!mgr) {
631 MOZ_ASSERT(false, "MediaManager should stay until everything is removed")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MediaManager should stay until everything is removed"
")", "./../../../dom/media/MediaManager.cpp", 631); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "MediaManager should stay until everything is removed"
")"); do { MOZ_CrashSequence(__null, 631); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
632 return;
633 }
634 GetUserMediaWindowListener* windowListener =
635 mgr->GetWindowListener(mWindowID);
636
637 if (!windowListener) {
638 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
639 auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
640 if (globalWindow) {
641 auto req = MakeRefPtr<GetUserMediaRequest>(
642 globalWindow, VoidString(), VoidString(),
643 UserActivation::IsHandlingUserInput());
644 obs->NotifyWhenScriptSafe(req, "recording-device-stopped", nullptr);
645 }
646 return;
647 }
648
649 MOZ_ASSERT(windowListener == this,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(windowListener == this)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(windowListener == this))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("windowListener == this"
" (" "There should only be one window listener per window ID"
")", "./../../../dom/media/MediaManager.cpp", 650); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener == this" ") (" "There should only be one window listener per window ID"
")"); do { MOZ_CrashSequence(__null, 650); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
650 "There should only be one window listener per window ID")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(windowListener == this)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(windowListener == this))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("windowListener == this"
" (" "There should only be one window listener per window ID"
")", "./../../../dom/media/MediaManager.cpp", 650); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener == this" ") (" "There should only be one window listener per window ID"
")"); do { MOZ_CrashSequence(__null, 650); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
651
652 LOG("GUMWindowListener {} removing windowID {}", fmt::ptr(this), mWindowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GUMWindowListener {} removing windowID {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "GUMWindowListener {} removing windowID {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), mWindowID); } } while (
0)
;
653 mgr->RemoveWindowID(mWindowID);
654 }
655
656 /**
657 * Removes a listener from our lists. Safe to call without holding a hard
658 * reference. That said, you'll still want to iterate on a copy of said lists,
659 * if you end up calling this method (or methods that may call this method) in
660 * the loop, to avoid inadvertently skipping members.
661 *
662 * For use only from GetUserMediaWindowListener and DeviceListener.
663 */
664 bool Remove(RefPtr<DeviceListener> aListener) {
665 // We refcount aListener on entry since we're going to proxy-release it
666 // below to prevent the refcount going to zero on callers who might be
667 // inside the listener, but operating without a hard reference to self.
668 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 668); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 668); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
669
670 if (!mInactiveListeners.RemoveElement(aListener) &&
671 !mActiveListeners.RemoveElement(aListener)) {
672 return false;
673 }
674 MOZ_ASSERT(!mInactiveListeners.Contains(aListener),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mInactiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 676); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 676); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
675 "A DeviceListener should only be once in one of "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mInactiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 676); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 676); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
676 "mInactiveListeners and mActiveListeners")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInactiveListeners.Contains(aListener))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mInactiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mInactiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 676); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 676); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
677 MOZ_ASSERT(!mActiveListeners.Contains(aListener),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mActiveListeners.Contains(aListener))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!mActiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mActiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 679); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 679); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
678 "A DeviceListener should only be once in one of "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mActiveListeners.Contains(aListener))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!mActiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mActiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 679); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 679); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
679 "mInactiveListeners and mActiveListeners")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mActiveListeners.Contains(aListener))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!mActiveListeners.Contains(aListener)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mActiveListeners.Contains(aListener)"
" (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")", "./../../../dom/media/MediaManager.cpp", 679); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)" ") ("
"A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { MOZ_CrashSequence(__null, 679); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
680
681 LOG("GUMWindowListener {} stopping DeviceListener {}.", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GUMWindowListener {} stopping DeviceListener {}.")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "GUMWindowListener {} stopping DeviceListener {}."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(aListener.get(
))); } } while (0)
682 fmt::ptr(aListener.get()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GUMWindowListener {} stopping DeviceListener {}.")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "GUMWindowListener {} stopping DeviceListener {}."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(aListener.get(
))); } } while (0)
;
683 aListener->Stop();
684
685 if (LocalMediaDevice* removedDevice = aListener->GetDevice()) {
686 bool revokePermission = true;
687 nsString removedRawId;
688 nsString removedSourceType;
689 removedDevice->GetRawId(removedRawId);
690 removedDevice->GetMediaSource(removedSourceType);
691
692 for (const auto& l : mActiveListeners) {
693 if (LocalMediaDevice* device = l->GetDevice()) {
694 nsString rawId;
695 device->GetRawId(rawId);
696 if (removedRawId.Equals(rawId)) {
697 revokePermission = false;
698 break;
699 }
700 }
701 }
702
703 if (revokePermission) {
704 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
705 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
706 auto req = MakeRefPtr<GetUserMediaRequest>(
707 window, removedRawId, removedSourceType,
708 UserActivation::IsHandlingUserInput());
709 obs->NotifyWhenScriptSafe(req, "recording-device-stopped", nullptr);
710 }
711 }
712
713 if (mInactiveListeners.Length() == 0 && mActiveListeners.Length() == 0) {
714 LOG("GUMWindowListener {} Removed last DeviceListener. Cleaning up.",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GUMWindowListener {} Removed last DeviceListener. Cleaning up."
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GUMWindowListener {} Removed last DeviceListener. Cleaning up."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
715 fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GUMWindowListener {} Removed last DeviceListener. Cleaning up."
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GUMWindowListener {} Removed last DeviceListener. Cleaning up."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
;
716 RemoveAll();
717 }
718
719 nsCOMPtr<nsIEventTarget> mainTarget = do_GetMainThread();
720 // To allow being invoked by callers not holding a strong reference to self,
721 // hold the listener alive until the stack has unwound, by always
722 // dispatching a runnable (aAlwaysProxy = true)
723 NS_ProxyRelease(__func__, mainTarget, aListener.forget(), true);
724 return true;
725 }
726
727 /**
728 * Stops all screen/window/audioCapture sharing, but not camera or microphone.
729 */
730 void StopSharing();
731
732 void StopRawID(const nsString& removedDeviceID);
733
734 void MuteOrUnmuteCameras(bool aMute);
735 void MuteOrUnmuteMicrophones(bool aMute);
736
737 /**
738 * Called by one of our DeviceListeners when one of its tracks has changed so
739 * that chrome state is affected.
740 * Schedules an event for the next stable state to update chrome.
741 */
742 void ChromeAffectingStateChanged();
743
744 /**
745 * Called in stable state to send a notification to update chrome.
746 */
747 void NotifyChrome();
748
749 bool CapturingVideo() const {
750 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 750); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 750); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
751 for (auto& l : mActiveListeners) {
752 if (l->CapturingVideo()) {
753 return true;
754 }
755 }
756 return false;
757 }
758
759 bool CapturingAudio() const {
760 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 760); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 760); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
761 for (auto& l : mActiveListeners) {
762 if (l->CapturingAudio()) {
763 return true;
764 }
765 }
766 return false;
767 }
768
769 CaptureState CapturingSource(MediaSourceEnum aSource) const {
770 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 770); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 770); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
771 CaptureState result = CaptureState::Off;
772 for (auto& l : mActiveListeners) {
773 result = CombineCaptureState(result, l->CapturingSource(aSource));
774 }
775 return result;
776 }
777
778 RefPtr<LocalMediaDeviceSetRefCnt> GetDevices() {
779 RefPtr devices = new LocalMediaDeviceSetRefCnt();
780 for (auto& l : mActiveListeners) {
781 devices->AppendElement(l->GetDevice());
782 }
783 return devices;
784 }
785
786 uint64_t WindowID() const { return mWindowID; }
787
788 PrincipalHandle GetPrincipalHandle() const { return mPrincipalHandle; }
789
790 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
791 size_t amount = aMallocSizeOf(this);
792 // Assume mPrincipalHandle refers to a principal owned elsewhere.
793 amount += mInactiveListeners.ShallowSizeOfExcludingThis(aMallocSizeOf);
794 for (const RefPtr<DeviceListener>& listener : mInactiveListeners) {
795 amount += listener->SizeOfIncludingThis(aMallocSizeOf);
796 }
797 amount += mActiveListeners.ShallowSizeOfExcludingThis(aMallocSizeOf);
798 for (const RefPtr<DeviceListener>& listener : mActiveListeners) {
799 amount += listener->SizeOfIncludingThis(aMallocSizeOf);
800 }
801 return amount;
802 }
803
804 private:
805 ~GetUserMediaWindowListener() {
806 MOZ_ASSERT(mInactiveListeners.Length() == 0,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInactiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInactiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mInactiveListeners.Length() == 0" " (" "Inactive listeners should already be removed"
")", "./../../../dom/media/MediaManager.cpp", 807); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0" ") (" "Inactive listeners should already be removed"
")"); do { MOZ_CrashSequence(__null, 807); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
807 "Inactive listeners should already be removed")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInactiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInactiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mInactiveListeners.Length() == 0" " (" "Inactive listeners should already be removed"
")", "./../../../dom/media/MediaManager.cpp", 807); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0" ") (" "Inactive listeners should already be removed"
")"); do { MOZ_CrashSequence(__null, 807); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
808 MOZ_ASSERT(mActiveListeners.Length() == 0,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mActiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mActiveListeners.Length() == 0" " (" "Active listeners should already be removed"
")", "./../../../dom/media/MediaManager.cpp", 809); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0" ") (" "Active listeners should already be removed"
")"); do { MOZ_CrashSequence(__null, 809); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
809 "Active listeners should already be removed")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActiveListeners.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mActiveListeners.Length() ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mActiveListeners.Length() == 0" " (" "Active listeners should already be removed"
")", "./../../../dom/media/MediaManager.cpp", 809); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0" ") (" "Active listeners should already be removed"
")"); do { MOZ_CrashSequence(__null, 809); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
810 }
811
812 uint64_t mWindowID;
813 const PrincipalHandle mPrincipalHandle;
814
815 // true if we have scheduled a task to notify chrome in the next stable state.
816 // The task will reset this to false. MainThread only.
817 bool mChromeNotificationTaskPosted;
818
819 nsTArray<RefPtr<DeviceListener>> mInactiveListeners;
820 nsTArray<RefPtr<DeviceListener>> mActiveListeners;
821
822 // Whether camera and microphone access in this window are currently
823 // User Agent (UA) muted. When true, new and cloned tracks must start
824 // out muted, to avoid JS circumventing UA mute. Per-camera and
825 // per-microphone UA muting is not supported.
826 bool mCamerasAreMuted = false;
827 bool mMicrophonesAreMuted = false;
828};
829
830class LocalTrackSource : public MediaStreamTrackSource {
831 public:
832 LocalTrackSource(nsIPrincipal* aPrincipal, const nsString& aLabel,
833 const RefPtr<DeviceListener>& aListener,
834 MediaSourceEnum aSource, MediaTrack* aTrack,
835 RefPtr<const PeerIdentity> aPeerIdentity,
836 TrackingId aTrackingId = TrackingId())
837 : MediaStreamTrackSource(aPrincipal, aLabel, std::move(aTrackingId)),
838 mSource(aSource),
839 mTrack(aTrack),
840 mPeerIdentity(std::move(aPeerIdentity)),
841 mListener(aListener.get()) {}
842
843 MediaSourceEnum GetMediaSource() const override { return mSource; }
844
845 const PeerIdentity* GetPeerIdentity() const override { return mPeerIdentity; }
846
847 RefPtr<MediaStreamTrackSource::ApplyConstraintsPromise> ApplyConstraints(
848 const MediaTrackConstraints& aConstraints,
849 CallerType aCallerType) override {
850 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 850); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 850); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
851 if (sHasMainThreadShutdown || !mListener) {
852 // Track has been stopped, or we are in shutdown. In either case
853 // there's no observable outcome, so pretend we succeeded.
854 return MediaStreamTrackSource::ApplyConstraintsPromise::CreateAndResolve(
855 false, __func__);
856 }
857 auto p = mListener->ApplyConstraints(aConstraints, aCallerType);
858 p->Then(
859 GetCurrentSerialEventTarget(), __func__,
860 [aConstraints, this, self = RefPtr(this)] {
861 ConstraintsChanged(aConstraints);
862 },
863 [] {});
864 return p;
865 }
866
867 void GetSettings(MediaTrackSettings& aOutSettings) override {
868 if (mListener) {
869 mListener->GetSettings(aOutSettings);
870 }
871 }
872
873 void GetCapabilities(MediaTrackCapabilities& aOutCapabilities) override {
874 if (mListener) {
875 mListener->GetCapabilities(aOutCapabilities);
876 }
877 }
878
879 void Stop() override {
880 if (mListener) {
881 mListener->Stop();
882 mListener = nullptr;
883 }
884 if (!mTrack->IsDestroyed()) {
885 mTrack->Destroy();
886 }
887 }
888
889 CloneResult Clone() override {
890 if (!mListener) {
891 return {};
892 }
893 RefPtr listener = mListener->Clone();
894 MOZ_ASSERT(listener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(listener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(listener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("listener", "./../../../dom/media/MediaManager.cpp"
, 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "listener" ")"
); do { MOZ_CrashSequence(__null, 894); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
895 if (!listener) {
896 return {};
897 }
898
899 return {.mSource = listener->GetTrackSource(),
900 .mInputTrack = listener->GetTrackSource()->mTrack};
901 }
902
903 void Disable() override {
904 if (mListener) {
905 mListener->SetDeviceEnabled(false);
906 }
907 }
908
909 void Enable() override {
910 if (mListener) {
911 mListener->SetDeviceEnabled(true);
912 }
913 }
914
915 void Mute() {
916 MutedChanged(true);
917 mTrack->SetDisabledTrackMode(DisabledTrackMode::SILENCE_BLACK);
918 }
919
920 void Unmute() {
921 MutedChanged(false);
922 mTrack->SetDisabledTrackMode(DisabledTrackMode::ENABLED);
923 }
924
925 const MediaSourceEnum mSource;
926 const RefPtr<MediaTrack> mTrack;
927 const RefPtr<const PeerIdentity> mPeerIdentity;
928
929 protected:
930 ~LocalTrackSource() {
931 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 931); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 931); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
932 MOZ_ASSERT(mTrack->IsDestroyed())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mTrack->IsDestroyed())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mTrack->IsDestroyed()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mTrack->IsDestroyed()"
, "./../../../dom/media/MediaManager.cpp", 932); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mTrack->IsDestroyed()" ")"); do { MOZ_CrashSequence
(__null, 932); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
933 }
934
935 // This is a weak pointer to avoid having the DeviceListener (which may
936 // have references to threads and threadpools) kept alive by DOM-objects
937 // that may have ref-cycles and thus are released very late during
938 // shutdown, even after xpcom-shutdown-threads. See bug 1351655 for what
939 // can happen.
940 WeakPtr<DeviceListener> mListener;
941};
942
943class AudioCaptureTrackSource : public LocalTrackSource {
944 public:
945 AudioCaptureTrackSource(nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow,
946 const nsString& aLabel,
947 AudioCaptureTrack* aAudioCaptureTrack,
948 RefPtr<PeerIdentity> aPeerIdentity)
949 : LocalTrackSource(aPrincipal, aLabel, nullptr,
950 MediaSourceEnum::AudioCapture, aAudioCaptureTrack,
951 std::move(aPeerIdentity)),
952 mWindow(aWindow),
953 mAudioCaptureTrack(aAudioCaptureTrack) {
954 mAudioCaptureTrack->Start();
955 mAudioCaptureTrack->Graph()->RegisterCaptureTrackForWindow(
956 mWindow->WindowID(), mAudioCaptureTrack);
957 mWindow->SetAudioCapture(true);
958 }
959
960 void Stop() override {
961 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 961); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 961); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
962 if (!mAudioCaptureTrack->IsDestroyed()) {
963 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "./../../../dom/media/MediaManager.cpp"
, 963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 963); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
964 mWindow->SetAudioCapture(false);
965 mAudioCaptureTrack->Graph()->UnregisterCaptureTrackForWindow(
966 mWindow->WindowID());
967 mWindow = nullptr;
968 }
969 // LocalTrackSource destroys the track.
970 LocalTrackSource::Stop();
971 MOZ_ASSERT(mAudioCaptureTrack->IsDestroyed())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAudioCaptureTrack->IsDestroyed())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAudioCaptureTrack->IsDestroyed
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mAudioCaptureTrack->IsDestroyed()", "./../../../dom/media/MediaManager.cpp"
, 971); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudioCaptureTrack->IsDestroyed()"
")"); do { MOZ_CrashSequence(__null, 971); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
972 }
973
974 ProcessedMediaTrack* InputTrack() const { return mAudioCaptureTrack.get(); }
975
976 protected:
977 ~AudioCaptureTrackSource() {
978 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 978); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 978); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
979 MOZ_ASSERT(mAudioCaptureTrack->IsDestroyed())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAudioCaptureTrack->IsDestroyed())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAudioCaptureTrack->IsDestroyed
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mAudioCaptureTrack->IsDestroyed()", "./../../../dom/media/MediaManager.cpp"
, 979); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudioCaptureTrack->IsDestroyed()"
")"); do { MOZ_CrashSequence(__null, 979); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
980 }
981
982 RefPtr<nsPIDOMWindowInner> mWindow;
983 const RefPtr<AudioCaptureTrack> mAudioCaptureTrack;
984};
985
986/**
987 * nsIMediaDevice implementation.
988 */
989NS_IMPL_ISUPPORTS(LocalMediaDevice, nsIMediaDevice)MozExternalRefCountType LocalMediaDevice::AddRef(void) { static_assert
(!std::is_destructible_v<LocalMediaDevice>, "Reference-counted class "
"LocalMediaDevice" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 989); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 989
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("LocalMediaDevice" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("LocalMediaDevice" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"LocalMediaDevice\" != nullptr" " (" "Must specify a name" ")"
, "./../../../dom/media/MediaManager.cpp", 989); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "\"LocalMediaDevice\" != nullptr" ") (" "Must specify a name"
")"); do { MOZ_CrashSequence(__null, 989); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (!mRefCnt
.isThreadSafe) _mOwningThread.AssertOwnership("LocalMediaDevice"
" not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef
((this), (count), ("LocalMediaDevice"), (uint32_t)(sizeof(*this
))); return count; } MozExternalRefCountType LocalMediaDevice
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 989); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 989
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("LocalMediaDevice" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("LocalMediaDevice" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"LocalMediaDevice\" != nullptr" " (" "Must specify a name" ")"
, "./../../../dom/media/MediaManager.cpp", 989); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "\"LocalMediaDevice\" != nullptr" ") (" "Must specify a name"
")"); do { MOZ_CrashSequence(__null, 989); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (!mRefCnt
.isThreadSafe) _mOwningThread.AssertOwnership("LocalMediaDevice"
" not thread-safe"); const char* const nametmp = "LocalMediaDevice"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult LocalMediaDevice::QueryInterface
(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../dom/media/MediaManager.cpp", 989
); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<LocalMediaDevice, nsIMediaDevice>, int32_t
( reinterpret_cast<char*>(static_cast<nsIMediaDevice
*>((LocalMediaDevice*)0x1000)) - reinterpret_cast<char*
>((LocalMediaDevice*)0x1000))}, {&mozilla::detail::kImplementedIID
<LocalMediaDevice, nsISupports>, int32_t(reinterpret_cast
<char*>(static_cast<nsISupports*>( static_cast<
nsIMediaDevice*>((LocalMediaDevice*)0x1000))) - reinterpret_cast
<char*>((LocalMediaDevice*)0x1000))}, { nullptr, 0 } } ;
static_assert(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
990
991MediaDevice::MediaDevice(MediaEngine* aEngine, MediaSourceEnum aMediaSource,
992 const nsString& aRawName, const nsString& aRawID,
993 const nsString& aRawGroupID, IsScary aIsScary,
994 const OsPromptable canRequestOsLevelPrompt)
995 : mEngine(aEngine),
996 mAudioDeviceInfo(nullptr),
997 mMediaSource(aMediaSource),
998 mKind(MediaEngineSource::IsVideo(aMediaSource)
999 ? MediaDeviceKind::Videoinput
1000 : MediaDeviceKind::Audioinput),
1001 mScary(aIsScary == IsScary::Yes),
1002 mCanRequestOsLevelPrompt(canRequestOsLevelPrompt == OsPromptable::Yes),
1003 mIsFake(mEngine->IsFake()),
1004 mType(NS_ConvertASCIItoUTF16(dom::GetEnumString(mKind))),
1005 mRawID(aRawID),
1006 mRawGroupID(aRawGroupID),
1007 mRawName(aRawName) {
1008 MOZ_ASSERT(mEngine)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mEngine)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mEngine))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mEngine", "./../../../dom/media/MediaManager.cpp"
, 1008); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mEngine" ")"
); do { MOZ_CrashSequence(__null, 1008); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1009}
1010
1011MediaDevice::MediaDevice(MediaEngine* aEngine,
1012 const RefPtr<AudioDeviceInfo>& aAudioDeviceInfo,
1013 const nsString& aRawID)
1014 : mEngine(aEngine),
1015 mAudioDeviceInfo(aAudioDeviceInfo),
1016 mMediaSource(mAudioDeviceInfo->Type() == AudioDeviceInfo::TYPE_INPUT
1017 ? MediaSourceEnum::Microphone
1018 : MediaSourceEnum::Other),
1019 mKind(mMediaSource == MediaSourceEnum::Microphone
1020 ? MediaDeviceKind::Audioinput
1021 : MediaDeviceKind::Audiooutput),
1022 mScary(false),
1023 mCanRequestOsLevelPrompt(false),
1024 mIsFake(false),
1025 mType(NS_ConvertASCIItoUTF16(dom::GetEnumString(mKind))),
1026 mRawID(aRawID),
1027 mRawGroupID(mAudioDeviceInfo->GroupID()),
1028 mRawName(mAudioDeviceInfo->Name()) {}
1029
1030/* static */
1031RefPtr<MediaDevice> MediaDevice::CopyWithNewRawGroupId(
1032 const RefPtr<MediaDevice>& aOther, const nsString& aRawGroupID) {
1033 MOZ_ASSERT(!aOther->mAudioDeviceInfo, "device not supported")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aOther->mAudioDeviceInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aOther->mAudioDeviceInfo
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!aOther->mAudioDeviceInfo" " (" "device not supported" ")"
, "./../../../dom/media/MediaManager.cpp", 1033); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!aOther->mAudioDeviceInfo" ") (" "device not supported"
")"); do { MOZ_CrashSequence(__null, 1033); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1034 return new MediaDevice(aOther->mEngine, aOther->mMediaSource,
1035 aOther->mRawName, aOther->mRawID, aRawGroupID,
1036 IsScary(aOther->mScary),
1037 OsPromptable(aOther->mCanRequestOsLevelPrompt));
1038}
1039
1040MediaDevice::~MediaDevice() = default;
1041
1042LocalMediaDevice::LocalMediaDevice(RefPtr<const MediaDevice> aRawDevice,
1043 const nsString& aID,
1044 const nsString& aGroupID,
1045 const nsString& aName)
1046 : mRawDevice(std::move(aRawDevice)),
1047 mName(aName),
1048 mID(aID),
1049 mGroupID(aGroupID) {
1050 MOZ_ASSERT(mRawDevice)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRawDevice)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRawDevice))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mRawDevice", "./../../../dom/media/MediaManager.cpp"
, 1050); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRawDevice"
")"); do { MOZ_CrashSequence(__null, 1050); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1051}
1052
1053/**
1054 * Helper functions that implement the constraints algorithm from
1055 * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
1056 */
1057
1058/* static */
1059bool LocalMediaDevice::StringsContain(
1060 const OwningStringOrStringSequence& aStrings, nsString aN) {
1061 return aStrings.IsString() ? aStrings.GetAsString() == aN
1062 : aStrings.GetAsStringSequence().Contains(aN);
1063}
1064
1065/* static */
1066uint32_t LocalMediaDevice::FitnessDistance(
1067 nsString aN, const ConstrainDOMStringParameters& aParams) {
1068 if (aParams.mExact.WasPassed() &&
1069 !StringsContain(aParams.mExact.Value(), aN)) {
1070 return UINT32_MAX(4294967295U);
1071 }
1072 if (aParams.mIdeal.WasPassed() &&
1073 !StringsContain(aParams.mIdeal.Value(), aN)) {
1074 return 1;
1075 }
1076 return 0;
1077}
1078
1079// Binding code doesn't templatize well...
1080
1081/* static */
1082uint32_t LocalMediaDevice::FitnessDistance(
1083 nsString aN,
1084 const OwningStringOrStringSequenceOrConstrainDOMStringParameters&
1085 aConstraint) {
1086 if (aConstraint.IsString()) {
1087 ConstrainDOMStringParameters params;
1088 params.mIdeal.Construct();
1089 params.mIdeal.Value().SetAsString() = aConstraint.GetAsString();
1090 return FitnessDistance(aN, params);
1091 } else if (aConstraint.IsStringSequence()) {
1092 ConstrainDOMStringParameters params;
1093 params.mIdeal.Construct();
1094 params.mIdeal.Value().SetAsStringSequence() =
1095 aConstraint.GetAsStringSequence();
1096 return FitnessDistance(aN, params);
1097 } else {
1098 return FitnessDistance(aN, aConstraint.GetAsConstrainDOMStringParameters());
1099 }
1100}
1101
1102uint32_t LocalMediaDevice::GetBestFitnessDistance(
1103 const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
1104 const MediaEnginePrefs& aPrefs, CallerType aCallerType) {
1105 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1105); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1105); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1106 MOZ_ASSERT(GetMediaSource() != MediaSourceEnum::Other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(GetMediaSource() != MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(GetMediaSource() != MediaSourceEnum::Other))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("GetMediaSource() != MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 1106); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "GetMediaSource() != MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 1106); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1107
1108 bool isChrome = aCallerType == CallerType::System;
1109 const nsString& id = isChrome ? RawID() : mID;
1110 auto type = GetMediaSource();
1111 uint64_t distance = 0;
1112 if (!aConstraintSets.IsEmpty()) {
1113 if (isChrome /* For the screen/window sharing preview */ ||
1114 type == MediaSourceEnum::Camera ||
1115 type == MediaSourceEnum::Microphone) {
1116 distance += uint64_t(MediaConstraintsHelper::FitnessDistance(
1117 Some(id), aConstraintSets[0]->mDeviceId)) +
1118 uint64_t(MediaConstraintsHelper::FitnessDistance(
1119 Some(mGroupID), aConstraintSets[0]->mGroupId));
1120 }
1121 }
1122 if (distance < UINT32_MAX(4294967295U)) {
1123 // Forward request to underlying object to interrogate per-mode
1124 // capabilities.
1125 distance += Source()->GetBestFitnessDistance(aConstraintSets, aPrefs);
1126 }
1127 return std::min<uint64_t>(distance, UINT32_MAX(4294967295U));
1128}
1129
1130NS_IMETHODIMPnsresult
1131LocalMediaDevice::GetRawName(nsAString& aName) {
1132 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1132); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1132); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1133 aName.Assign(mRawDevice->mRawName);
1134 return NS_OK;
1135}
1136
1137NS_IMETHODIMPnsresult
1138LocalMediaDevice::GetType(nsAString& aType) {
1139 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1139); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1139); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1140 aType.Assign(mRawDevice->mType);
1141 return NS_OK;
1142}
1143
1144NS_IMETHODIMPnsresult
1145LocalMediaDevice::GetRawId(nsAString& aID) {
1146 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1146); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1146); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1147 aID.Assign(RawID());
1148 return NS_OK;
1149}
1150
1151NS_IMETHODIMPnsresult
1152LocalMediaDevice::GetId(nsAString& aID) {
1153 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1153); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1153); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1154 aID.Assign(mID);
1155 return NS_OK;
1156}
1157
1158NS_IMETHODIMPnsresult
1159LocalMediaDevice::GetScary(bool* aScary) {
1160 *aScary = mRawDevice->mScary;
1161 return NS_OK;
1162}
1163
1164NS_IMETHODIMPnsresult
1165LocalMediaDevice::GetCanRequestOsLevelPrompt(bool* aCanRequestOsLevelPrompt) {
1166 *aCanRequestOsLevelPrompt = mRawDevice->mCanRequestOsLevelPrompt;
1167 return NS_OK;
1168}
1169
1170void LocalMediaDevice::GetSettings(MediaTrackSettings& aOutSettings) {
1171 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1171); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1171); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1172 Source()->GetSettings(aOutSettings);
1173}
1174
1175void LocalMediaDevice::GetCapabilities(
1176 MediaTrackCapabilities& aOutCapabilities) {
1177 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1177); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1177); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1178 Source()->GetCapabilities(aOutCapabilities);
1179}
1180
1181MediaEngineSource* LocalMediaDevice::Source() {
1182 if (!mSource) {
1183 mSource = mRawDevice->mEngine->CreateSource(mRawDevice);
1184 }
1185 return mSource;
1186}
1187
1188const TrackingId& LocalMediaDevice::GetTrackingId() const {
1189 return mSource->GetTrackingId();
1190}
1191
1192const dom::MediaTrackConstraints& LocalMediaDevice::Constraints() const {
1193 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1193); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1193); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1194 return mConstraints;
1195}
1196
1197// Threadsafe since mKind and mSource are const.
1198NS_IMETHODIMPnsresult
1199LocalMediaDevice::GetMediaSource(nsAString& aMediaSource) {
1200 if (Kind() == MediaDeviceKind::Audiooutput) {
1201 aMediaSource.Truncate();
1202 } else {
1203 aMediaSource.AssignASCII(dom::GetEnumString(GetMediaSource()));
1204 }
1205 return NS_OK;
1206}
1207
1208nsresult LocalMediaDevice::Allocate(const MediaTrackConstraints& aConstraints,
1209 const MediaEnginePrefs& aPrefs,
1210 uint64_t aWindowID,
1211 const char** aOutBadConstraint) {
1212 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1212); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1212); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1213
1214 // Mock failure for automated tests.
1215 if (IsFake() && aConstraints.mDeviceId.WasPassed() &&
1216 aConstraints.mDeviceId.Value().IsString() &&
1217 aConstraints.mDeviceId.Value().GetAsString().EqualsASCII("bad device")) {
1218 return NS_ERROR_FAILURE;
1219 }
1220
1221 nsresult rv =
1222 Source()->Allocate(aConstraints, aPrefs, aWindowID, aOutBadConstraint);
1223 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1224 mConstraints = aConstraints;
1225 }
1226 return rv;
1227}
1228
1229void LocalMediaDevice::SetTrack(const RefPtr<MediaTrack>& aTrack,
1230 const PrincipalHandle& aPrincipalHandle) {
1231 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1231); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1231); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1232 Source()->SetTrack(aTrack, aPrincipalHandle);
1233}
1234
1235nsresult LocalMediaDevice::Start() {
1236 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1236); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1236); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1237 MOZ_ASSERT(Source())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(Source())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(Source()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("Source()", "./../../../dom/media/MediaManager.cpp"
, 1237); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Source()" ")"
); do { MOZ_CrashSequence(__null, 1237); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1238 return Source()->Start();
1239}
1240
1241nsresult LocalMediaDevice::Reconfigure(
1242 const MediaTrackConstraints& aConstraints, const MediaEnginePrefs& aPrefs,
1243 const char** aOutBadConstraint) {
1244 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1244); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1244); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1245 using H = MediaConstraintsHelper;
1246 auto type = GetMediaSource();
1247 if (type == MediaSourceEnum::Camera || type == MediaSourceEnum::Microphone) {
1248 NormalizedConstraints c(aConstraints);
1249 if (H::FitnessDistance(Some(mID), c.mDeviceId) == UINT32_MAX(4294967295U)) {
1250 *aOutBadConstraint = "deviceId";
1251 return NS_ERROR_INVALID_ARG;
1252 }
1253 if (H::FitnessDistance(Some(mGroupID), c.mGroupId) == UINT32_MAX(4294967295U)) {
1254 *aOutBadConstraint = "groupId";
1255 return NS_ERROR_INVALID_ARG;
1256 }
1257 if (aPrefs.mResizeModeEnabled && type == MediaSourceEnum::Camera) {
1258 // Check invalid exact resizeMode constraint (not a device property)
1259 nsString none =
1260 NS_ConvertASCIItoUTF16(dom::GetEnumString(VideoResizeModeEnum::None));
1261 nsString crop = NS_ConvertASCIItoUTF16(
1262 dom::GetEnumString(VideoResizeModeEnum::Crop_and_scale));
1263 if (H::FitnessDistance(Some(none), c.mResizeMode) == UINT32_MAX(4294967295U) &&
1264 H::FitnessDistance(Some(crop), c.mResizeMode) == UINT32_MAX(4294967295U)) {
1265 *aOutBadConstraint = "resizeMode";
1266 return NS_ERROR_INVALID_ARG;
1267 }
1268 }
1269 }
1270 nsresult rv = Source()->Reconfigure(aConstraints, aPrefs, aOutBadConstraint);
1271 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1272 mConstraints = aConstraints;
1273 }
1274 return rv;
1275}
1276
1277nsresult LocalMediaDevice::FocusOnSelectedSource() {
1278 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1278); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1279 return Source()->FocusOnSelectedSource();
1280}
1281
1282nsresult LocalMediaDevice::Stop() {
1283 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1283); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1283); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1284 MOZ_ASSERT(mSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSource))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mSource", "./../../../dom/media/MediaManager.cpp"
, 1284); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSource" ")"
); do { MOZ_CrashSequence(__null, 1284); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1285 return mSource->Stop();
1286}
1287
1288nsresult LocalMediaDevice::Deallocate() {
1289 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1289); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1290 MOZ_ASSERT(mSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSource))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mSource", "./../../../dom/media/MediaManager.cpp"
, 1290); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSource" ")"
); do { MOZ_CrashSequence(__null, 1290); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1291 return mSource->Deallocate();
1292}
1293
1294already_AddRefed<LocalMediaDevice> LocalMediaDevice::Clone() const {
1295 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1295); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1295); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1296 auto device = MakeRefPtr<LocalMediaDevice>(mRawDevice, mID, mGroupID, mName);
1297 device->mSource =
1298 mRawDevice->mEngine->CreateSourceFrom(mSource, device->mRawDevice);
1299#ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED1
1300 // The source is normally created on the MediaManager thread. But for cloning,
1301 // it ends up being created on main thread. Make sure its owning event target
1302 // is set properly.
1303 auto* src = device->Source();
1304 src->_mOwningThread = mSource->_mOwningThread;
1305#endif
1306 return device.forget();
1307}
1308
1309MediaSourceEnum MediaDevice::GetMediaSource() const { return mMediaSource; }
1310
1311static const MediaTrackConstraints& GetInvariant(
1312 const OwningBooleanOrMediaTrackConstraints& aUnion) {
1313 static const MediaTrackConstraints empty;
1314 return aUnion.IsMediaTrackConstraints() ? aUnion.GetAsMediaTrackConstraints()
1315 : empty;
1316}
1317
1318// Source getter returning full list
1319
1320static void GetMediaDevices(MediaEngine* aEngine, MediaSourceEnum aSrcType,
1321 MediaManager::MediaDeviceSet& aResult,
1322 const char* aMediaDeviceName = nullptr) {
1323 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 1323); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 1323); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1324
1325 LOG("{}: aEngine={}, aSrcType={}, aMediaDeviceName={}", __func__,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}"
, MOZ_LOG_EXPAND_ARGS __func__, fmt::ptr(aEngine), static_cast
<uint8_t>(aSrcType), aMediaDeviceName ? aMediaDeviceName
: "null"); } } while (0)
1326 fmt::ptr(aEngine), static_cast<uint8_t>(aSrcType),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}"
, MOZ_LOG_EXPAND_ARGS __func__, fmt::ptr(aEngine), static_cast
<uint8_t>(aSrcType), aMediaDeviceName ? aMediaDeviceName
: "null"); } } while (0)
1327 aMediaDeviceName ? aMediaDeviceName : "null")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "{}: aEngine={}, aSrcType={}, aMediaDeviceName={}"
, MOZ_LOG_EXPAND_ARGS __func__, fmt::ptr(aEngine), static_cast
<uint8_t>(aSrcType), aMediaDeviceName ? aMediaDeviceName
: "null"); } } while (0)
;
1328 nsTArray<RefPtr<MediaDevice>> devices;
1329 aEngine->EnumerateDevices(aSrcType, MediaSinkEnum::Other, &devices);
1330
1331 /*
1332 * We're allowing multiple tabs to access the same camera for parity
1333 * with Chrome. See bug 811757 for some of the issues surrounding
1334 * this decision. To disallow, we'd filter by IsAvailable() as we used
1335 * to.
1336 */
1337 if (aMediaDeviceName && *aMediaDeviceName) {
1338 for (auto& device : devices) {
1339 if (device->mRawName.EqualsASCII(aMediaDeviceName)) {
1340 aResult.AppendElement(device);
1341 LOG("{}: found aMediaDeviceName={}", __func__, aMediaDeviceName)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: found aMediaDeviceName={}")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "{}: found aMediaDeviceName={}"
, MOZ_LOG_EXPAND_ARGS __func__, aMediaDeviceName); } } while (
0)
;
1342 break;
1343 }
1344 }
1345 } else {
1346 aResult = std::move(devices);
1347 if (MOZ_LOG_TEST(gMediaManagerLog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gMediaManagerLog
, mozilla::LogLevel::Debug)), 0))
) {
1348 for (auto& device : aResult) {
1349 LOG("{}: appending device={}", __func__,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: appending device={}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "{}: appending device={}", MOZ_LOG_EXPAND_ARGS
__func__, NS_ConvertUTF16toUTF8(device->mRawName).get());
} } while (0)
1350 NS_ConvertUTF16toUTF8(device->mRawName).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: appending device={}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "{}: appending device={}", MOZ_LOG_EXPAND_ARGS
__func__, NS_ConvertUTF16toUTF8(device->mRawName).get());
} } while (0)
;
1351 }
1352 }
1353 }
1354}
1355
1356RefPtr<LocalDeviceSetPromise> MediaManager::SelectSettings(
1357 const MediaStreamConstraints& aConstraints, CallerType aCallerType,
1358 RefPtr<LocalMediaDeviceSetRefCnt> aDevices) {
1359 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1359); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1359); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1360
1361 // Algorithm accesses device capabilities code and must run on media thread.
1362 // Modifies passed-in aDevices.
1363
1364 return MediaManager::Dispatch<LocalDeviceSetPromise>(
1365 __func__, [aConstraints, devices = std::move(aDevices), prefs = mPrefs,
1366 aCallerType](MozPromiseHolder<LocalDeviceSetPromise>& holder) {
1367 auto& devicesRef = *devices;
1368
1369 // Since the advanced part of the constraints algorithm needs to know
1370 // when a candidate set is overconstrained (zero members), we must split
1371 // up the list into videos and audios, and put it back together again at
1372 // the end.
1373
1374 nsTArray<RefPtr<LocalMediaDevice>> videos;
1375 nsTArray<RefPtr<LocalMediaDevice>> audios;
1376
1377 for (const auto& device : devicesRef) {
1378 MOZ_ASSERT(device->Kind() == MediaDeviceKind::Videoinput ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(device->Kind() == MediaDeviceKind::Videoinput || device
->Kind() == MediaDeviceKind::Audioinput)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(device->Kind() == MediaDeviceKind
::Videoinput || device->Kind() == MediaDeviceKind::Audioinput
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
, "./../../../dom/media/MediaManager.cpp", 1379); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
")"); do { MOZ_CrashSequence(__null, 1379); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1379 device->Kind() == MediaDeviceKind::Audioinput)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(device->Kind() == MediaDeviceKind::Videoinput || device
->Kind() == MediaDeviceKind::Audioinput)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(device->Kind() == MediaDeviceKind
::Videoinput || device->Kind() == MediaDeviceKind::Audioinput
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
, "./../../../dom/media/MediaManager.cpp", 1379); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
")"); do { MOZ_CrashSequence(__null, 1379); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1380 if (device->Kind() == MediaDeviceKind::Videoinput) {
1381 videos.AppendElement(device);
1382 } else if (device->Kind() == MediaDeviceKind::Audioinput) {
1383 audios.AppendElement(device);
1384 }
1385 }
1386 devicesRef.Clear();
1387 const char* badConstraint = nullptr;
1388 bool needVideo = IsOn(aConstraints.mVideo);
1389 bool needAudio = IsOn(aConstraints.mAudio);
1390
1391 if (needVideo && videos.Length()) {
1392 badConstraint = MediaConstraintsHelper::SelectSettings(
1393 NormalizedConstraints(GetInvariant(aConstraints.mVideo)), prefs,
1394 videos, aCallerType);
1395 }
1396 if (!badConstraint && needAudio && audios.Length()) {
1397 badConstraint = MediaConstraintsHelper::SelectSettings(
1398 NormalizedConstraints(GetInvariant(aConstraints.mAudio)), prefs,
1399 audios, aCallerType);
1400 }
1401 if (badConstraint) {
1402 LOG("SelectSettings: bad constraint found! Calling error handler!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectSettings: bad constraint found! Calling error handler!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectSettings: bad constraint found! Calling error handler!"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
1403 nsString constraint;
1404 constraint.AssignASCII(badConstraint);
1405 holder.Reject(
1406 new MediaMgrError(MediaMgrError::Name::OverconstrainedError, "",
1407 constraint),
1408 __func__);
1409 return;
1410 }
1411 if (!needVideo == !videos.Length() && !needAudio == !audios.Length()) {
1412 for (auto& video : videos) {
1413 devicesRef.AppendElement(video);
1414 }
1415 for (auto& audio : audios) {
1416 devicesRef.AppendElement(audio);
1417 }
1418 }
1419 holder.Resolve(devices, __func__);
1420 });
1421}
1422
1423/**
1424 * Describes a requested task that handles response from the UI and sends
1425 * results back to the DOM.
1426 */
1427class GetUserMediaTask {
1428 public:
1429 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GetUserMediaTask)public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<GetUserMediaTask>, "Reference-counted class "
"GetUserMediaTask" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 1429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1429
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("GetUserMediaTask"), (uint32_t)(sizeof(*this))); return (
nsrefcnt)count; } MozExternalRefCountType Release(void) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 1429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1429
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("GetUserMediaTask")); if (count == 0) { delete (this
); return 0; } return count; } using HasThreadSafeRefCnt = std
::true_type; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt
; public:
1430 GetUserMediaTask(uint64_t aWindowID, const ipc::PrincipalInfo& aPrincipalInfo,
1431 CallerType aCallerType)
1432 : mPrincipalInfo(aPrincipalInfo),
1433 mWindowID(aWindowID),
1434 mCallerType(aCallerType) {}
1435
1436 virtual void Denied(MediaMgrError::Name aName,
1437 const nsCString& aMessage = ""_ns) = 0;
1438
1439 virtual GetUserMediaStreamTask* AsGetUserMediaStreamTask() { return nullptr; }
1440 virtual SelectAudioOutputTask* AsSelectAudioOutputTask() { return nullptr; }
1441
1442 uint64_t GetWindowID() const { return mWindowID; }
1443 enum CallerType CallerType() const { return mCallerType; }
1444
1445 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
1446 size_t amount = aMallocSizeOf(this);
1447 // Assume mWindowListener is owned by MediaManager.
1448 // Assume mAudioDeviceListener and mVideoDeviceListener are owned by
1449 // mWindowListener.
1450 // Assume PrincipalInfo string buffers are shared.
1451 // Member types without support for accounting of pointees:
1452 // MozPromiseHolder, RefPtr<LocalMediaDevice>.
1453 // We don't have a good way to account for lambda captures for MozPromise
1454 // callbacks.
1455 return amount;
1456 }
1457
1458 protected:
1459 virtual ~GetUserMediaTask() = default;
1460
1461 // Call GetPrincipalKey again, if not private browing, this time with
1462 // persist = true, to promote deviceIds to persistent, in case they're not
1463 // already. Fire'n'forget.
1464 void PersistPrincipalKey() {
1465 if (IsPrincipalInfoPrivate(mPrincipalInfo)) {
1466 return;
1467 }
1468 media::GetPrincipalKey(mPrincipalInfo, true)
1469 ->Then(
1470 GetCurrentSerialEventTarget(), __func__,
1471 [](const media::PrincipalKeyPromise::ResolveOrRejectValue& aValue) {
1472 if (aValue.IsReject()) {
1473 LOG("Failed get Principal key. Persisting of deviceIds "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Failed get Principal key. Persisting of deviceIds " "will be broken"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "Failed get Principal key. Persisting of deviceIds "
"will be broken", MOZ_LOG_EXPAND_ARGS); } } while (0)
1474 "will be broken")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Failed get Principal key. Persisting of deviceIds " "will be broken"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "Failed get Principal key. Persisting of deviceIds "
"will be broken", MOZ_LOG_EXPAND_ARGS); } } while (0)
;
1475 }
1476 });
1477 }
1478
1479 private:
1480 // Thread-safe (object) principal of Window with ID mWindowID
1481 const ipc::PrincipalInfo mPrincipalInfo;
1482
1483 protected:
1484 // The ID of the not-necessarily-toplevel inner Window relevant global
1485 // object of the MediaDevices on which getUserMedia() was called
1486 const uint64_t mWindowID;
1487 // Whether the JS caller of getUserMedia() has system (subject) principal
1488 const enum CallerType mCallerType;
1489};
1490
1491/**
1492 * Describes a requested task that handles response from the UI to a
1493 * getUserMedia() request and sends results back to content. If the request
1494 * is allowed and device initialization succeeds, then the MozPromise is
1495 * resolved with a DOMMediaStream having a track or tracks for the approved
1496 * device or devices.
1497 */
1498class GetUserMediaStreamTask final : public GetUserMediaTask {
1499 public:
1500 GetUserMediaStreamTask(
1501 const MediaStreamConstraints& aConstraints,
1502 MozPromiseHolder<MediaManager::StreamPromise>&& aHolder,
1503 uint64_t aWindowID, RefPtr<GetUserMediaWindowListener> aWindowListener,
1504 RefPtr<DeviceListener> aAudioDeviceListener,
1505 RefPtr<DeviceListener> aVideoDeviceListener,
1506 const MediaEnginePrefs& aPrefs, const ipc::PrincipalInfo& aPrincipalInfo,
1507 enum CallerType aCallerType, bool aShouldFocusSource)
1508 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1509 mConstraints(aConstraints),
1510 mHolder(std::move(aHolder)),
1511 mWindowListener(std::move(aWindowListener)),
1512 mAudioDeviceListener(std::move(aAudioDeviceListener)),
1513 mVideoDeviceListener(std::move(aVideoDeviceListener)),
1514 mPrefs(aPrefs),
1515 mShouldFocusSource(aShouldFocusSource),
1516 mManager(MediaManager::GetInstance()) {}
1517
1518 void Allowed(RefPtr<LocalMediaDevice> aAudioDevice,
1519 RefPtr<LocalMediaDevice> aVideoDevice) {
1520 MOZ_ASSERT(aAudioDevice || aVideoDevice)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aAudioDevice || aVideoDevice)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aAudioDevice || aVideoDevice
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aAudioDevice || aVideoDevice", "./../../../dom/media/MediaManager.cpp"
, 1520); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioDevice || aVideoDevice"
")"); do { MOZ_CrashSequence(__null, 1520); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1521 mAudioDevice = std::move(aAudioDevice);
1522 mVideoDevice = std::move(aVideoDevice);
1523 // Reuse the same thread to save memory.
1524 MediaManager::Dispatch(
1525 NewRunnableMethod("GetUserMediaStreamTask::AllocateDevices", this,
1526 &GetUserMediaStreamTask::AllocateDevices));
1527 }
1528
1529 GetUserMediaStreamTask* AsGetUserMediaStreamTask() override { return this; }
1530
1531 private:
1532 ~GetUserMediaStreamTask() override {
1533 if (!mHolder.IsEmpty()) {
1534 Fail(MediaMgrError::Name::NotAllowedError);
1535 }
1536 }
1537
1538 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns,
1539 const nsString& aConstraint = u""_ns) {
1540 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage, aConstraint),
1541 __func__);
1542 // We add a disabled listener to the StreamListeners array until accepted
1543 // If this was the only active MediaStream, remove the window from the list.
1544 NS_DispatchToMainThread(NS_NewRunnableFunction(
1545 "DeviceListener::Stop",
1546 [audio = mAudioDeviceListener, video = mVideoDeviceListener] {
1547 if (audio) {
1548 audio->Stop();
1549 }
1550 if (video) {
1551 video->Stop();
1552 }
1553 }));
1554 }
1555
1556 /**
1557 * Runs on a separate thread and is responsible for allocating devices.
1558 *
1559 * Do not run this on the main thread.
1560 */
1561 void AllocateDevices() {
1562 MOZ_ASSERT(!NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1562); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1562); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1563 LOG("GetUserMediaStreamTask::AllocateDevices()")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::AllocateDevices()")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::AllocateDevices()"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
1564
1565 // Allocate a video or audio device and return a MediaStream via
1566 // PrepareDOMStream().
1567
1568 nsresult rv;
1569 const char* errorMsg = nullptr;
1570 const char* badConstraint = nullptr;
1571
1572 if (mAudioDevice) {
1573 auto& constraints = GetInvariant(mConstraints.mAudio);
1574 rv = mAudioDevice->Allocate(constraints, mPrefs, mWindowID,
1575 &badConstraint);
1576 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1577 errorMsg = "Failed to allocate audiosource";
1578 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1579 nsTArray<RefPtr<LocalMediaDevice>> devices;
1580 devices.AppendElement(mAudioDevice);
1581 badConstraint = MediaConstraintsHelper::SelectSettings(
1582 NormalizedConstraints(constraints), mPrefs, devices, mCallerType);
1583 }
1584 }
1585 }
1586 if (!errorMsg && mVideoDevice) {
1587 auto& constraints = GetInvariant(mConstraints.mVideo);
1588 rv = mVideoDevice->Allocate(constraints, mPrefs, mWindowID,
1589 &badConstraint);
1590 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1591 errorMsg = "Failed to allocate videosource";
1592 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1593 nsTArray<RefPtr<LocalMediaDevice>> devices;
1594 devices.AppendElement(mVideoDevice);
1595 badConstraint = MediaConstraintsHelper::SelectSettings(
1596 NormalizedConstraints(constraints), mPrefs, devices, mCallerType);
1597 }
1598 if (mAudioDevice) {
1599 mAudioDevice->Deallocate();
1600 }
1601 } else {
1602 mVideoTrackingId.emplace(mVideoDevice->GetTrackingId());
1603 }
1604 }
1605 if (errorMsg) {
1606 LOG("{} {}", errorMsg, static_cast<uint32_t>(rv))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{} {}")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "{} {}", MOZ_LOG_EXPAND_ARGS errorMsg, static_cast<uint32_t
>(rv)); } } while (0)
;
1607 if (badConstraint) {
1608 Fail(MediaMgrError::Name::OverconstrainedError, ""_ns,
1609 NS_ConvertUTF8toUTF16(badConstraint));
1610 } else {
1611 Fail(MediaMgrError::Name::NotReadableError, nsCString(errorMsg));
1612 }
1613 NS_DispatchToMainThread(
1614 NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest", []() {
1615 if (MediaManager* manager = MediaManager::GetIfExists()) {
1616 manager->SendPendingGUMRequest();
1617 }
1618 }));
1619 return;
1620 }
1621 NS_DispatchToMainThread(
1622 NewRunnableMethod("GetUserMediaStreamTask::PrepareDOMStream", this,
1623 &GetUserMediaStreamTask::PrepareDOMStream));
1624 }
1625
1626 public:
1627 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1628 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1628); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1628); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1629 Fail(aName, aMessage);
1630 }
1631
1632 const MediaStreamConstraints& GetConstraints() { return mConstraints; }
1633
1634 void PrimeVoiceProcessing() {
1635 mPrimingStream = MakeAndAddRef<PrimingCubebVoiceInputStream>();
1636 mPrimingStream->Init();
1637 }
1638
1639 private:
1640 void PrepareDOMStream();
1641
1642 class PrimingCubebVoiceInputStream {
1643 class Listener final : public CubebInputStream::Listener {
1644 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Listener, override)public: MozExternalRefCountType AddRef(void) override { static_assert
(!std::is_destructible_v<Listener>, "Reference-counted class "
"Listener" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 1644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1644
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("Listener"), (uint32_t)(sizeof(*this))); return (nsrefcnt
)count; } MozExternalRefCountType Release(void) override { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 1644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1644
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("Listener")); if (count == 0) { delete (this); return
0; } return count; } using HasThreadSafeRefCnt = std::true_type
; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; public:
;
1645
1646 private:
1647 ~Listener() = default;
1648
1649 long DataCallback(const void*, long) override {
1650 MOZ_CRASH("Unexpected data callback")do { do { } while (false); MOZ_ReportCrash("" "Unexpected data callback"
, "./../../../dom/media/MediaManager.cpp", 1650); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected data callback" ")"); do { MOZ_CrashSequence
(__null, 1650); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
1651 }
1652 void StateCallback(cubeb_state) override {}
1653 void DeviceChangedCallback() override {}
1654 };
1655
1656 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_EVENT_TARGET(public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<PrimingCubebVoiceInputStream>, "Reference-counted class "
"PrimingCubebVoiceInputStream" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 1657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1657
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("PrimingCubebVoiceInputStream"), (uint32_t)(sizeof(*this)
)); return (nsrefcnt)count; } MozExternalRefCountType Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 1657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1657
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("PrimingCubebVoiceInputStream")); if (count == 0) { ::
mozilla::detail::ProxyDeleteVoid( "ProxyDelete " "PrimingCubebVoiceInputStream"
, mCubebThread.GetEventTarget(), this, [](void* self) { delete
static_cast<PrimingCubebVoiceInputStream*>(self); }); return
0; } return count; } using HasThreadSafeRefCnt = std::true_type
; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; public:
1657 PrimingCubebVoiceInputStream, mCubebThread.GetEventTarget())public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<PrimingCubebVoiceInputStream>, "Reference-counted class "
"PrimingCubebVoiceInputStream" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 1657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1657
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("PrimingCubebVoiceInputStream"), (uint32_t)(sizeof(*this)
)); return (nsrefcnt)count; } MozExternalRefCountType Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../dom/media/MediaManager.cpp"
, 1657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1657
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("PrimingCubebVoiceInputStream")); if (count == 0) { ::
mozilla::detail::ProxyDeleteVoid( "ProxyDelete " "PrimingCubebVoiceInputStream"
, mCubebThread.GetEventTarget(), this, [](void* self) { delete
static_cast<PrimingCubebVoiceInputStream*>(self); }); return
0; } return count; } using HasThreadSafeRefCnt = std::true_type
; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; public:
1658
1659 public:
1660 void Init() {
1661 mCubebThread.GetEventTarget()->Dispatch(
1662 NS_NewRunnableFunction(__func__, [this, self = RefPtr(this)] {
1663 mCubebThread.AssertOnCurrentThread();
1664 LOG("Priming voice processing with stream {}", fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Priming voice processing with stream {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Priming voice processing with stream {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
;
1665 TRACE("PrimingCubebVoiceInputStream::Init")AutoTracer trace(gAudioCallbackTraceLogger, "PrimingCubebVoiceInputStream::Init"
);
;
1666 const cubeb_devid default_device = nullptr;
1667 const uint32_t mono = 1;
1668 const uint32_t rate = CubebUtils::PreferredSampleRate(false);
1669 const bool isVoice = true;
1670 mCubebStream =
1671 CubebInputStream::Create(default_device, mono, rate, isVoice,
1672 MakeRefPtr<Listener>().get());
1673 }));
1674 }
1675
1676 private:
1677 ~PrimingCubebVoiceInputStream() {
1678 mCubebThread.AssertOnCurrentThread();
1679 LOG("Releasing primed voice processing stream {}", fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Releasing primed voice processing stream {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Releasing primed voice processing stream {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
;
1680 mCubebStream = nullptr;
1681 }
1682
1683 const EventTargetCapability<nsISerialEventTarget> mCubebThread =
1684 EventTargetCapability<nsISerialEventTarget>(
1685 TaskQueue::Create(CubebUtils::GetCubebOperationThread(),
1686 "PrimingCubebInputStream::mCubebThread")
1687 .get());
1688 UniquePtr<CubebInputStream> mCubebStream MOZ_GUARDED_BY(mCubebThread)__attribute__((guarded_by(mCubebThread)));
1689 };
1690
1691 // Constraints derived from those passed to getUserMedia() but adjusted for
1692 // preferences, defaults, and security
1693 const MediaStreamConstraints mConstraints;
1694
1695 MozPromiseHolder<MediaManager::StreamPromise> mHolder;
1696 // GetUserMediaWindowListener with which DeviceListeners are registered
1697 const RefPtr<GetUserMediaWindowListener> mWindowListener;
1698 const RefPtr<DeviceListener> mAudioDeviceListener;
1699 const RefPtr<DeviceListener> mVideoDeviceListener;
1700 // MediaDevices are set when selected and Allowed() by the UI.
1701 RefPtr<LocalMediaDevice> mAudioDevice;
1702 RefPtr<LocalMediaDevice> mVideoDevice;
1703 RefPtr<PrimingCubebVoiceInputStream> mPrimingStream;
1704 // Tracking id unique for a video frame source. Set when the corresponding
1705 // device has been allocated.
1706 Maybe<TrackingId> mVideoTrackingId;
1707 // Copy of MediaManager::mPrefs
1708 const MediaEnginePrefs mPrefs;
1709 // media.getusermedia.window.focus_source.enabled
1710 const bool mShouldFocusSource;
1711 // The MediaManager is referenced at construction so that it won't be
1712 // created after its ShutdownBlocker would run.
1713 const RefPtr<MediaManager> mManager;
1714};
1715
1716/**
1717 * Creates a MediaTrack, attaches a listener and resolves a MozPromise to
1718 * provide the stream to the DOM.
1719 *
1720 * All of this must be done on the main thread!
1721 */
1722void GetUserMediaStreamTask::PrepareDOMStream() {
1723 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1723); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1723); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1724 LOG("GetUserMediaStreamTask::PrepareDOMStream()")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::PrepareDOMStream()")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::PrepareDOMStream()"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
1725 nsGlobalWindowInner* window =
1726 nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
1727
1728 // We're on main-thread, and the windowlist can only
1729 // be invalidated from the main-thread (see OnNavigation)
1730 if (!mManager->IsWindowListenerStillActive(mWindowListener)) {
1731 // This window is no longer live. mListener has already been removed.
1732 return;
1733 }
1734
1735 MediaTrackGraph::GraphDriverType graphDriverType =
1736 mAudioDevice ? MediaTrackGraph::AUDIO_THREAD_DRIVER
1737 : MediaTrackGraph::SYSTEM_THREAD_DRIVER;
1738 MediaTrackGraph* mtg = MediaTrackGraph::GetInstance(
1739 graphDriverType, window, MediaTrackGraph::REQUEST_DEFAULT_SAMPLE_RATE,
1740 MediaTrackGraph::DEFAULT_OUTPUT_DEVICE);
1741
1742 auto domStream = MakeRefPtr<DOMMediaStream>(window);
1743 RefPtr<LocalTrackSource> audioTrackSource;
1744 RefPtr<LocalTrackSource> videoTrackSource;
1745 nsCOMPtr<nsIPrincipal> principal;
1746 RefPtr<PeerIdentity> peerIdentity = nullptr;
1747 if (!mConstraints.mPeerIdentity.IsEmpty()) {
1748 peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
1749 principal = NullPrincipal::CreateWithInheritedAttributes(
1750 window->GetExtantDoc()->NodePrincipal());
1751 } else {
1752 principal = window->GetExtantDoc()->NodePrincipal();
1753 }
1754 RefPtr<GenericNonExclusivePromise> firstFramePromise;
1755 if (mAudioDevice) {
1756 if (mAudioDevice->GetMediaSource() == MediaSourceEnum::AudioCapture) {
1757 // AudioCapture is a special case, here, in the sense that we're not
1758 // really using the audio source and the SourceMediaTrack, which acts
1759 // as placeholders. We re-route a number of tracks internally in the
1760 // MTG and mix them down instead.
1761 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 1764)
1762 "MediaCaptureWindowState doesn't handle "NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 1764)
1763 "MediaSourceEnum::AudioCapture. This must be fixed with UX "NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 1764)
1764 "before shipping.")NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 1764)
;
1765 auto audioCaptureSource = MakeRefPtr<AudioCaptureTrackSource>(
1766 principal, window, u"Window audio capture"_ns,
1767 mtg->CreateAudioCaptureTrack(), peerIdentity);
1768 audioTrackSource = audioCaptureSource;
1769 RefPtr<MediaStreamTrack> track = new dom::AudioStreamTrack(
1770 window, audioCaptureSource->InputTrack(), audioCaptureSource);
1771 domStream->AddTrackInternal(track);
1772 } else {
1773 const nsString& audioDeviceName = mAudioDevice->mName;
1774 RefPtr<MediaTrack> track;
1775#ifdef MOZ_WEBRTC1
1776 if (mAudioDevice->IsFake()) {
1777 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1778 } else {
1779 track = AudioProcessingTrack::Create(mtg);
1780 track->Suspend(); // Microphone source resumes in SetTrack
1781 }
1782#else
1783 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1784#endif
1785 audioTrackSource = new LocalTrackSource(
1786 principal, audioDeviceName, mAudioDeviceListener,
1787 mAudioDevice->GetMediaSource(), track, peerIdentity);
1788 MOZ_ASSERT(MediaManager::IsOn(mConstraints.mAudio))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsOn(mConstraints.mAudio))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(MediaManager::IsOn(mConstraints.mAudio)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("MediaManager::IsOn(mConstraints.mAudio)"
, "./../../../dom/media/MediaManager.cpp", 1788); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mAudio)" ")"
); do { MOZ_CrashSequence(__null, 1788); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1789 RefPtr<MediaStreamTrack> domTrack = new dom::AudioStreamTrack(
1790 window, track, audioTrackSource, dom::MediaStreamTrackState::Live,
1791 false, GetInvariant(mConstraints.mAudio));
1792 domStream->AddTrackInternal(domTrack);
1793 }
1794 }
1795 if (mVideoDevice) {
1796 const nsString& videoDeviceName = mVideoDevice->mName;
1797 RefPtr<MediaTrack> track = mtg->CreateSourceTrack(MediaSegment::VIDEO);
1798 videoTrackSource = new LocalTrackSource(
1799 principal, videoDeviceName, mVideoDeviceListener,
1800 mVideoDevice->GetMediaSource(), track, peerIdentity, *mVideoTrackingId);
1801 MOZ_ASSERT(MediaManager::IsOn(mConstraints.mVideo))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsOn(mConstraints.mVideo))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(MediaManager::IsOn(mConstraints.mVideo)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("MediaManager::IsOn(mConstraints.mVideo)"
, "./../../../dom/media/MediaManager.cpp", 1801); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mVideo)" ")"
); do { MOZ_CrashSequence(__null, 1801); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1802 RefPtr<MediaStreamTrack> domTrack = new dom::VideoStreamTrack(
1803 window, track, videoTrackSource, dom::MediaStreamTrackState::Live,
1804 false, GetInvariant(mConstraints.mVideo));
1805 domStream->AddTrackInternal(domTrack);
1806 switch (mVideoDevice->GetMediaSource()) {
1807 case MediaSourceEnum::Browser:
1808 case MediaSourceEnum::Screen:
1809 case MediaSourceEnum::Window:
1810 // Wait for first frame for screen-sharing devices, to ensure
1811 // with and height settings are available immediately, to pass wpt.
1812 firstFramePromise = mVideoDevice->Source()->GetFirstFramePromise();
1813 break;
1814 default:
1815 break;
1816 }
1817 }
1818
1819 if (!domStream || (!audioTrackSource && !videoTrackSource) ||
1820 sHasMainThreadShutdown) {
1821 LOG("Returning error for getUserMedia() - no stream")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Returning error for getUserMedia() - no stream")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Returning error for getUserMedia() - no stream"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
1822
1823 mHolder.Reject(
1824 MakeRefPtr<MediaMgrError>(
1825 MediaMgrError::Name::AbortError,
1826 sHasMainThreadShutdown ? "In shutdown"_ns : "No stream."_ns),
1827 __func__);
1828 return;
1829 }
1830
1831 // Activate our device listeners. We'll call Start() on the source when we
1832 // get a callback that the MediaStream has started consuming. The listener
1833 // is freed when the page is invalidated (on navigation or close).
1834 if (mAudioDeviceListener) {
1835 mWindowListener->Activate(mAudioDeviceListener, mAudioDevice,
1836 std::move(audioTrackSource),
1837 /*aIsAllocated=*/true);
1838 }
1839 if (mVideoDeviceListener) {
1840 mWindowListener->Activate(mVideoDeviceListener, mVideoDevice,
1841 std::move(videoTrackSource),
1842 /*aIsAllocated=*/true);
1843 }
1844
1845 // Dispatch to the media thread to ask it to start the sources, because that
1846 // can take a while.
1847 typedef DeviceListener::DeviceListenerPromise PromiseType;
1848 AutoTArray<RefPtr<PromiseType>, 2> promises;
1849 if (mAudioDeviceListener) {
1850 promises.AppendElement(mAudioDeviceListener->InitializeAsync());
1851 }
1852 if (mVideoDeviceListener) {
1853 promises.AppendElement(mVideoDeviceListener->InitializeAsync());
1854 }
1855 PromiseType::All(GetMainThreadSerialEventTarget(), promises)
1856 ->Then(
1857 GetMainThreadSerialEventTarget(), __func__,
1858 [manager = mManager, windowListener = mWindowListener,
1859 firstFramePromise] {
1860 LOG("GetUserMediaStreamTask::PrepareDOMStream: starting success "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::PrepareDOMStream: starting success "
"callback following InitializeAsync()")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::PrepareDOMStream: starting success "
"callback following InitializeAsync()", MOZ_LOG_EXPAND_ARGS)
; } } while (0)
1861 "callback following InitializeAsync()")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::PrepareDOMStream: starting success "
"callback following InitializeAsync()")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::PrepareDOMStream: starting success "
"callback following InitializeAsync()", MOZ_LOG_EXPAND_ARGS)
; } } while (0)
;
1862 // Initiating and starting devices succeeded.
1863 windowListener->ChromeAffectingStateChanged();
1864 manager->SendPendingGUMRequest();
1865 if (!firstFramePromise) {
1866 return DeviceListener::DeviceListenerPromise::CreateAndResolve(
1867 true, __func__);
1868 }
1869 RefPtr<DeviceListener::DeviceListenerPromise> resolvePromise =
1870 firstFramePromise->Then(
1871 GetMainThreadSerialEventTarget(), __func__,
1872 [] {
1873 return DeviceListener::DeviceListenerPromise::
1874 CreateAndResolve(true, __func__);
1875 },
1876 [](nsresult aError) {
1877 MOZ_ASSERT(NS_FAILED(aError))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)),
0))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)),
0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)), 0)))",
"./../../../dom/media/MediaManager.cpp", 1877); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)), 0)))"
")"); do { MOZ_CrashSequence(__null, 1877); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1878 if (aError == NS_ERROR_UNEXPECTED) {
1879 return DeviceListener::DeviceListenerPromise::
1880 CreateAndReject(
1881 MakeRefPtr<MediaMgrError>(
1882 MediaMgrError::Name::NotAllowedError),
1883 __func__);
1884 }
1885 MOZ_ASSERT(aError == NS_ERROR_ABORT)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aError == NS_ERROR_ABORT)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aError == NS_ERROR_ABORT))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("aError == NS_ERROR_ABORT"
, "./../../../dom/media/MediaManager.cpp", 1885); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aError == NS_ERROR_ABORT" ")"); do { MOZ_CrashSequence
(__null, 1885); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1886 return DeviceListener::DeviceListenerPromise::
1887 CreateAndReject(MakeRefPtr<MediaMgrError>(
1888 MediaMgrError::Name::AbortError,
1889 "In shutdown"),
1890 __func__);
1891 });
1892 return resolvePromise;
1893 },
1894 [audio = mAudioDeviceListener,
1895 video = mVideoDeviceListener](const RefPtr<MediaMgrError>& aError) {
1896 LOG("GetUserMediaStreamTask::PrepareDOMStream: starting failure "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::PrepareDOMStream: starting failure "
"callback following InitializeAsync()")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::PrepareDOMStream: starting failure "
"callback following InitializeAsync()", MOZ_LOG_EXPAND_ARGS)
; } } while (0)
1897 "callback following InitializeAsync()")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMediaStreamTask::PrepareDOMStream: starting failure "
"callback following InitializeAsync()")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "GetUserMediaStreamTask::PrepareDOMStream: starting failure "
"callback following InitializeAsync()", MOZ_LOG_EXPAND_ARGS)
; } } while (0)
;
1898 if (audio) {
1899 audio->Stop();
1900 }
1901 if (video) {
1902 video->Stop();
1903 }
1904 return DeviceListener::DeviceListenerPromise::CreateAndReject(
1905 aError, __func__);
1906 })
1907 ->Then(
1908 GetMainThreadSerialEventTarget(), __func__,
1909 [holder = std::move(mHolder), domStream, callerType = mCallerType,
1910 shouldFocus = mShouldFocusSource, videoDevice = mVideoDevice](
1911 const DeviceListener::DeviceListenerPromise::ResolveOrRejectValue&
1912 aValue) mutable {
1913 if (aValue.IsResolve()) {
1914 if (auto* mgr = MediaManager::GetIfExists();
1915 mgr && !sHasMainThreadShutdown && videoDevice &&
1916 callerType == CallerType::NonSystem && shouldFocus) {
1917 // Device was successfully started. Attempt to focus the
1918 // source.
1919 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1920 mgr->mMediaThread->Dispatch(NS_NewRunnableFunction(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1921 "GetUserMediaStreamTask::FocusOnSelectedSource",do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1922 [videoDevice = std::move(videoDevice)] {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1923 nsresult rv = videoDevice->FocusOnSelectedSource();do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1924 if (NS_FAILED(rv)) {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1925 LOG("FocusOnSelectedSource failed");do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1926 }do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1927 })))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( "GetUserMediaStreamTask::FocusOnSelectedSource"
, [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice
->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!
(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "FocusOnSelectedSource failed"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "FocusOnSelectedSource failed"
, MOZ_LOG_EXPAND_ARGS); } } while (0); } })))), 1)))), 1))) {
} else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
, "./../../../dom/media/MediaManager.cpp", 1927); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mgr->mMediaThread->Dispatch(NS_NewRunnableFunction( \"GetUserMediaStreamTask::FocusOnSelectedSource\", [videoDevice = std::move(videoDevice)] { nsresult rv = videoDevice->FocusOnSelectedSource(); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"FocusOnSelectedSource failed\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"FocusOnSelectedSource failed\", MOZ_LOG_EXPAND_ARGS); } } while (0); } })))"
")"); do { MOZ_CrashSequence(__null, 1927); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1928 }
1929
1930 holder.Resolve(domStream, __func__);
1931 } else {
1932 holder.Reject(aValue.RejectValue(), __func__);
1933 }
1934 });
1935
1936 PersistPrincipalKey();
1937}
1938
1939/**
1940 * Describes a requested task that handles response from the UI to a
1941 * selectAudioOutput() request and sends results back to content. If the
1942 * request is allowed, then the MozPromise is resolved with a MediaDevice
1943 * for the approved device.
1944 */
1945class SelectAudioOutputTask final : public GetUserMediaTask {
1946 public:
1947 SelectAudioOutputTask(MozPromiseHolder<LocalDevicePromise>&& aHolder,
1948 uint64_t aWindowID, enum CallerType aCallerType,
1949 const ipc::PrincipalInfo& aPrincipalInfo)
1950 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1951 mHolder(std::move(aHolder)) {}
1952
1953 void Allowed(RefPtr<LocalMediaDevice> aAudioOutput) {
1954 MOZ_ASSERT(aAudioOutput)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aAudioOutput)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aAudioOutput))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aAudioOutput", "./../../../dom/media/MediaManager.cpp"
, 1954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioOutput"
")"); do { MOZ_CrashSequence(__null, 1954); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1955 mHolder.Resolve(std::move(aAudioOutput), __func__);
1956 PersistPrincipalKey();
1957 }
1958
1959 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1960 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 1960); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1960); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1961 Fail(aName, aMessage);
1962 }
1963
1964 SelectAudioOutputTask* AsSelectAudioOutputTask() override { return this; }
1965
1966 private:
1967 ~SelectAudioOutputTask() override {
1968 if (!mHolder.IsEmpty()) {
1969 Fail(MediaMgrError::Name::NotAllowedError);
1970 }
1971 }
1972
1973 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns) {
1974 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage), __func__);
1975 }
1976
1977 private:
1978 MozPromiseHolder<LocalDevicePromise> mHolder;
1979};
1980
1981/* static */
1982void MediaManager::GuessVideoDeviceGroupIDs(MediaDeviceSet& aDevices,
1983 const MediaDeviceSet& aAudios) {
1984 // Run the logic in a lambda to avoid duplication.
1985 auto updateGroupIdIfNeeded = [&](RefPtr<MediaDevice>& aVideo,
1986 const MediaDeviceKind aKind) -> bool {
1987 MOZ_ASSERT(aVideo->mKind == MediaDeviceKind::Videoinput)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aVideo->mKind == MediaDeviceKind::Videoinput)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aVideo->mKind == MediaDeviceKind::Videoinput))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aVideo->mKind == MediaDeviceKind::Videoinput"
, "./../../../dom/media/MediaManager.cpp", 1987); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideo->mKind == MediaDeviceKind::Videoinput"
")"); do { MOZ_CrashSequence(__null, 1987); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1988 MOZ_ASSERT(aKind == MediaDeviceKind::Audioinput ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind
::Audiooutput)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aKind == MediaDeviceKind::Audioinput
|| aKind == MediaDeviceKind::Audiooutput))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
, "./../../../dom/media/MediaManager.cpp", 1989); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { MOZ_CrashSequence(__null, 1989); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1989 aKind == MediaDeviceKind::Audiooutput)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind
::Audiooutput)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aKind == MediaDeviceKind::Audioinput
|| aKind == MediaDeviceKind::Audiooutput))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
, "./../../../dom/media/MediaManager.cpp", 1989); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { MOZ_CrashSequence(__null, 1989); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1990 // This will store the new group id if a match is found.
1991 nsString newVideoGroupID;
1992 // If the group id needs to be updated this will become true. It is
1993 // necessary when the new group id is an empty string. Without this extra
1994 // variable to signal the update, we would resort to test if
1995 // `newVideoGroupId` is empty. However,
1996 // that check does not work when the new group id is an empty string.
1997 bool updateGroupId = false;
1998 for (const RefPtr<MediaDevice>& dev : aAudios) {
1999 if (dev->mKind != aKind) {
2000 continue;
2001 }
2002 if (!FindInReadable(aVideo->mRawName, dev->mRawName)) {
2003 continue;
2004 }
2005 if (newVideoGroupID.IsEmpty()) {
2006 // This is only expected on first match. If that's the only match group
2007 // id will be updated to this one at the end of the loop.
2008 updateGroupId = true;
2009 newVideoGroupID = dev->mRawGroupID;
2010 } else {
2011 // More than one device found, it is impossible to know which group id
2012 // is the correct one.
2013 updateGroupId = false;
2014 newVideoGroupID = u""_ns;
2015 break;
2016 }
2017 }
2018 if (updateGroupId) {
2019 aVideo = MediaDevice::CopyWithNewRawGroupId(aVideo, newVideoGroupID);
2020 return true;
2021 }
2022 return false;
2023 };
2024
2025 for (RefPtr<MediaDevice>& video : aDevices) {
2026 if (video->mKind != MediaDeviceKind::Videoinput) {
2027 continue;
2028 }
2029 if (updateGroupIdIfNeeded(video, MediaDeviceKind::Audioinput)) {
2030 // GroupId has been updated, continue to the next video device
2031 continue;
2032 }
2033 // GroupId has not been updated, check among the outputs
2034 updateGroupIdIfNeeded(video, MediaDeviceKind::Audiooutput);
2035 }
2036}
2037
2038namespace {
2039
2040// Class to hold the promise used to request device access and to resolve
2041// even if |task| does not run, either because GeckoViewPermissionProcessChild
2042// gets destroyed before ask-device-permission receives its
2043// got-device-permission reply, or because the media thread is no longer
2044// available. In either case, the process is shutting down so the result is
2045// not important. Reject with a dummy error so the following Then-handler can
2046// resolve with an empty set, so that callers do not need to handle rejection.
2047class DeviceAccessRequestPromiseHolderWithFallback
2048 : public MozPromiseHolder<MozPromise<
2049 CamerasAccessStatus, mozilla::ipc::ResponseRejectReason, true>> {
2050 public:
2051 DeviceAccessRequestPromiseHolderWithFallback() = default;
2052 DeviceAccessRequestPromiseHolderWithFallback(
2053 DeviceAccessRequestPromiseHolderWithFallback&&) = default;
2054 ~DeviceAccessRequestPromiseHolderWithFallback() {
2055 if (!IsEmpty()) {
2056 Reject(ipc::ResponseRejectReason::ChannelClosed, __func__);
2057 }
2058 }
2059};
2060
2061} // anonymous namespace
2062
2063MediaManager::DeviceEnumerationParams::DeviceEnumerationParams(
2064 dom::MediaSourceEnum aInputType, DeviceType aType,
2065 nsAutoCString aForcedDeviceName)
2066 : mInputType(aInputType),
2067 mType(aType),
2068 mForcedDeviceName(std::move(aForcedDeviceName)) {
2069 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2069); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2069); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2070 MOZ_ASSERT(mInputType != dom::MediaSourceEnum::Other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInputType != dom::MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mInputType != dom::MediaSourceEnum::Other))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mInputType != dom::MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 2070); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mInputType != dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2070); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2071 MOZ_ASSERT_IF(!mForcedDeviceName.IsEmpty(), mType == DeviceType::Real)do { if (!mForcedDeviceName.IsEmpty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(mType == DeviceType
::Real)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mType == DeviceType::Real))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mType == DeviceType::Real", "./../../../dom/media/MediaManager.cpp"
, 2071); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mType == DeviceType::Real"
")"); do { MOZ_CrashSequence(__null, 2071); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2072}
2073
2074MediaManager::VideoDeviceEnumerationParams::VideoDeviceEnumerationParams(
2075 dom::MediaSourceEnum aInputType, DeviceType aType,
2076 nsAutoCString aForcedDeviceName, nsAutoCString aForcedMicrophoneName)
2077 : DeviceEnumerationParams(aInputType, aType, std::move(aForcedDeviceName)),
2078 mForcedMicrophoneName(std::move(aForcedMicrophoneName)) {
2079 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2079); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2079); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2080 MOZ_ASSERT_IF(!mForcedMicrophoneName.IsEmpty(),do { if (!mForcedMicrophoneName.IsEmpty()) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(mInputType
== dom::MediaSourceEnum::Camera)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputType == dom::MediaSourceEnum
::Camera))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2081); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2081); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2081 mInputType == dom::MediaSourceEnum::Camera)do { if (!mForcedMicrophoneName.IsEmpty()) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(mInputType
== dom::MediaSourceEnum::Camera)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputType == dom::MediaSourceEnum
::Camera))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2081); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2081); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2082 MOZ_ASSERT_IF(!mForcedMicrophoneName.IsEmpty(), mType == DeviceType::Real)do { if (!mForcedMicrophoneName.IsEmpty()) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(mType ==
DeviceType::Real)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mType == DeviceType::Real)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("mType == DeviceType::Real"
, "./../../../dom/media/MediaManager.cpp", 2082); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mType == DeviceType::Real" ")"); do { MOZ_CrashSequence
(__null, 2082); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
2083}
2084
2085MediaManager::EnumerationParams::EnumerationParams(
2086 EnumerationFlags aFlags, Maybe<VideoDeviceEnumerationParams> aVideo,
2087 Maybe<DeviceEnumerationParams> aAudio)
2088 : mFlags(aFlags), mVideo(std::move(aVideo)), mAudio(std::move(aAudio)) {
2089 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2089); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2089); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2090 MOZ_ASSERT_IF(mVideo, MediaEngineSource::IsVideo(mVideo->mInputType))do { if (mVideo) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(MediaEngineSource::IsVideo(mVideo->mInputType
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(MediaEngineSource::IsVideo(mVideo->mInputType))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("MediaEngineSource::IsVideo(mVideo->mInputType)"
, "./../../../dom/media/MediaManager.cpp", 2090); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaEngineSource::IsVideo(mVideo->mInputType)"
")"); do { MOZ_CrashSequence(__null, 2090); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2091 MOZ_ASSERT_IF(mVideo && !mVideo->mForcedDeviceName.IsEmpty(),do { if (mVideo && !mVideo->mForcedDeviceName.IsEmpty
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mVideo->mInputType == dom::MediaSourceEnum::Camera
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mVideo->mInputType == dom::MediaSourceEnum::Camera
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mVideo->mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2092); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2092 mVideo->mInputType == dom::MediaSourceEnum::Camera)do { if (mVideo && !mVideo->mForcedDeviceName.IsEmpty
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mVideo->mInputType == dom::MediaSourceEnum::Camera
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mVideo->mInputType == dom::MediaSourceEnum::Camera
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mVideo->mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2092); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2093 MOZ_ASSERT_IF(mVideo && mVideo->mType == DeviceType::Fake,do { if (mVideo && mVideo->mType == DeviceType::Fake
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mVideo->mInputType == dom::MediaSourceEnum::Camera
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mVideo->mInputType == dom::MediaSourceEnum::Camera
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mVideo->mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2094); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2094); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2094 mVideo->mInputType == dom::MediaSourceEnum::Camera)do { if (mVideo && mVideo->mType == DeviceType::Fake
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mVideo->mInputType == dom::MediaSourceEnum::Camera
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mVideo->mInputType == dom::MediaSourceEnum::Camera
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mVideo->mInputType == dom::MediaSourceEnum::Camera", "./../../../dom/media/MediaManager.cpp"
, 2094); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2094); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2095 MOZ_ASSERT_IF(mAudio, MediaEngineSource::IsAudio(mAudio->mInputType))do { if (mAudio) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(MediaEngineSource::IsAudio(mAudio->mInputType
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(MediaEngineSource::IsAudio(mAudio->mInputType))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("MediaEngineSource::IsAudio(mAudio->mInputType)"
, "./../../../dom/media/MediaManager.cpp", 2095); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaEngineSource::IsAudio(mAudio->mInputType)"
")"); do { MOZ_CrashSequence(__null, 2095); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2096 MOZ_ASSERT_IF(mAudio && !mAudio->mForcedDeviceName.IsEmpty(),do { if (mAudio && !mAudio->mForcedDeviceName.IsEmpty
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mAudio->mInputType == dom::MediaSourceEnum::Microphone
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mAudio->mInputType == dom::MediaSourceEnum::Microphone
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mAudio->mInputType == dom::MediaSourceEnum::Microphone", "./../../../dom/media/MediaManager.cpp"
, 2097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2097); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2097 mAudio->mInputType == dom::MediaSourceEnum::Microphone)do { if (mAudio && !mAudio->mForcedDeviceName.IsEmpty
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mAudio->mInputType == dom::MediaSourceEnum::Microphone
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mAudio->mInputType == dom::MediaSourceEnum::Microphone
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mAudio->mInputType == dom::MediaSourceEnum::Microphone", "./../../../dom/media/MediaManager.cpp"
, 2097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2097); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2098 MOZ_ASSERT_IF(mAudio && mAudio->mType == DeviceType::Fake,do { if (mAudio && mAudio->mType == DeviceType::Fake
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mAudio->mInputType == dom::MediaSourceEnum::Microphone
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mAudio->mInputType == dom::MediaSourceEnum::Microphone
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mAudio->mInputType == dom::MediaSourceEnum::Microphone", "./../../../dom/media/MediaManager.cpp"
, 2099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2099); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2099 mAudio->mInputType == dom::MediaSourceEnum::Microphone)do { if (mAudio && mAudio->mType == DeviceType::Fake
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(mAudio->mInputType == dom::MediaSourceEnum::Microphone
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mAudio->mInputType == dom::MediaSourceEnum::Microphone
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mAudio->mInputType == dom::MediaSourceEnum::Microphone", "./../../../dom/media/MediaManager.cpp"
, 2099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2099); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2100}
2101
2102bool MediaManager::EnumerationParams::HasFakeCams() const {
2103 return mVideo
2104 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2105 .valueOr(false);
2106}
2107
2108bool MediaManager::EnumerationParams::HasFakeMics() const {
2109 return mAudio
2110 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2111 .valueOr(false);
2112}
2113
2114bool MediaManager::EnumerationParams::RealDeviceRequested() const {
2115 auto isReal = [](const auto& aDev) { return aDev.mType == DeviceType::Real; };
2116 return mVideo.map(isReal).valueOr(false) ||
2117 mAudio.map(isReal).valueOr(false) ||
2118 mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2119}
2120
2121MediaSourceEnum MediaManager::EnumerationParams::VideoInputType() const {
2122 return mVideo.map([](const auto& aDev) { return aDev.mInputType; })
2123 .valueOr(MediaSourceEnum::Other);
2124}
2125
2126MediaSourceEnum MediaManager::EnumerationParams::AudioInputType() const {
2127 return mAudio.map([](const auto& aDev) { return aDev.mInputType; })
2128 .valueOr(MediaSourceEnum::Other);
2129}
2130
2131/* static */ MediaManager::EnumerationParams
2132MediaManager::CreateEnumerationParams(dom::MediaSourceEnum aVideoInputType,
2133 dom::MediaSourceEnum aAudioInputType,
2134 EnumerationFlags aFlags) {
2135 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2135); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2135); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2136 MOZ_ASSERT_IF(!MediaEngineSource::IsVideo(aVideoInputType),do { if (!MediaEngineSource::IsVideo(aVideoInputType)) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(aVideoInputType == dom::MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aVideoInputType == dom::MediaSourceEnum::Other))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aVideoInputType == dom::MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 2137); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2137); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2137 aVideoInputType == dom::MediaSourceEnum::Other)do { if (!MediaEngineSource::IsVideo(aVideoInputType)) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(aVideoInputType == dom::MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aVideoInputType == dom::MediaSourceEnum::Other))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aVideoInputType == dom::MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 2137); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2137); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2138 MOZ_ASSERT_IF(!MediaEngineSource::IsAudio(aAudioInputType),do { if (!MediaEngineSource::IsAudio(aAudioInputType)) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(aAudioInputType == dom::MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aAudioInputType == dom::MediaSourceEnum::Other))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aAudioInputType == dom::MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 2139); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2139); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2139 aAudioInputType == dom::MediaSourceEnum::Other)do { if (!MediaEngineSource::IsAudio(aAudioInputType)) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(aAudioInputType == dom::MediaSourceEnum::Other)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aAudioInputType == dom::MediaSourceEnum::Other))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aAudioInputType == dom::MediaSourceEnum::Other"
, "./../../../dom/media/MediaManager.cpp", 2139); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2139); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2140 const bool forceFakes = aFlags.contains(EnumerationFlag::ForceFakes);
2141 const bool fakeByPref = Preferences::GetBool("media.navigator.streams.fake");
2142 Maybe<VideoDeviceEnumerationParams> videoParams;
2143 Maybe<DeviceEnumerationParams> audioParams;
2144 nsAutoCString audioDev;
2145 bool audioDevRead = false;
2146 constexpr const char* VIDEO_DEV_NAME = "media.video_loopback_dev";
2147 constexpr const char* AUDIO_DEV_NAME = "media.audio_loopback_dev";
2148 const auto ensureDev = [](const char* aPref, nsAutoCString* aLoopDev,
2149 bool* aPrefRead) {
2150 if (aPrefRead) {
2151 if (*aPrefRead) {
2152 return;
2153 }
2154 *aPrefRead = true;
2155 }
2156
2157 if (NS_FAILED(Preferences::GetCString(aPref, *aLoopDev))((bool)(__builtin_expect(!!(NS_FAILED_impl(Preferences::GetCString
(aPref, *aLoopDev))), 0)))
) {
2158 // Ensure we fall back to an empty string if reading the pref failed.
2159 aLoopDev->SetIsVoid(true);
2160 }
2161 };
2162 if (MediaEngineSource::IsVideo(aVideoInputType)) {
2163 nsAutoCString videoDev;
2164 DeviceType type = DeviceType::Real;
2165 if (aVideoInputType == MediaSourceEnum::Camera) {
2166 // Fake and loopback devices are supported for only Camera.
2167 if (forceFakes) {
2168 type = DeviceType::Fake;
2169 } else {
2170 ensureDev(VIDEO_DEV_NAME, &videoDev, nullptr);
2171 // Loopback prefs take precedence over fake prefs
2172 if (fakeByPref && videoDev.IsEmpty()) {
2173 type = DeviceType::Fake;
2174 } else {
2175 // For groupId correlation we need the audio device name.
2176 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2177 }
2178 }
2179 }
2180 videoParams = Some(VideoDeviceEnumerationParams(
2181 aVideoInputType, type, std::move(videoDev), audioDev));
2182 }
2183 if (MediaEngineSource::IsAudio(aAudioInputType)) {
2184 nsAutoCString realAudioDev;
2185 DeviceType type = DeviceType::Real;
2186 if (aAudioInputType == MediaSourceEnum::Microphone) {
2187 // Fake and loopback devices are supported for only Microphone.
2188 if (forceFakes) {
2189 type = DeviceType::Fake;
2190 } else {
2191 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2192 // Loopback prefs take precedence over fake prefs
2193 if (fakeByPref && audioDev.IsEmpty()) {
2194 type = DeviceType::Fake;
2195 } else {
2196 realAudioDev = std::move(audioDev);
2197 }
2198 }
2199 }
2200 audioParams = Some(DeviceEnumerationParams(aAudioInputType, type,
2201 std::move(realAudioDev)));
2202 }
2203 return EnumerationParams(aFlags, std::move(videoParams),
2204 std::move(audioParams));
2205}
2206
2207RefPtr<DeviceSetPromise>
2208MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
2209 EnumerationParams aParams) {
2210 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2210); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2210); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2211 MOZ_ASSERT(aParams.mVideo.isSome() || aParams.mAudio.isSome() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParams.mVideo.isSome() || aParams.mAudio.isSome() ||
aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aParams.mVideo.isSome() || aParams.mAudio.isSome() ||
aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
, "./../../../dom/media/MediaManager.cpp", 2212); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { MOZ_CrashSequence(__null, 2212); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2212 aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParams.mVideo.isSome() || aParams.mAudio.isSome() ||
aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aParams.mVideo.isSome() || aParams.mAudio.isSome() ||
aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
, "./../../../dom/media/MediaManager.cpp", 2212); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { MOZ_CrashSequence(__null, 2212); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2213
2214 LOG("{}: aVideoInputType={}, aAudioInputType={}", __func__,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aVideoInputType={}, aAudioInputType={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, static_cast<uint8_t>(aParams
.VideoInputType()), static_cast<uint8_t>(aParams.AudioInputType
())); } } while (0)
2215 static_cast<uint8_t>(aParams.VideoInputType()),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aVideoInputType={}, aAudioInputType={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, static_cast<uint8_t>(aParams
.VideoInputType()), static_cast<uint8_t>(aParams.AudioInputType
())); } } while (0)
2216 static_cast<uint8_t>(aParams.AudioInputType()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: aVideoInputType={}, aAudioInputType={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, static_cast<uint8_t>(aParams
.VideoInputType()), static_cast<uint8_t>(aParams.AudioInputType
())); } } while (0)
;
2217
2218 if (sHasMainThreadShutdown) {
2219 // The media thread is no longer available but the result will not be
2220 // observable.
2221 return DeviceSetPromise::CreateAndResolve(
2222 new MediaDeviceSetRefCnt(),
2223 "MaybeRequestPermissionAndEnumerateRawDevices: sync shutdown");
2224 }
2225
2226 const bool hasVideo = aParams.mVideo.isSome();
2227 const bool hasAudio = aParams.mAudio.isSome();
2228 const bool hasAudioOutput =
2229 aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2230 const bool hasFakeCams = aParams.HasFakeCams();
2231 const bool hasFakeMics = aParams.HasFakeMics();
2232 // True if at least one of video input or audio input is a real device
2233 // or there is audio output.
2234 const bool realDeviceRequested = (!hasFakeCams && hasVideo) ||
2235 (!hasFakeMics && hasAudio) || hasAudioOutput;
2236
2237 using NativePromise =
2238 MozPromise<CamerasAccessStatus, mozilla::ipc::ResponseRejectReason,
2239 /* IsExclusive = */ true>;
2240 RefPtr<NativePromise> deviceAccessPromise;
2241 if (realDeviceRequested &&
2242 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
2243 Preferences::GetBool("media.navigator.permission.device", false)) {
2244 // Need to ask permission to retrieve list of all devices;
2245 // notify frontend observer and wait for callback notification to post
2246 // task.
2247 const char16_t* const type =
2248 (aParams.VideoInputType() != MediaSourceEnum::Camera) ? u"audio"
2249 : (aParams.AudioInputType() != MediaSourceEnum::Microphone) ? u"video"
2250 : u"all";
2251 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2252 DeviceAccessRequestPromiseHolderWithFallback deviceAccessPromiseHolder;
2253 deviceAccessPromise = deviceAccessPromiseHolder.Ensure(__func__);
2254 RefPtr task = NS_NewRunnableFunction(
2255 __func__, [holder = std::move(deviceAccessPromiseHolder)]() mutable {
2256 holder.Resolve(CamerasAccessStatus::Granted,
2257 "getUserMedia:got-device-permission");
2258 });
2259 obs->NotifyObservers(static_cast<nsIRunnable*>(task),
2260 "getUserMedia:ask-device-permission", type);
2261 } else if (realDeviceRequested && hasVideo &&
2262 aParams.VideoInputType() == MediaSourceEnum::Camera) {
2263 ipc::PBackgroundChild* backgroundChild =
2264 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2265 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(
2266 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest));
2267 }
2268
2269 if (!deviceAccessPromise) {
2270 // No device access request needed. We can proceed directly, but we still
2271 // need to update camera availability, because the camera engine is always
2272 // created together with the WebRTC backend, which is done because
2273 // devicechange events must work before prompting in cases where persistent
2274 // permission has already been given. Making a request to camera access not
2275 // allowing a permission request does exactly what we need in this case.
2276 ipc::PBackgroundChild* backgroundChild =
2277 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2278 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(false);
2279 }
2280
2281 return deviceAccessPromise->Then(
2282 GetCurrentSerialEventTarget(), __func__,
2283 [this, self = RefPtr(this), aParams = std::move(aParams)](
2284 NativePromise::ResolveOrRejectValue&& aValue) mutable {
2285 if (sHasMainThreadShutdown) {
2286 return DeviceSetPromise::CreateAndResolve(
2287 new MediaDeviceSetRefCnt(),
2288 "MaybeRequestPermissionAndEnumerateRawDevices: async shutdown");
2289 }
2290
2291 if (aValue.IsReject()) {
2292 // IPC failure probably means we're in shutdown. Resolve with
2293 // an empty set, so that callers do not need to handle rejection.
2294 return DeviceSetPromise::CreateAndResolve(
2295 new MediaDeviceSetRefCnt(),
2296 "MaybeRequestPermissionAndEnumerateRawDevices: ipc failure");
2297 }
2298
2299 if (auto v = aValue.ResolveValue();
2300 v == CamerasAccessStatus::Error ||
2301 v == CamerasAccessStatus::Rejected) {
2302 LOG("Request to camera access {}",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Request to camera access {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "Request to camera access {}", MOZ_LOG_EXPAND_ARGS
v == CamerasAccessStatus::Rejected ? "was rejected" : "failed"
); } } while (0)
2303 v == CamerasAccessStatus::Rejected ? "was rejected" : "failed")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Request to camera access {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "Request to camera access {}", MOZ_LOG_EXPAND_ARGS
v == CamerasAccessStatus::Rejected ? "was rejected" : "failed"
); } } while (0)
;
2304 if (v == CamerasAccessStatus::Error) {
2305 NS_WARNING("Failed to request camera access")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to request camera access"
, nullptr, "./../../../dom/media/MediaManager.cpp", 2305)
;
2306 }
2307 return DeviceSetPromise::CreateAndReject(
2308 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2309 "MaybeRequestPermissionAndEnumerateRawDevices: camera access "
2310 "rejected");
2311 }
2312
2313 // We have to nest this, unfortunately, since we have no guarantees that
2314 // mMediaThread is alive. If we'd reject due to shutdown above, and have
2315 // the below async operation in a Then handler on the media thread the
2316 // Then handler would fail to dispatch and trip an assert on
2317 // destruction, for instance.
2318 return InvokeAsync(
2319 mMediaThread, __func__, [aParams = std::move(aParams)]() mutable {
2320 return DeviceSetPromise::CreateAndResolve(
2321 EnumerateRawDevices(std::move(aParams)),
2322 "MaybeRequestPermissionAndEnumerateRawDevices: success");
2323 });
2324 });
2325}
2326
2327/**
2328 * EnumerateRawDevices - Enumerate a list of audio & video devices that
2329 * satisfy passed-in constraints. List contains raw id's.
2330 */
2331
2332/* static */ RefPtr<MediaManager::MediaDeviceSetRefCnt>
2333MediaManager::EnumerateRawDevices(EnumerationParams aParams) {
2334 MOZ_ASSERT(IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "./../../../dom/media/MediaManager.cpp", 2334); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "IsInMediaThread()" ")"); do { MOZ_CrashSequence
(__null, 2334); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2335 // Only enumerate what's asked for, and only fake cams and mics.
2336 RefPtr<MediaEngine> fakeBackend, realBackend;
2337 if (aParams.HasFakeCams() || aParams.HasFakeMics()) {
2338 fakeBackend = new MediaEngineFake();
2339 }
2340 if (aParams.RealDeviceRequested()) {
2341 MediaManager* manager = MediaManager::GetIfExists();
2342 MOZ_RELEASE_ASSERT(manager, "Must exist while media thread is alive")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(manager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(manager))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("manager" " (" "Must exist while media thread is alive"
")", "./../../../dom/media/MediaManager.cpp", 2342); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "manager" ") (" "Must exist while media thread is alive"
")"); do { MOZ_CrashSequence(__null, 2342); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2343 realBackend = manager->GetBackend();
2344 }
2345
2346 RefPtr<MediaEngine> videoBackend;
2347 RefPtr<MediaEngine> audioBackend;
2348 Maybe<MediaDeviceSet> micsOfVideoBackend;
2349 Maybe<MediaDeviceSet> speakers;
2350 RefPtr devices = new MediaDeviceSetRefCnt();
2351
2352 // Enumerate microphones first, then cameras, then speakers, since
2353 // the enumerateDevices() algorithm expects them listed in that order.
2354 if (const auto& audio = aParams.mAudio; audio.isSome()) {
2355 audioBackend = aParams.HasFakeMics() ? fakeBackend : realBackend;
2356 MediaDeviceSet audios;
2357 LOG("EnumerateRawDevices: Getting audio sources with {} backend",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting audio sources with {} backend"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "EnumerateRawDevices: Getting audio sources with {} backend"
, MOZ_LOG_EXPAND_ARGS audioBackend == fakeBackend ? "fake" : "real"
); } } while (0)
2358 audioBackend == fakeBackend ? "fake" : "real")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting audio sources with {} backend"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "EnumerateRawDevices: Getting audio sources with {} backend"
, MOZ_LOG_EXPAND_ARGS audioBackend == fakeBackend ? "fake" : "real"
); } } while (0)
;
2359 GetMediaDevices(audioBackend, audio->mInputType, audios,
2360 audio->mForcedDeviceName.get());
2361 if (audio->mInputType == MediaSourceEnum::Microphone &&
2362 audioBackend == videoBackend) {
2363 micsOfVideoBackend.emplace();
2364 micsOfVideoBackend->AppendElements(audios);
2365 }
2366 devices->AppendElements(std::move(audios));
2367 }
2368 if (const auto& video = aParams.mVideo; video.isSome()) {
2369 videoBackend = aParams.HasFakeCams() ? fakeBackend : realBackend;
2370 MediaDeviceSet videos;
2371 LOG("EnumerateRawDevices: Getting video sources with {} backend",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting video sources with {} backend"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "EnumerateRawDevices: Getting video sources with {} backend"
, MOZ_LOG_EXPAND_ARGS videoBackend == fakeBackend ? "fake" : "real"
); } } while (0)
2372 videoBackend == fakeBackend ? "fake" : "real")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting video sources with {} backend"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "EnumerateRawDevices: Getting video sources with {} backend"
, MOZ_LOG_EXPAND_ARGS videoBackend == fakeBackend ? "fake" : "real"
); } } while (0)
;
2373 GetMediaDevices(videoBackend, video->mInputType, videos,
2374 video->mForcedDeviceName.get());
2375 devices->AppendElements(std::move(videos));
2376 }
2377 if (aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)) {
2378 MediaDeviceSet outputs;
2379 MOZ_ASSERT(realBackend)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(realBackend)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(realBackend))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("realBackend", "./../../../dom/media/MediaManager.cpp"
, 2379); AnnotateMozCrashReason("MOZ_ASSERT" "(" "realBackend"
")"); do { MOZ_CrashSequence(__null, 2379); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2380 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2381 MediaSinkEnum::Speaker, &outputs);
2382 speakers = Some(MediaDeviceSet());
2383 speakers->AppendElements(outputs);
2384 devices->AppendElements(std::move(outputs));
2385 }
2386 if (aParams.VideoInputType() == MediaSourceEnum::Camera) {
2387 MediaDeviceSet audios;
2388 LOG("EnumerateRawDevices: Getting audio sources with {} backend for "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation", MOZ_LOG_EXPAND_ARGS videoBackend == fakeBackend
? "fake" : "real"); } } while (0)
2389 "groupId correlation",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation", MOZ_LOG_EXPAND_ARGS videoBackend == fakeBackend
? "fake" : "real"); } } while (0)
2390 videoBackend == fakeBackend ? "fake" : "real")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "EnumerateRawDevices: Getting audio sources with {} backend for "
"groupId correlation", MOZ_LOG_EXPAND_ARGS videoBackend == fakeBackend
? "fake" : "real"); } } while (0)
;
2391 // We need to correlate cameras with audio groupIds. We use the backend of
2392 // the camera to always do correlation on devices in the same scope. If we
2393 // don't do this, video-only getUserMedia will not apply groupId constraints
2394 // to the same set of groupIds as gets returned by enumerateDevices.
2395 if (micsOfVideoBackend.isSome()) {
2396 // Microphones from the same backend used for the cameras have
2397 // already been enumerated. Avoid doing it again.
2398 MOZ_ASSERT(aParams.mVideo->mForcedMicrophoneName ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParams.mVideo->mForcedMicrophoneName == aParams.
mAudio->mForcedDeviceName)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aParams.mVideo->mForcedMicrophoneName
== aParams.mAudio->mForcedDeviceName))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
, "./../../../dom/media/MediaManager.cpp", 2399); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { MOZ_CrashSequence(__null, 2399); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2399 aParams.mAudio->mForcedDeviceName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParams.mVideo->mForcedMicrophoneName == aParams.
mAudio->mForcedDeviceName)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aParams.mVideo->mForcedMicrophoneName
== aParams.mAudio->mForcedDeviceName))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
, "./../../../dom/media/MediaManager.cpp", 2399); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { MOZ_CrashSequence(__null, 2399); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2400 audios.AppendElements(micsOfVideoBackend.extract());
2401 } else {
2402 GetMediaDevices(videoBackend, MediaSourceEnum::Microphone, audios,
2403 aParams.mVideo->mForcedMicrophoneName.get());
2404 }
2405 if (videoBackend == realBackend) {
2406 // When using the real backend for video, there could also be
2407 // speakers to correlate with. There are no fake speakers.
2408 if (speakers.isSome()) {
2409 // Speakers have already been enumerated. Avoid doing it again.
2410 audios.AppendElements(speakers.extract());
2411 } else {
2412 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2413 MediaSinkEnum::Speaker, &audios);
2414 }
2415 }
2416 GuessVideoDeviceGroupIDs(*devices, audios);
2417 }
2418
2419 return devices;
2420}
2421
2422RefPtr<ConstDeviceSetPromise> MediaManager::GetPhysicalDevices() {
2423 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2423); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2423); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2424 if (mPhysicalDevices) {
2425 return ConstDeviceSetPromise::CreateAndResolve(mPhysicalDevices, __func__);
2426 }
2427 if (mPendingDevicesPromises) {
2428 // Enumeration is already in progress.
2429 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2430 }
2431 mPendingDevicesPromises =
2432 new Refcountable<nsTArray<MozPromiseHolder<ConstDeviceSetPromise>>>;
2433 MaybeRequestPermissionAndEnumerateRawDevices(
2434 CreateEnumerationParams(MediaSourceEnum::Camera,
2435 MediaSourceEnum::Microphone,
2436 EnumerationFlag::EnumerateAudioOutputs))
2437 ->Then(
2438 GetCurrentSerialEventTarget(), __func__,
2439 [self = RefPtr(this), this, promises = mPendingDevicesPromises](
2440 RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
2441 for (auto& promiseHolder : *promises) {
2442 promiseHolder.Resolve(aDevices, __func__);
2443 }
2444 // mPendingDevicesPromises may have changed if devices have changed.
2445 if (promises == mPendingDevicesPromises) {
2446 mPendingDevicesPromises = nullptr;
2447 mPhysicalDevices = std::move(aDevices);
2448 }
2449 },
2450 [](RefPtr<MediaMgrError>&& reason) {
2451 MOZ_ASSERT_UNREACHABLE(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")", "./../../../dom/media/MediaManager.cpp", 2452); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2452); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2452 "MaybeRequestPermissionAndEnumerateRawDevices does not reject")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")", "./../../../dom/media/MediaManager.cpp", 2452); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2452); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2453 });
2454
2455 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2456}
2457
2458MediaManager::MediaManager(already_AddRefed<TaskQueue> aMediaThread)
2459 : mMediaThread(aMediaThread), mBackend(nullptr) {
2460 mPrefs.mFreq = 1000; // 1KHz test tone
2461 mPrefs.mWidth = 0; // adaptive default
2462 mPrefs.mHeight = 0; // adaptive default
2463 mPrefs.mResizeModeEnabled = false;
2464 mPrefs.mResizeMode = VideoResizeModeEnum::None;
2465 mPrefs.mFPS = MediaEnginePrefs::DEFAULT_VIDEO_FPS;
2466 mPrefs.mUsePlatformProcessing = false;
2467 mPrefs.mAecOn = false;
2468 mPrefs.mAgcOn = false;
2469 mPrefs.mHPFOn = false;
2470 mPrefs.mNoiseOn = false;
2471 mPrefs.mTransientOn = false;
2472 mPrefs.mAgc2Forced = false;
2473 mPrefs.mExpectDrift = -1; // auto
2474#ifdef MOZ_WEBRTC1
2475 mPrefs.mAgc =
2476 webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
2477 mPrefs.mNoise =
2478 webrtc::AudioProcessing::Config::NoiseSuppression::Level::kModerate;
2479#else
2480 mPrefs.mAgc = 0;
2481 mPrefs.mNoise = 0;
2482#endif
2483 mPrefs.mChannels = 0; // max channels default
2484 nsresult rv;
2485 nsCOMPtr<nsIPrefService> prefs =
2486 do_GetService("@mozilla.org/preferences-service;1", &rv);
2487 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2488 nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
2489 if (branch) {
2490 GetPrefs(branch, nullptr);
2491 }
2492 }
2493}
2494
2495NS_IMPL_ISUPPORTS(MediaManager, nsIMediaManagerService, nsIMemoryReporter,MozExternalRefCountType MediaManager::AddRef(void) { static_assert
(!std::is_destructible_v<MediaManager>, "Reference-counted class "
"MediaManager" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 2496
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MediaManager" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("MediaManager" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"MediaManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2496); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MediaManager" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("MediaManager"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
MediaManager::Release(void) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../dom/media/MediaManager.cpp", 2496); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release"
")"); do { MOZ_CrashSequence(__null, 2496); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("MediaManager"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("MediaManager" != nullptr))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("\"MediaManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2496); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MediaManager" " not thread-safe"); const char
* const nametmp = "MediaManager"; nsrefcnt count = --mRefCnt;
NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
MediaManager::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "./../../../dom/media/MediaManager.cpp", 2496); MOZ_PretendNoReturn
(); } } while (0); nsresult rv = NS_ERROR_FAILURE; static_assert
(3 > 0, "Need more arguments to NS_INTERFACE_TABLE"); static
const QITableEntry table[] = { {&mozilla::detail::kImplementedIID
<MediaManager, nsIMediaManagerService>, int32_t( reinterpret_cast
<char*>(static_cast<nsIMediaManagerService*>((MediaManager
*)0x1000)) - reinterpret_cast<char*>((MediaManager*)0x1000
))}, {&mozilla::detail::kImplementedIID<MediaManager, nsIMemoryReporter
>, int32_t( reinterpret_cast<char*>(static_cast<nsIMemoryReporter
*>((MediaManager*)0x1000)) - reinterpret_cast<char*>
((MediaManager*)0x1000))}, {&mozilla::detail::kImplementedIID
<MediaManager, nsIObserver>, int32_t( reinterpret_cast<
char*>(static_cast<nsIObserver*>((MediaManager*)0x1000
)) - reinterpret_cast<char*>((MediaManager*)0x1000))}, {
&mozilla::detail::kImplementedIID<MediaManager, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIMediaManagerService*>((MediaManager
*)0x1000))) - reinterpret_cast<char*>((MediaManager*)0x1000
))}, { nullptr, 0 } } ; static_assert(std::size(table) > 1
, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast
<void*>(this), aIID, aInstancePtr, table); return rv; }
2496 nsIObserver)MozExternalRefCountType MediaManager::AddRef(void) { static_assert
(!std::is_destructible_v<MediaManager>, "Reference-counted class "
"MediaManager" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 2496
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MediaManager" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("MediaManager" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"MediaManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2496); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MediaManager" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("MediaManager"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
MediaManager::Release(void) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../dom/media/MediaManager.cpp", 2496); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release"
")"); do { MOZ_CrashSequence(__null, 2496); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("MediaManager"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("MediaManager" != nullptr))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("\"MediaManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/media/MediaManager.cpp"
, 2496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2496); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MediaManager" " not thread-safe"); const char
* const nametmp = "MediaManager"; nsrefcnt count = --mRefCnt;
NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
MediaManager::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "./../../../dom/media/MediaManager.cpp", 2496); MOZ_PretendNoReturn
(); } } while (0); nsresult rv = NS_ERROR_FAILURE; static_assert
(3 > 0, "Need more arguments to NS_INTERFACE_TABLE"); static
const QITableEntry table[] = { {&mozilla::detail::kImplementedIID
<MediaManager, nsIMediaManagerService>, int32_t( reinterpret_cast
<char*>(static_cast<nsIMediaManagerService*>((MediaManager
*)0x1000)) - reinterpret_cast<char*>((MediaManager*)0x1000
))}, {&mozilla::detail::kImplementedIID<MediaManager, nsIMemoryReporter
>, int32_t( reinterpret_cast<char*>(static_cast<nsIMemoryReporter
*>((MediaManager*)0x1000)) - reinterpret_cast<char*>
((MediaManager*)0x1000))}, {&mozilla::detail::kImplementedIID
<MediaManager, nsIObserver>, int32_t( reinterpret_cast<
char*>(static_cast<nsIObserver*>((MediaManager*)0x1000
)) - reinterpret_cast<char*>((MediaManager*)0x1000))}, {
&mozilla::detail::kImplementedIID<MediaManager, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIMediaManagerService*>((MediaManager
*)0x1000))) - reinterpret_cast<char*>((MediaManager*)0x1000
))}, { nullptr, 0 } } ; static_assert(std::size(table) > 1
, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast
<void*>(this), aIID, aInstancePtr, table); return rv; }
2497
2498/* static */
2499StaticRefPtr<MediaManager> MediaManager::sSingleton;
2500
2501#ifdef DEBUG1
2502/* static */
2503bool MediaManager::IsInMediaThread() {
2504 return sSingleton && sSingleton->mMediaThread->IsOnCurrentThread();
2505}
2506#endif
2507
2508template <typename Function>
2509static void ForeachObservedPref(const Function& aFunction) {
2510 aFunction("media.navigator.video.default_width"_ns);
2511 aFunction("media.navigator.video.default_height"_ns);
2512 aFunction("media.navigator.video.default_fps"_ns);
2513 aFunction("media.navigator.audio.fake_frequency"_ns);
2514 aFunction("media.audio_loopback_dev"_ns);
2515 aFunction("media.video_loopback_dev"_ns);
2516 aFunction("media.getusermedia.fake-camera-name"_ns);
2517#ifdef MOZ_WEBRTC1
2518 aFunction("media.navigator.video.resize_mode.enabled"_ns);
2519 aFunction("media.navigator.video.default_resize_mode"_ns);
2520 aFunction("media.getusermedia.audio.processing.aec.enabled"_ns);
2521 aFunction("media.getusermedia.audio.processing.aec"_ns);
2522 aFunction("media.getusermedia.audio.processing.agc.enabled"_ns);
2523 aFunction("media.getusermedia.audio.processing.agc"_ns);
2524 aFunction("media.getusermedia.audio.processing.agc2.forced"_ns);
2525 aFunction("media.getusermedia.audio.processing.hpf.enabled"_ns);
2526 aFunction("media.getusermedia.audio.processing.noise.enabled"_ns);
2527 aFunction("media.getusermedia.audio.processing.noise"_ns);
2528 aFunction("media.getusermedia.audio.max_channels"_ns);
2529 aFunction("media.navigator.streams.fake"_ns);
2530#endif
2531}
2532
2533// NOTE: never NS_DispatchAndSpinEventLoopUntilComplete to the MediaManager
2534// thread from the MainThread, as we NS_DispatchAndSpinEventLoopUntilComplete to
2535// MainThread from MediaManager thread.
2536
2537// Guaranteed never to return nullptr.
2538/* static */
2539MediaManager* MediaManager::Get() {
2540 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2540); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2540); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2541
2542 if (!sSingleton) {
2543 static int timesCreated = 0;
2544 timesCreated++;
2545 MOZ_RELEASE_ASSERT(timesCreated == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(timesCreated == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(timesCreated == 1))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("timesCreated == 1"
, "./../../../dom/media/MediaManager.cpp", 2545); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "timesCreated == 1" ")"); do { MOZ_CrashSequence
(__null, 2545); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2546
2547 RefPtr<TaskQueue> mediaThread =
2548#ifdef MOZ_WEBRTC1
2549 CreateWebrtcTaskQueueWrapper(
2550 GetMediaThreadPool(MediaThreadType::SUPERVISOR), "MediaManager"_ns,
2551 TailDispatchPolicy::NoTailDispatch);
2552#else
2553 TaskQueue::Create(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
2554 "MediaManager", TailDispatchPolicy::NoTailDispatch);
2555#endif
2556 LOG("New Media thread for gum")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "New Media thread for gum")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "New Media thread for gum", MOZ_LOG_EXPAND_ARGS
); } } while (0)
;
2557
2558 sSingleton = new MediaManager(mediaThread.forget());
2559
2560 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2561 if (obs) {
2562 obs->AddObserver(sSingleton, "last-pb-context-exited", false);
2563 obs->AddObserver(sSingleton, "getUserMedia:got-device-permission", false);
2564 obs->AddObserver(sSingleton, "getUserMedia:privileged:allow", false);
2565 obs->AddObserver(sSingleton, "getUserMedia:response:allow", false);
2566 obs->AddObserver(sSingleton, "getUserMedia:response:deny", false);
2567 obs->AddObserver(sSingleton, "getUserMedia:response:noOSPermission",
2568 false);
2569 obs->AddObserver(sSingleton, "getUserMedia:revoke", false);
2570 obs->AddObserver(sSingleton, "getUserMedia:muteVideo", false);
2571 obs->AddObserver(sSingleton, "getUserMedia:unmuteVideo", false);
2572 obs->AddObserver(sSingleton, "getUserMedia:muteAudio", false);
2573 obs->AddObserver(sSingleton, "getUserMedia:unmuteAudio", false);
2574 obs->AddObserver(sSingleton, "application-background", false);
2575 obs->AddObserver(sSingleton, "application-foreground", false);
2576 }
2577 // else MediaManager won't work properly and will leak (see bug 837874)
2578 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
2579 if (prefs) {
2580 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
2581 prefs->AddObserver(aPrefName, sSingleton, false);
2582 });
2583 }
2584 RegisterStrongMemoryReporter(do_AddRef(sSingleton));
2585
2586 // Prepare async shutdown
2587
2588 class Blocker : public media::ShutdownBlocker {
2589 public:
2590 Blocker()
2591 : media::ShutdownBlocker(
2592 u"Media shutdown: blocking on media thread"_ns) {}
2593
2594 NS_IMETHODvirtual nsresult BlockShutdown(nsIAsyncShutdownClient*) override {
2595 MOZ_RELEASE_ASSERT(MediaManager::GetIfExists())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::GetIfExists())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::GetIfExists())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("MediaManager::GetIfExists()"
, "./../../../dom/media/MediaManager.cpp", 2595); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "MediaManager::GetIfExists()" ")");
do { MOZ_CrashSequence(__null, 2595); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2596 MediaManager::GetIfExists()->Shutdown();
2597 return NS_OK;
2598 }
2599 };
2600
2601 sSingleton->mShutdownBlocker = new Blocker();
2602 nsresult rv = media::MustGetShutdownBarrier()->AddBlocker(
2603 sSingleton->mShutdownBlocker, NS_LITERAL_STRING_FROM_CSTRING(__FILE__)static_cast<const nsLiteralString&>( nsLiteralString
(u"" "./../../../dom/media/MediaManager.cpp"))
,
2604 __LINE__2604, u""_ns);
2605 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../dom/media/MediaManager.cpp"
, 2605); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 2605); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2606 }
2607 return sSingleton;
2608}
2609
2610/* static */
2611MediaManager* MediaManager::GetIfExists() {
2612 MOZ_ASSERT(NS_IsMainThread() || IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread() || IsInMediaThread())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(NS_IsMainThread() || IsInMediaThread()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("NS_IsMainThread() || IsInMediaThread()"
, "./../../../dom/media/MediaManager.cpp", 2612); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread() || IsInMediaThread()" ")"
); do { MOZ_CrashSequence(__null, 2612); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2613 return sSingleton;
2614}
2615
2616/* static */
2617already_AddRefed<MediaManager> MediaManager::GetInstance() {
2618 // so we can have non-refcounted getters
2619 RefPtr<MediaManager> service = MediaManager::Get();
2620 return service.forget();
2621}
2622
2623media::Parent<media::NonE10s>* MediaManager::GetNonE10sParent() {
2624 if (!mNonE10sParent) {
2625 mNonE10sParent = new media::Parent<media::NonE10s>();
2626 }
2627 return mNonE10sParent;
2628}
2629
2630/* static */
2631void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
2632 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2632); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2632); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2633 if (sHasMainThreadShutdown) {
2634 // Can't safely delete task here since it may have items with specific
2635 // thread-release requirements.
2636 // XXXkhuey well then who is supposed to delete it?! We don't signal
2637 // that we failed ...
2638 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "./../../../dom/media/MediaManager.cpp"
, 2638); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { MOZ_CrashSequence
(__null, 2638); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
2639 return;
2640 }
2641 NS_ASSERTION(Get(), "MediaManager singleton?")do { if (!(Get())) { NS_DebugBreak(NS_DEBUG_ASSERTION, "MediaManager singleton?"
, "Get()", "./../../../dom/media/MediaManager.cpp", 2641); MOZ_PretendNoReturn
(); } } while (0)
;
2642 NS_ASSERTION(Get()->mMediaThread, "No thread yet")do { if (!(Get()->mMediaThread)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "No thread yet", "Get()->mMediaThread", "./../../../dom/media/MediaManager.cpp"
, 2642); MOZ_PretendNoReturn(); } } while (0)
;
2643 MOZ_ALWAYS_SUCCEEDS(Get()->mMediaThread->Dispatch(std::move(task)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(Get()->mMediaThread->Dispatch(std::move(task)))), 1)))
), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(Get()->mMediaThread->Dispatch(std::move(task)))"
, "./../../../dom/media/MediaManager.cpp", 2643); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(Get()->mMediaThread->Dispatch(std::move(task)))"
")"); do { MOZ_CrashSequence(__null, 2643); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2644}
2645
2646template <typename MozPromiseType, typename FunctionType>
2647/* static */
2648RefPtr<MozPromiseType> MediaManager::Dispatch(StaticString aName,
2649 FunctionType&& aFunction) {
2650 MozPromiseHolder<MozPromiseType> holder;
2651 RefPtr<MozPromiseType> promise = holder.Ensure(aName);
2652 MediaManager::Dispatch(NS_NewRunnableFunction(
2653 aName, [h = std::move(holder), func = std::forward<FunctionType>(
2654 aFunction)]() mutable { func(h); }));
2655 return promise;
2656}
2657
2658/* static */
2659nsresult MediaManager::NotifyRecordingStatusChange(
2660 nsPIDOMWindowInner* aWindow) {
2661 NS_ENSURE_ARG(aWindow)do { if ((__builtin_expect(!!(!(aWindow)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aWindow" ") failed", nullptr
, "./../../../dom/media/MediaManager.cpp", 2661); return NS_ERROR_INVALID_ARG
; } } while (false)
;
2662
2663 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2664 if (!obs) {
2665 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 2667)
2666 "Could not get the Observer service for GetUserMedia recording "NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 2667)
2667 "notification.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 2667)
;
2668 return NS_ERROR_FAILURE;
2669 }
2670
2671 auto props = MakeRefPtr<nsHashPropertyBag>();
2672
2673 nsCString pageURL;
2674 nsCOMPtr<nsIURI> docURI = aWindow->GetDocumentURI();
2675 NS_ENSURE_TRUE(docURI, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(docURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "docURI" ") failed", nullptr
, "./../../../dom/media/MediaManager.cpp", 2675); return NS_ERROR_FAILURE
; } } while (false)
;
2676
2677 nsresult rv = docURI->GetSpec(pageURL);
2678 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../dom/media/MediaManager.cpp"
, 2678); return rv; } } while (false)
;
2679
2680 NS_ConvertUTF8toUTF16 requestURL(pageURL);
2681
2682 props->SetPropertyAsAString(u"requestURL"_ns, requestURL);
2683 props->SetPropertyAsInterface(u"window"_ns, aWindow);
2684
2685 obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
2686 "recording-device-events", nullptr);
2687 LOG("Sent recording-device-events for url '{}'", pageURL.get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Sent recording-device-events for url '{}'")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Sent recording-device-events for url '{}'"
, MOZ_LOG_EXPAND_ARGS pageURL.get()); } } while (0)
;
2688
2689 return NS_OK;
2690}
2691
2692void MediaManager::DeviceListChanged() {
2693 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2693); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2693); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2694 if (sHasMainThreadShutdown) {
2695 return;
2696 }
2697 // Invalidate immediately to provide an up-to-date device list for future
2698 // enumerations on platforms with sane device-list-changed events.
2699 InvalidateDeviceCache();
2700
2701 // Wait 200 ms, because
2702 // A) on some Windows machines, if we call EnumerateRawDevices immediately
2703 // after receiving devicechange event, we'd get an outdated devices list.
2704 // B) Waiting helps coalesce multiple calls on us into one, which can happen
2705 // if a device with both audio input and output is attached or removed.
2706 // We want to react & fire a devicechange event only once in that case.
2707
2708 // The wait is extended if another hardware device-list-changed notification
2709 // is received to provide the full 200ms for EnumerateRawDevices().
2710 if (mDeviceChangeTimer) {
2711 mDeviceChangeTimer->Cancel();
2712 } else {
2713 mDeviceChangeTimer = MakeRefPtr<MediaTimer<TimeStamp>>();
2714 }
2715 // However, if this would cause a delay of over 1000ms in handling the
2716 // oldest unhandled event, then respond now and set the timer to run
2717 // EnumerateRawDevices() again in 200ms.
2718 auto now = TimeStamp::NowLoRes();
2719 auto enumerateDelay = TimeDuration::FromMilliseconds(200);
2720 auto coalescenceLimit = TimeDuration::FromMilliseconds(1000) - enumerateDelay;
2721 if (!mUnhandledDeviceChangeTime) {
2722 mUnhandledDeviceChangeTime = now;
2723 } else if (now - mUnhandledDeviceChangeTime > coalescenceLimit) {
2724 HandleDeviceListChanged();
2725 mUnhandledDeviceChangeTime = now;
2726 }
2727 RefPtr<MediaManager> self = this;
2728 mDeviceChangeTimer->WaitFor(enumerateDelay, __func__)
2729 ->Then(
2730 GetCurrentSerialEventTarget(), __func__,
2731 [self, this] {
2732 // Invalidate again for the sake of platforms with inconsistent
2733 // timing between device-list-changed notification and enumeration.
2734 InvalidateDeviceCache();
2735
2736 mUnhandledDeviceChangeTime = TimeStamp();
2737 HandleDeviceListChanged();
2738 },
2739 [] { /* Timer was canceled by us, or we're in shutdown. */ });
2740}
2741
2742void MediaManager::InvalidateDeviceCache() {
2743 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2743); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2743); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2744
2745 mPhysicalDevices = nullptr;
2746 // Disconnect any in-progress enumeration, which may now be out of date,
2747 // from updating mPhysicalDevices or resolving future device request
2748 // promises.
2749 mPendingDevicesPromises = nullptr;
2750}
2751
2752void MediaManager::HandleDeviceListChanged() {
2753 mDeviceListChangeEvent.Notify();
2754
2755 GetPhysicalDevices()->Then(
2756 GetCurrentSerialEventTarget(), __func__,
2757 [self = RefPtr(this), this](RefPtr<const MediaDeviceSetRefCnt> aDevices) {
2758 if (!MediaManager::GetIfExists()) {
2759 return;
2760 }
2761
2762 nsTHashSet<nsString> deviceIDs;
2763 for (const auto& device : *aDevices) {
2764 deviceIDs.Insert(device->mRawID);
2765 }
2766 // For any real removed cameras or microphones, notify their
2767 // listeners cleanly that the source has stopped, so JS knows and
2768 // usage indicators update.
2769 // First collect the listeners in an array to stop them after
2770 // iterating the hashtable. The StopRawID() method indirectly
2771 // modifies the mActiveWindows and would assert-crash if the
2772 // iterator were active while the table is being enumerated.
2773 const auto windowListeners = ToArray(mActiveWindows.Values());
2774 for (const RefPtr<GetUserMediaWindowListener>& l : windowListeners) {
2775 const auto activeDevices = l->GetDevices();
2776 for (const RefPtr<LocalMediaDevice>& device : *activeDevices) {
2777 if (device->IsFake()) {
2778 continue;
2779 }
2780 MediaSourceEnum mediaSource = device->GetMediaSource();
2781 if (mediaSource != MediaSourceEnum::Microphone &&
2782 mediaSource != MediaSourceEnum::Camera) {
2783 continue;
2784 }
2785 if (!deviceIDs.Contains(device->RawID())) {
2786 // Device has been removed
2787 l->StopRawID(device->RawID());
2788 }
2789 }
2790 }
2791 },
2792 [](RefPtr<MediaMgrError>&& reason) {
2793 MOZ_ASSERT_UNREACHABLE("EnumerateRawDevices does not reject")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"EnumerateRawDevices does not reject" ")", "./../../../dom/media/MediaManager.cpp"
, 2793); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "EnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2793); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2794 });
2795}
2796
2797size_t MediaManager::AddTaskAndGetCount(uint64_t aWindowID,
2798 const nsAString& aCallID,
2799 RefPtr<GetUserMediaTask> aTask) {
2800 // Store the task w/callbacks.
2801 mActiveCallbacks.InsertOrUpdate(aCallID, std::move(aTask));
2802
2803 // Add a WindowID cross-reference so OnNavigation can tear things down
2804 nsTArray<nsString>* const array = mCallIds.GetOrInsertNew(aWindowID);
2805 array->AppendElement(aCallID);
2806
2807 return array->Length();
2808}
2809
2810RefPtr<GetUserMediaTask> MediaManager::TakeGetUserMediaTask(
2811 const nsAString& aCallID) {
2812 RefPtr<GetUserMediaTask> task;
2813 mActiveCallbacks.Remove(aCallID, getter_AddRefs(task));
2814 if (!task) {
2815 return nullptr;
2816 }
2817 nsTArray<nsString>* array;
2818 mCallIds.Get(task->GetWindowID(), &array);
2819 MOZ_ASSERT(array)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(array)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(array))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("array", "./../../../dom/media/MediaManager.cpp"
, 2819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { MOZ_CrashSequence(__null, 2819); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2820 array->RemoveElement(aCallID);
2821 return task;
2822}
2823
2824void MediaManager::NotifyAllowed(const nsString& aCallID,
2825 const LocalMediaDeviceSet& aDevices) {
2826 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2827 nsCOMPtr<nsIMutableArray> devicesCopy = nsArray::Create();
2828 for (const auto& device : aDevices) {
2829 nsresult rv = devicesCopy->AppendElement(device);
2830 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 2830)
) {
2831 obs->NotifyObservers(nullptr, "getUserMedia:response:deny",
2832 aCallID.get());
2833 return;
2834 }
2835 }
2836 obs->NotifyObservers(devicesCopy, "getUserMedia:privileged:allow",
2837 aCallID.get());
2838}
2839
2840nsresult MediaManager::GenerateUUID(nsAString& aResult) {
2841 nsresult rv;
2842 nsCOMPtr<nsIUUIDGenerator> uuidgen =
2843 do_GetService("@mozilla.org/uuid-generator;1", &rv);
2844 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../dom/media/MediaManager.cpp"
, 2844); return rv; } } while (false)
;
2845
2846 // Generate a call ID.
2847 nsID id;
2848 rv = uuidgen->GenerateUUIDInPlace(&id);
2849 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../dom/media/MediaManager.cpp"
, 2849); return rv; } } while (false)
;
2850
2851 char buffer[NSID_LENGTH39];
2852 id.ToProvidedString(buffer);
2853 aResult.Assign(NS_ConvertUTF8toUTF16(buffer));
2854 return NS_OK;
2855}
2856
2857enum class GetUserMediaSecurityState {
2858 Other = 0,
2859 HTTPS = 1,
2860 File = 2,
2861 App = 3,
2862 Localhost = 4,
2863 Loop = 5,
2864 Privileged = 6
2865};
2866
2867/**
2868 * This function is used in getUserMedia when privacy.resistFingerprinting is
2869 * true. Only mediaSource of audio/video constraint will be kept. On mobile
2870 * facing mode is also kept.
2871 */
2872static void ReduceConstraint(
2873 OwningBooleanOrMediaTrackConstraints& aConstraint) {
2874 // Not requesting stream.
2875 if (!MediaManager::IsOn(aConstraint)) {
2876 return;
2877 }
2878
2879 // It looks like {audio: true}, do nothing.
2880 if (!aConstraint.IsMediaTrackConstraints()) {
2881 return;
2882 }
2883
2884 // Keep mediaSource.
2885 Maybe<nsString> mediaSource;
2886 if (aConstraint.GetAsMediaTrackConstraints().mMediaSource.WasPassed()) {
2887 mediaSource =
2888 Some(aConstraint.GetAsMediaTrackConstraints().mMediaSource.Value());
2889 }
2890
2891 Maybe<OwningStringOrStringSequenceOrConstrainDOMStringParameters> facingMode;
2892 if (aConstraint.GetAsMediaTrackConstraints().mFacingMode.WasPassed()) {
2893 facingMode =
2894 Some(aConstraint.GetAsMediaTrackConstraints().mFacingMode.Value());
2895 }
2896
2897 aConstraint.Uninit();
2898 if (mediaSource) {
2899 aConstraint.SetAsMediaTrackConstraints().mMediaSource.Construct(
2900 *mediaSource);
2901 } else {
2902 (void)aConstraint.SetAsMediaTrackConstraints();
2903 }
2904
2905#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_UIKIT)
2906 if (facingMode) {
2907 aConstraint.SetAsMediaTrackConstraints().mFacingMode.Construct(*facingMode);
2908 } else {
2909 (void)aConstraint.SetAsMediaTrackConstraints();
2910 }
2911#endif
2912}
2913
2914/**
2915 * The entry point for this file. A call from MediaDevices::GetUserMedia
2916 * will end up here. MediaManager is a singleton that is responsible
2917 * for handling all incoming getUserMedia calls from every window.
2918 */
2919RefPtr<MediaManager::StreamPromise> MediaManager::GetUserMedia(
2920 nsPIDOMWindowInner* aWindow,
2921 const MediaStreamConstraints& aConstraintsPassedIn,
2922 CallerType aCallerType) {
2923 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 2923); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2923); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2924 MOZ_ASSERT(aWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aWindow", "./../../../dom/media/MediaManager.cpp"
, 2924); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindow" ")"
); do { MOZ_CrashSequence(__null, 2924); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2925 uint64_t windowID = aWindow->WindowID();
2926
2927 MediaStreamConstraints c(aConstraintsPassedIn); // use a modifiable copy
2928
2929 if (sHasMainThreadShutdown) {
2930 return StreamPromise::CreateAndReject(
2931 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError,
2932 "In shutdown"),
2933 __func__);
2934 }
2935
2936 // Determine permissions early (while we still have a stack).
2937
2938 nsIURI* docURI = aWindow->GetDocumentURI();
2939 if (!docURI) {
2940 return StreamPromise::CreateAndReject(
2941 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError), __func__);
2942 }
2943 bool isChrome = (aCallerType == CallerType::System);
2944 bool privileged =
2945 isChrome ||
2946 Preferences::GetBool("media.navigator.permission.disabled", false);
2947 bool isSecure = aWindow->IsSecureContext();
2948 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
2949 nsCString host;
2950 nsresult rv = docURI->GetHost(host);
Value stored to 'rv' during its initialization is never read
2951
2952 nsCOMPtr<nsIPrincipal> principal =
2953 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
2954 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "./../../../dom/media/MediaManager.cpp"
, 2954)
) {
2955 return StreamPromise::CreateAndReject(
2956 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2957 __func__);
2958 }
2959
2960 Document* doc = aWindow->GetExtantDoc();
2961 if (NS_WARN_IF(!doc)NS_warn_if_impl(!doc, "!doc", "./../../../dom/media/MediaManager.cpp"
, 2961)
) {
2962 return StreamPromise::CreateAndReject(
2963 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2964 __func__);
2965 }
2966
2967 // Disallow access to null principal pages and http pages (unless pref)
2968 if (principal->GetIsNullPrincipal() ||
2969 !(isSecure || StaticPrefs::media_getusermedia_insecure_enabled())) {
2970 return StreamPromise::CreateAndReject(
2971 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2972 __func__);
2973 }
2974
2975 // This principal needs to be sent to different threads and so via IPC.
2976 // For this reason it's better to convert it to PrincipalInfo right now.
2977 ipc::PrincipalInfo principalInfo;
2978 rv = PrincipalToPrincipalInfo(principal, &principalInfo);
2979 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 2979)
) {
2980 return StreamPromise::CreateAndReject(
2981 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2982 __func__);
2983 }
2984
2985 const bool resistFingerprinting =
2986 !isChrome && doc->ShouldResistFingerprinting(RFPTarget::MediaDevices);
2987 if (resistFingerprinting) {
2988 ReduceConstraint(c.mVideo);
2989 ReduceConstraint(c.mAudio);
2990 }
2991
2992 if (!Preferences::GetBool("media.navigator.video.enabled", true)) {
2993 c.mVideo.SetAsBoolean() = false;
2994 }
2995
2996 MediaSourceEnum videoType = MediaSourceEnum::Other; // none
2997 MediaSourceEnum audioType = MediaSourceEnum::Other; // none
2998
2999 if (c.mVideo.IsMediaTrackConstraints()) {
3000 auto& vc = c.mVideo.GetAsMediaTrackConstraints();
3001 if (!vc.mMediaSource.WasPassed()) {
3002 vc.mMediaSource.Construct().AssignASCII(
3003 dom::GetEnumString(MediaSourceEnum::Camera));
3004 }
3005 videoType = dom::StringToEnum<MediaSourceEnum>(vc.mMediaSource.Value())
3006 .valueOr(MediaSourceEnum::Other);
3007 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3008 (uint32_t)videoType);
3009 switch (videoType) {
3010 case MediaSourceEnum::Camera:
3011 break;
3012
3013 case MediaSourceEnum::Browser:
3014 // If no window id is passed in then default to the caller's window.
3015 // Functional defaults are helpful in tests, but also a natural outcome
3016 // of the constraints API's limited semantics for requiring input.
3017 if (!vc.mBrowserWindow.WasPassed()) {
3018 nsPIDOMWindowOuter* outer = aWindow->GetOuterWindow();
3019 vc.mBrowserWindow.Construct(outer->WindowID());
3020 }
3021 // Allow tab capture requests from chrome context if device id is
3022 // specified, since no prompt is needed.
3023 if (isChrome && videoType == MediaSourceEnum::Browser &&
3024 c.mVideo.IsMediaTrackConstraints() &&
3025 c.mVideo.GetAsMediaTrackConstraints().mDeviceId.WasPassed()) {
3026 break;
3027 }
3028 [[fallthrough]];
3029 case MediaSourceEnum::Screen:
3030 case MediaSourceEnum::Window:
3031 // Deny screensharing request if support is disabled, or
3032 // the requesting document is not from a host on the whitelist.
3033 if (!Preferences::GetBool(
3034 ((videoType == MediaSourceEnum::Browser)
3035 ? "media.getusermedia.browser.enabled"
3036 : "media.getusermedia.screensharing.enabled"),
3037 false) ||
3038 (!privileged && !aWindow->IsSecureContext())) {
3039 return StreamPromise::CreateAndReject(
3040 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3041 __func__);
3042 }
3043 break;
3044
3045 case MediaSourceEnum::Microphone:
3046 case MediaSourceEnum::Other:
3047 default: {
3048 return StreamPromise::CreateAndReject(
3049 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
3050 "", u"mediaSource"_ns),
3051 __func__);
3052 }
3053 }
3054
3055 if (!privileged) {
3056 // Only allow privileged content to explicitly pick full-screen,
3057 // application or tabsharing, since these modes are still available for
3058 // testing. All others get "Window" (*) sharing.
3059 //
3060 // *) We overload "Window" with the new default getDisplayMedia spec-
3061 // mandated behavior of not influencing user-choice, which we currently
3062 // implement as a list containing BOTH windows AND screen(s).
3063 //
3064 // Notes on why we chose "Window" as the one to overload. Two reasons:
3065 //
3066 // 1. It's the closest logically & behaviorally (multi-choice, no default)
3067 // 2. Screen is still useful in tests (implicit default is entire screen)
3068 //
3069 // For UX reasons we don't want "Entire Screen" to be the first/default
3070 // choice (in our code first=default). It's a "scary" source that comes
3071 // with complicated warnings on-top that would be confusing as the first
3072 // thing people see, and also deserves to be listed as last resort for
3073 // privacy reasons.
3074
3075 if (videoType == MediaSourceEnum::Screen ||
3076 videoType == MediaSourceEnum::Browser) {
3077 videoType = MediaSourceEnum::Window;
3078 vc.mMediaSource.Value().AssignASCII(dom::GetEnumString(videoType));
3079 }
3080 // only allow privileged content to set the window id
3081 if (vc.mBrowserWindow.WasPassed()) {
3082 vc.mBrowserWindow.Value() = -1;
3083 }
3084 if (vc.mAdvanced.WasPassed()) {
3085 for (MediaTrackConstraintSet& cs : vc.mAdvanced.Value()) {
3086 if (cs.mBrowserWindow.WasPassed()) {
3087 cs.mBrowserWindow.Value() = -1;
3088 }
3089 }
3090 }
3091 }
3092 } else if (IsOn(c.mVideo)) {
3093 videoType = MediaSourceEnum::Camera;
3094 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3095 (uint32_t)videoType);
3096 }
3097
3098 if (c.mAudio.IsMediaTrackConstraints()) {
3099 auto& ac = c.mAudio.GetAsMediaTrackConstraints();
3100 if (!ac.mMediaSource.WasPassed()) {
3101 ac.mMediaSource.Construct(NS_ConvertASCIItoUTF16(
3102 dom::GetEnumString(MediaSourceEnum::Microphone)));
3103 }
3104 audioType = dom::StringToEnum<MediaSourceEnum>(ac.mMediaSource.Value())
3105 .valueOr(MediaSourceEnum::Other);
3106 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3107 (uint32_t)audioType);
3108
3109 switch (audioType) {
3110 case MediaSourceEnum::Microphone:
3111 break;
3112
3113 case MediaSourceEnum::AudioCapture:
3114 // Only enable AudioCapture if the pref is enabled. If it's not, we can
3115 // deny right away.
3116 if (!Preferences::GetBool("media.getusermedia.audio.capture.enabled")) {
3117 return StreamPromise::CreateAndReject(
3118 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3119 __func__);
3120 }
3121 break;
3122
3123 case MediaSourceEnum::Other:
3124 default: {
3125 return StreamPromise::CreateAndReject(
3126 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
3127 "", u"mediaSource"_ns),
3128 __func__);
3129 }
3130 }
3131 } else if (IsOn(c.mAudio)) {
3132 audioType = MediaSourceEnum::Microphone;
3133 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3134 (uint32_t)audioType);
3135 }
3136
3137 // Create a window listener if it doesn't already exist.
3138 RefPtr<GetUserMediaWindowListener> windowListener =
3139 GetOrMakeWindowListener(aWindow);
3140 MOZ_ASSERT(windowListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(windowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(windowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("windowListener"
, "./../../../dom/media/MediaManager.cpp", 3140); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener" ")"); do { MOZ_CrashSequence
(__null, 3140); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3141 // Create an inactive DeviceListener to act as a placeholder, so the
3142 // window listener doesn't clean itself up until we're done.
3143 auto placeholderListener = MakeRefPtr<DeviceListener>();
3144 windowListener->Register(placeholderListener);
3145
3146 { // Check Permissions Policy. Reject if a requested feature is disabled.
3147 bool disabled = !IsOn(c.mAudio) && !IsOn(c.mVideo);
3148 if (IsOn(c.mAudio)) {
3149 if (audioType == MediaSourceEnum::Microphone) {
3150 if (Preferences::GetBool("media.getusermedia.microphone.deny", false) ||
3151 !FeaturePolicyUtils::IsFeatureAllowed(doc, u"microphone"_ns)) {
3152 disabled = true;
3153 }
3154 } else if (!FeaturePolicyUtils::IsFeatureAllowed(doc,
3155 u"display-capture"_ns)) {
3156 disabled = true;
3157 }
3158 }
3159 if (IsOn(c.mVideo)) {
3160 if (videoType == MediaSourceEnum::Camera) {
3161 if (Preferences::GetBool("media.getusermedia.camera.deny", false) ||
3162 !FeaturePolicyUtils::IsFeatureAllowed(doc, u"camera"_ns)) {
3163 disabled = true;
3164 }
3165 } else if (!FeaturePolicyUtils::IsFeatureAllowed(doc,
3166 u"display-capture"_ns)) {
3167 disabled = true;
3168 }
3169 }
3170
3171 if (disabled) {
3172 placeholderListener->Stop();
3173 return StreamPromise::CreateAndReject(
3174 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3175 __func__);
3176 }
3177 }
3178
3179 // Get list of all devices, with origin-specific device ids.
3180
3181 MediaEnginePrefs prefs = mPrefs;
3182
3183 nsString callID;
3184 rv = GenerateUUID(callID);
3185 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../dom/media/MediaManager.cpp"
, 3185); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 3185); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3186
3187 bool hasVideo = videoType != MediaSourceEnum::Other;
3188 bool hasAudio = audioType != MediaSourceEnum::Other;
3189
3190 // Handle fake requests from content. For gUM we don't consider resist
3191 // fingerprinting as users should be prompted anyway.
3192 bool forceFakes = c.mFake.WasPassed() && c.mFake.Value();
3193 // fake:true is effective only for microphone and camera devices, so
3194 // permission must be requested for screen capture even if fake:true is set.
3195 bool hasOnlyForcedFakes =
3196 forceFakes && (!hasVideo || videoType == MediaSourceEnum::Camera) &&
3197 (!hasAudio || audioType == MediaSourceEnum::Microphone);
3198 bool askPermission =
3199 (!privileged ||
3200 Preferences::GetBool("media.navigator.permission.force")) &&
3201 (!hasOnlyForcedFakes ||
3202 Preferences::GetBool("media.navigator.permission.fake"));
3203
3204 LOG("{}: Preparing to enumerate devices. windowId={}, videoType={}, "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}", MOZ_LOG_EXPAND_ARGS
__func__, windowID, static_cast<uint8_t>(videoType), static_cast
<uint8_t>(audioType), forceFakes ? "true" : "false", askPermission
? "true" : "false"); } } while (0)
3205 "audioType={}, forceFakes={}, askPermission={}",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}", MOZ_LOG_EXPAND_ARGS
__func__, windowID, static_cast<uint8_t>(videoType), static_cast
<uint8_t>(audioType), forceFakes ? "true" : "false", askPermission
? "true" : "false"); } } while (0)
3206 __func__, windowID, static_cast<uint8_t>(videoType),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}", MOZ_LOG_EXPAND_ARGS
__func__, windowID, static_cast<uint8_t>(videoType), static_cast
<uint8_t>(audioType), forceFakes ? "true" : "false", askPermission
? "true" : "false"); } } while (0)
3207 static_cast<uint8_t>(audioType), forceFakes ? "true" : "false",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}", MOZ_LOG_EXPAND_ARGS
__func__, windowID, static_cast<uint8_t>(videoType), static_cast
<uint8_t>(audioType), forceFakes ? "true" : "false", askPermission
? "true" : "false"); } } while (0)
3208 askPermission ? "true" : "false")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "{}: Preparing to enumerate devices. windowId={}, videoType={}, "
"audioType={}, forceFakes={}, askPermission={}", MOZ_LOG_EXPAND_ARGS
__func__, windowID, static_cast<uint8_t>(videoType), static_cast
<uint8_t>(audioType), forceFakes ? "true" : "false", askPermission
? "true" : "false"); } } while (0)
;
3209
3210 EnumerationFlags flags = EnumerationFlag::AllowPermissionRequest;
3211 if (forceFakes) {
3212 flags += EnumerationFlag::ForceFakes;
3213 }
3214 if (privileged && videoType == MediaSourceEnum::Browser &&
3215 c.mVideo.IsMediaTrackConstraints() &&
3216 c.mVideo.GetAsMediaTrackConstraints().mDeviceId.WasPassed()) {
3217 // Bug 2041678: For automation purposes when calling getUserMedia
3218 // in privileged context to record a browser window, since we avoid
3219 // the interface to choose the device and just provide it directly,
3220 // we have to invalidate the device cache.
3221 MOZ_ALWAYS_SUCCEEDS(mMediaThread->Dispatch(NS_NewRunnableFunction(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3222 __func__, [self = RefPtr(this), this, videoType] {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3223 if (mBackend) {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3224 mBackend->InvalidateDesktopCaptureDeviceCache(videoType);do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3225 }do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3226 })))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [
self = RefPtr(this), this, videoType] { if (mBackend) { mBackend
->InvalidateDesktopCaptureDeviceCache(videoType); } })))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
, "./../../../dom/media/MediaManager.cpp", 3226); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3226); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3227 }
3228 RefPtr<MediaManager> self = this;
3229 return EnumerateDevicesImpl(
3230 aWindow, CreateEnumerationParams(videoType, audioType, flags))
3231 ->Then(
3232 GetCurrentSerialEventTarget(), __func__,
3233 [self, windowID, c, windowListener,
3234 aCallerType](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) {
3235 LOG("GetUserMedia: post enumeration promise success callback "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration promise success callback " "starting"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration promise success callback "
"starting", MOZ_LOG_EXPAND_ARGS); } } while (0)
3236 "starting")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration promise success callback " "starting"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration promise success callback "
"starting", MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3237 // Ensure that our windowID is still good.
3238 RefPtr<nsPIDOMWindowInner> window =
3239 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3240 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3241 LOG("GetUserMedia: bad window ({}) in post enumeration success "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
3242 "callback!",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
3243 windowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
;
3244 return LocalDeviceSetPromise::CreateAndReject(
3245 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3246 __func__);
3247 }
3248 // Apply any constraints. This modifies the passed-in list.
3249 return self->SelectSettings(c, aCallerType, std::move(aDevices));
3250 },
3251 [](RefPtr<MediaMgrError>&& aError) {
3252 LOG("GetUserMedia: post enumeration EnumerateDevicesImpl "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration EnumerateDevicesImpl " "failure callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration EnumerateDevicesImpl "
"failure callback called!", MOZ_LOG_EXPAND_ARGS); } } while (
0)
3253 "failure callback called!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration EnumerateDevicesImpl " "failure callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration EnumerateDevicesImpl "
"failure callback called!", MOZ_LOG_EXPAND_ARGS); } } while (
0)
;
3254 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3255 __func__);
3256 })
3257 ->Then(
3258 GetCurrentSerialEventTarget(), __func__,
3259 [self, windowID, c, windowListener, placeholderListener, hasAudio,
3260 hasVideo, askPermission, prefs, isSecure, isHandlingUserInput,
3261 callID, principalInfo, aCallerType, resistFingerprinting, audioType,
3262 forceFakes](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3263 LOG("GetUserMedia: starting post enumeration promise2 success "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: starting post enumeration promise2 success "
"callback!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: starting post enumeration promise2 success "
"callback!", MOZ_LOG_EXPAND_ARGS); } } while (0)
3264 "callback!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: starting post enumeration promise2 success "
"callback!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: starting post enumeration promise2 success "
"callback!", MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3265
3266 // Ensure that the window is still good.
3267 RefPtr<nsPIDOMWindowInner> window =
3268 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3269 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3270 LOG("GetUserMedia: bad window ({}) in post enumeration success "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
3271 "callback 2!",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
3272 windowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "GetUserMedia: bad window ({}) in post enumeration success "
"callback 2!", MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
;
3273 placeholderListener->Stop();
3274 return StreamPromise::CreateAndReject(
3275 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3276 __func__);
3277 }
3278 if (!aDevices->Length()) {
3279 LOG("GetUserMedia: no devices found in post enumeration promise2 "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: no devices found in post enumeration promise2 "
"success callback! Calling error handler!")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "GetUserMedia: no devices found in post enumeration promise2 "
"success callback! Calling error handler!", MOZ_LOG_EXPAND_ARGS
); } } while (0)
3280 "success callback! Calling error handler!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: no devices found in post enumeration promise2 "
"success callback! Calling error handler!")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "GetUserMedia: no devices found in post enumeration promise2 "
"success callback! Calling error handler!", MOZ_LOG_EXPAND_ARGS
); } } while (0)
;
3281 placeholderListener->Stop();
3282 // When privacy.resistFingerprinting = true, no
3283 // available device implies content script is requesting
3284 // a fake device, so report NotAllowedError.
3285 auto error = resistFingerprinting
3286 ? MediaMgrError::Name::NotAllowedError
3287 : MediaMgrError::Name::NotFoundError;
3288 return StreamPromise::CreateAndReject(
3289 MakeRefPtr<MediaMgrError>(error), __func__);
3290 }
3291
3292 // Time to start devices. Create the necessary device listeners and
3293 // remove the placeholder.
3294 RefPtr<DeviceListener> audioListener;
3295 RefPtr<DeviceListener> videoListener;
3296 if (hasAudio) {
3297 audioListener = MakeRefPtr<DeviceListener>();
3298 windowListener->Register(audioListener);
3299 }
3300 if (hasVideo) {
3301 videoListener = MakeRefPtr<DeviceListener>();
3302 windowListener->Register(videoListener);
3303 }
3304 placeholderListener->Stop();
3305
3306 bool focusSource = mozilla::Preferences::GetBool(
3307 "media.getusermedia.window.focus_source.enabled", true);
3308
3309 // Incremental hack to compile. To be replaced by deeper
3310 // refactoring. MediaManager allows
3311 // "neither-resolve-nor-reject" semantics, so we cannot
3312 // use MozPromiseHolder here.
3313 MozPromiseHolder<StreamPromise> holder;
3314 RefPtr<StreamPromise> p = holder.Ensure(__func__);
3315
3316 // Pass callbacks and listeners along to GetUserMediaStreamTask.
3317 auto task = MakeRefPtr<GetUserMediaStreamTask>(
3318 c, std::move(holder), windowID, std::move(windowListener),
3319 std::move(audioListener), std::move(videoListener), prefs,
3320 principalInfo, aCallerType, focusSource);
3321
3322 // It is time to ask for user permission, prime voice processing
3323 // now. Use a local lambda to enable a guard pattern.
3324 [&] {
3325 if (forceFakes) {
3326 return;
3327 }
3328
3329 if (audioType != MediaSourceEnum::Microphone) {
3330 return;
3331 }
3332
3333 if (!StaticPrefs::
3334 media_getusermedia_microphone_voice_stream_priming_enabled() ||
3335 !StaticPrefs::
3336 media_getusermedia_microphone_prefer_voice_stream_with_processing_enabled()) {
3337 return;
3338 }
3339
3340 if (const auto fc = FlattenedConstraints(
3341 NormalizedConstraints(GetInvariant(c.mAudio)));
3342 !fc.mEchoCancellation.Get(prefs.mAecOn) &&
3343 !fc.mAutoGainControl.Get(prefs.mAgcOn && prefs.mAecOn) &&
3344 !fc.mNoiseSuppression.Get(prefs.mNoiseOn && prefs.mAecOn)) {
3345 return;
3346 }
3347
3348 if (GetPersistentPermissions(windowID)
3349 .map([](auto&& aState) {
3350 return aState.mMicrophonePermission ==
3351 PersistentPermissionState::Deny;
3352 })
3353 .unwrapOr(true)) {
3354 return;
3355 }
3356
3357 task->PrimeVoiceProcessing();
3358 }();
3359
3360 size_t taskCount =
3361 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3362
3363 if (!askPermission) {
3364 self->NotifyAllowed(callID, *aDevices);
3365 } else {
3366 auto req = MakeRefPtr<GetUserMediaRequest>(
3367 window, callID, std::move(aDevices), c, isSecure,
3368 isHandlingUserInput);
3369 if (!Preferences::GetBool("media.navigator.permission.force") &&
3370 taskCount > 1) {
3371 // there is at least 1 pending gUM request
3372 // For the scarySources test case, always send the
3373 // request
3374 self->mPendingGUMRequest.AppendElement(req.forget());
3375 } else {
3376 nsCOMPtr<nsIObserverService> obs =
3377 services::GetObserverService();
3378 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3379 }
3380 }
3381#ifdef MOZ_WEBRTC1
3382 self->mLogHandle = EnsureWebrtcLogging();
3383#endif
3384 return p;
3385 },
3386 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3387 LOG("GetUserMedia: post enumeration SelectSettings failure "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration SelectSettings failure " "callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration SelectSettings failure "
"callback called!", MOZ_LOG_EXPAND_ARGS); } } while (0)
3388 "callback called!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "GetUserMedia: post enumeration SelectSettings failure " "callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "GetUserMedia: post enumeration SelectSettings failure "
"callback called!", MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3389 placeholderListener->Stop();
3390 return StreamPromise::CreateAndReject(std::move(aError), __func__);
3391 });
3392};
3393
3394RefPtr<LocalDeviceSetPromise> MediaManager::AnonymizeDevices(
3395 nsPIDOMWindowInner* aWindow, RefPtr<const MediaDeviceSetRefCnt> aDevices) {
3396 // Get an origin-key (for either regular or private browsing).
3397 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3397); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3397); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3398 uint64_t windowId = aWindow->WindowID();
3399 nsCOMPtr<nsIPrincipal> principal =
3400 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3401 MOZ_ASSERT(principal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(principal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(principal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("principal", "./../../../dom/media/MediaManager.cpp"
, 3401); AnnotateMozCrashReason("MOZ_ASSERT" "(" "principal" ")"
); do { MOZ_CrashSequence(__null, 3401); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3402 ipc::PrincipalInfo principalInfo;
3403 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3404 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 3404)
) {
3405 return LocalDeviceSetPromise::CreateAndReject(
3406 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3407 __func__);
3408 }
3409 bool resistFingerprinting =
3410 aWindow->AsGlobal()->ShouldResistFingerprinting(RFPTarget::MediaDevices);
3411 bool persist =
3412 IsActivelyCapturingOrHasAPermission(windowId) && !resistFingerprinting;
3413 return media::GetPrincipalKey(principalInfo, persist)
3414 ->Then(
3415 GetMainThreadSerialEventTarget(), __func__,
3416 [rawDevices = std::move(aDevices), windowId,
3417 resistFingerprinting](const nsCString& aOriginKey) {
3418 MOZ_ASSERT(!aOriginKey.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aOriginKey.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aOriginKey.IsEmpty()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!aOriginKey.IsEmpty()"
, "./../../../dom/media/MediaManager.cpp", 3418); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!aOriginKey.IsEmpty()" ")"); do { MOZ_CrashSequence
(__null, 3418); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3419 RefPtr anonymized = new LocalMediaDeviceSetRefCnt();
3420 for (const RefPtr<MediaDevice>& device : *rawDevices) {
3421 nsString name = device->mRawName;
3422 if (name.Find(u"AirPods"_ns) != -1) {
3423 name = u"AirPods"_ns;
3424 }
3425
3426 nsString id = device->mRawID;
3427 if (resistFingerprinting) {
3428 nsRFPService::GetMediaDeviceName(name, device->mKind);
3429 id = name;
3430 id.AppendInt(windowId);
3431 }
3432 // An empty id represents a virtual default device, for which
3433 // the exposed deviceId is the empty string.
3434 if (!id.IsEmpty()) {
3435 nsContentUtils::AnonymizeId(id, aOriginKey);
3436 }
3437
3438 nsString groupId = device->mRawGroupID;
3439 if (resistFingerprinting) {
3440 nsRFPService::GetMediaDeviceGroup(groupId, device->mKind);
3441 }
3442 // Use window id to salt group id in order to make it session
3443 // based as required by the spec. This does not provide unique
3444 // group ids through out a browser restart. However, this is not
3445 // against the spec. Furthermore, since device ids are the same
3446 // after a browser restart the fingerprint is not bigger.
3447 groupId.AppendInt(windowId);
3448 nsContentUtils::AnonymizeId(groupId, aOriginKey);
3449 anonymized->EmplaceBack(
3450 new LocalMediaDevice(device, id, groupId, name));
3451 }
3452 return LocalDeviceSetPromise::CreateAndResolve(anonymized,
3453 __func__);
3454 },
3455 [](nsresult rs) {
3456 NS_WARNING("AnonymizeDevices failed to get Principal Key")NS_DebugBreak(NS_DEBUG_WARNING, "AnonymizeDevices failed to get Principal Key"
, nullptr, "./../../../dom/media/MediaManager.cpp", 3456)
;
3457 return LocalDeviceSetPromise::CreateAndReject(
3458 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3459 __func__);
3460 });
3461}
3462
3463RefPtr<LocalDeviceSetPromise> MediaManager::EnumerateDevicesImpl(
3464 nsPIDOMWindowInner* aWindow, EnumerationParams aParams) {
3465 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3465); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3465); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3466
3467 uint64_t windowId = aWindow->WindowID();
3468 LOG("{}: windowId={}, aVideoInputType={}, aAudioInputType={}", __func__,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"))
, 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, windowId, static_cast<uint8_t
>(aParams.VideoInputType()), static_cast<uint8_t>(aParams
.AudioInputType())); } } while (0)
3469 windowId, static_cast<uint8_t>(aParams.VideoInputType()),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"))
, 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, windowId, static_cast<uint8_t
>(aParams.VideoInputType()), static_cast<uint8_t>(aParams
.AudioInputType())); } } while (0)
3470 static_cast<uint8_t>(aParams.AudioInputType()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"))
, 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: windowId={}, aVideoInputType={}, aAudioInputType={}"
, MOZ_LOG_EXPAND_ARGS __func__, windowId, static_cast<uint8_t
>(aParams.VideoInputType()), static_cast<uint8_t>(aParams
.AudioInputType())); } } while (0)
;
3471
3472 // To get a device list anonymized for a particular origin, we must:
3473 // 1. Get the raw devices list
3474 // 2. Anonymize the raw list with an origin-key.
3475
3476 // Add the window id here to check for that and abort silently if no longer
3477 // exists.
3478 RefPtr<GetUserMediaWindowListener> windowListener =
3479 GetOrMakeWindowListener(aWindow);
3480 MOZ_ASSERT(windowListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(windowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(windowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("windowListener"
, "./../../../dom/media/MediaManager.cpp", 3480); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener" ")"); do { MOZ_CrashSequence
(__null, 3480); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3481 // Create an inactive DeviceListener to act as a placeholder, so the
3482 // window listener doesn't clean itself up until we're done.
3483 auto placeholderListener = MakeRefPtr<DeviceListener>();
3484 windowListener->Register(placeholderListener);
3485
3486 return MaybeRequestPermissionAndEnumerateRawDevices(std::move(aParams))
3487 ->Then(
3488 GetMainThreadSerialEventTarget(), __func__,
3489 [self = RefPtr(this), this, window = nsCOMPtr(aWindow),
3490 placeholderListener](RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
3491 // Only run if window is still on our active list.
3492 MediaManager* mgr = MediaManager::GetIfExists();
3493 if (!mgr || placeholderListener->Stopped()) {
3494 // The listener has already been removed if the window is no
3495 // longer active.
3496 return LocalDeviceSetPromise::CreateAndReject(
3497 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3498 __func__);
3499 }
3500 MOZ_ASSERT(mgr->IsWindowStillActive(window->WindowID()))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mgr->IsWindowStillActive(window->WindowID()))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mgr->IsWindowStillActive(window->WindowID())))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mgr->IsWindowStillActive(window->WindowID())"
, "./../../../dom/media/MediaManager.cpp", 3500); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mgr->IsWindowStillActive(window->WindowID())"
")"); do { MOZ_CrashSequence(__null, 3500); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3501 placeholderListener->Stop();
3502 return AnonymizeDevices(window, aDevices);
3503 },
3504 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3505 // EnumerateDevicesImpl may fail if a new doc has been set, in which
3506 // case the OnNavigation() method should have removed all previous
3507 // active listeners, or if a platform device access request was not
3508 // granted.
3509 placeholderListener->Stop();
3510 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3511 __func__);
3512 });
3513}
3514
3515RefPtr<LocalDevicePromise> MediaManager::SelectAudioOutput(
3516 nsPIDOMWindowInner* aWindow, const dom::AudioOutputOptions& aOptions,
3517 CallerType aCallerType) {
3518 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
3519 nsCOMPtr<nsIPrincipal> principal =
3520 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3521 if (!FeaturePolicyUtils::IsFeatureAllowed(aWindow->GetExtantDoc(),
3522 u"speaker-selection"_ns)) {
3523 return LocalDevicePromise::CreateAndReject(
3524 MakeRefPtr<MediaMgrError>(
3525 MediaMgrError::Name::NotAllowedError,
3526 "Document's Permissions Policy does not allow selectAudioOutput()"),
3527 __func__);
3528 }
3529 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "./../../../dom/media/MediaManager.cpp"
, 3529)
) {
3530 return LocalDevicePromise::CreateAndReject(
3531 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3532 __func__);
3533 }
3534 // Disallow access to null principal.
3535 if (principal->GetIsNullPrincipal()) {
3536 return LocalDevicePromise::CreateAndReject(
3537 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3538 __func__);
3539 }
3540 ipc::PrincipalInfo principalInfo;
3541 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3542 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/media/MediaManager.cpp"
, 3542)
) {
3543 return LocalDevicePromise::CreateAndReject(
3544 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3545 __func__);
3546 }
3547 uint64_t windowID = aWindow->WindowID();
3548 const bool resistFingerprinting =
3549 aWindow->AsGlobal()->ShouldResistFingerprinting(aCallerType,
3550 RFPTarget::MediaDevices);
3551 return EnumerateDevicesImpl(
3552 aWindow, CreateEnumerationParams(
3553 MediaSourceEnum::Other, MediaSourceEnum::Other,
3554 {EnumerationFlag::EnumerateAudioOutputs,
3555 EnumerationFlag::AllowPermissionRequest}))
3556 ->Then(
3557 GetCurrentSerialEventTarget(), __func__,
3558 [self = RefPtr<MediaManager>(this), windowID, aOptions, aCallerType,
3559 resistFingerprinting, isHandlingUserInput,
3560 principalInfo](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3561 // Ensure that the window is still good.
3562 RefPtr<nsPIDOMWindowInner> window =
3563 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3564 if (!window) {
3565 LOG("SelectAudioOutput: bad window ({}) in post enumeration "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: bad window ({}) in post enumeration " "success callback!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectAudioOutput: bad window ({}) in post enumeration "
"success callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while
(0)
3566 "success callback!",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: bad window ({}) in post enumeration " "success callback!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectAudioOutput: bad window ({}) in post enumeration "
"success callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while
(0)
3567 windowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: bad window ({}) in post enumeration " "success callback!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectAudioOutput: bad window ({}) in post enumeration "
"success callback!", MOZ_LOG_EXPAND_ARGS windowID); } } while
(0)
;
3568 return LocalDevicePromise::CreateAndReject(
3569 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3570 __func__);
3571 }
3572 if (aDevices->IsEmpty()) {
3573 LOG("SelectAudioOutput: no devices found")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: no devices found")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "SelectAudioOutput: no devices found"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3574 auto error = resistFingerprinting
3575 ? MediaMgrError::Name::NotAllowedError
3576 : MediaMgrError::Name::NotFoundError;
3577 return LocalDevicePromise::CreateAndReject(
3578 MakeRefPtr<MediaMgrError>(error), __func__);
3579 }
3580 MozPromiseHolder<LocalDevicePromise> holder;
3581 RefPtr<LocalDevicePromise> p = holder.Ensure(__func__);
3582 auto task = MakeRefPtr<SelectAudioOutputTask>(
3583 std::move(holder), windowID, aCallerType, principalInfo);
3584 nsString callID;
3585 nsresult rv = GenerateUUID(callID);
3586 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../dom/media/MediaManager.cpp"
, 3586); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 3586); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3587 size_t taskCount =
3588 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3589 bool askPermission =
3590 !Preferences::GetBool("media.navigator.permission.disabled") ||
3591 Preferences::GetBool("media.navigator.permission.force");
3592 if (!askPermission) {
3593 self->NotifyAllowed(callID, *aDevices);
3594 } else {
3595 MOZ_ASSERT(window->IsSecureContext())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(window->IsSecureContext())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(window->IsSecureContext()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"window->IsSecureContext()", "./../../../dom/media/MediaManager.cpp"
, 3595); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window->IsSecureContext()"
")"); do { MOZ_CrashSequence(__null, 3595); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3596 auto req = MakeRefPtr<GetUserMediaRequest>(
3597 window, callID, std::move(aDevices), aOptions, true,
3598 isHandlingUserInput);
3599 if (taskCount > 1) {
3600 // there is at least 1 pending gUM request
3601 self->mPendingGUMRequest.AppendElement(req.forget());
3602 } else {
3603 nsCOMPtr<nsIObserverService> obs =
3604 services::GetObserverService();
3605 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3606 }
3607 }
3608 return p;
3609 },
3610 [](RefPtr<MediaMgrError> aError) {
3611 LOG("SelectAudioOutput: EnumerateDevicesImpl "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: EnumerateDevicesImpl " "failure callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectAudioOutput: EnumerateDevicesImpl "
"failure callback called!", MOZ_LOG_EXPAND_ARGS); } } while (
0)
3612 "failure callback called!")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "SelectAudioOutput: EnumerateDevicesImpl " "failure callback called!"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "SelectAudioOutput: EnumerateDevicesImpl "
"failure callback called!", MOZ_LOG_EXPAND_ARGS); } } while (
0)
;
3613 return LocalDevicePromise::CreateAndReject(std::move(aError),
3614 __func__);
3615 });
3616}
3617
3618MediaEngine* MediaManager::GetBackend() {
3619 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3619); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3619); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3620 // Plugin backends as appropriate. The default engine also currently
3621 // includes picture support for Android.
3622 // This IS called off main-thread.
3623 if (!mBackend) {
3624#if defined(MOZ_WEBRTC1)
3625 mBackend = new MediaEngineWebRTC();
3626#else
3627 mBackend = new MediaEngineFake();
3628#endif
3629 mDeviceListChangeListener = mBackend->DeviceListChangeEvent().Connect(
3630 AbstractThread::MainThread(), this, &MediaManager::DeviceListChanged);
3631 }
3632 return mBackend;
3633}
3634
3635void MediaManager::OnNavigation(uint64_t aWindowID) {
3636 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3636); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3636); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3637 LOG("OnNavigation for {}", aWindowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "OnNavigation for {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "OnNavigation for {}", MOZ_LOG_EXPAND_ARGS aWindowID
); } } while (0)
;
3638
3639 // Stop the streams for this window. The runnables check this value before
3640 // making a call to content.
3641
3642 nsTArray<nsString>* callIDs;
3643 if (mCallIds.Get(aWindowID, &callIDs)) {
3644 for (auto& callID : *callIDs) {
3645 mActiveCallbacks.Remove(callID);
3646 for (auto& request : mPendingGUMRequest.Clone()) {
3647 nsString id;
3648 request->GetCallID(id);
3649 if (id == callID) {
3650 mPendingGUMRequest.RemoveElement(request);
3651 }
3652 }
3653 }
3654 mCallIds.Remove(aWindowID);
3655 }
3656
3657 if (RefPtr<GetUserMediaWindowListener> listener =
3658 GetWindowListener(aWindowID)) {
3659 listener->RemoveAll();
3660 }
3661 MOZ_ASSERT(!GetWindowListener(aWindowID))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowListener(aWindowID))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!GetWindowListener(aWindowID
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowListener(aWindowID)", "./../../../dom/media/MediaManager.cpp"
, 3661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowListener(aWindowID)"
")"); do { MOZ_CrashSequence(__null, 3661); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3662}
3663
3664void MediaManager::OnCameraMute(bool aMute) {
3665 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3665); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3665); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3666 LOG("OnCameraMute for all windows")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "OnCameraMute for all windows")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "OnCameraMute for all windows", MOZ_LOG_EXPAND_ARGS
); } } while (0)
;
3667 mCamerasMuted = aMute;
3668 // This is safe since we're on main-thread, and the windowlist can only
3669 // be added to from the main-thread
3670 for (const auto& window :
3671 ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>(
3672 mActiveWindows.Values())) {
3673 window->MuteOrUnmuteCameras(aMute);
3674 }
3675}
3676
3677void MediaManager::OnMicrophoneMute(bool aMute) {
3678 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3678); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3678); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3679 LOG("OnMicrophoneMute for all windows")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "OnMicrophoneMute for all windows")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "OnMicrophoneMute for all windows"
, MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3680 mMicrophonesMuted = aMute;
3681 // This is safe since we're on main-thread, and the windowlist can only
3682 // be added to from the main-thread
3683 for (const auto& window :
3684 ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>(
3685 mActiveWindows.Values())) {
3686 window->MuteOrUnmuteMicrophones(aMute);
3687 }
3688}
3689
3690RefPtr<GetUserMediaWindowListener> MediaManager::GetOrMakeWindowListener(
3691 nsPIDOMWindowInner* aWindow) {
3692 Document* doc = aWindow->GetExtantDoc();
3693 if (!doc) {
3694 // The window has been destroyed. Destroyed windows don't have listeners.
3695 return nullptr;
3696 }
3697 nsIPrincipal* principal = doc->NodePrincipal();
3698 uint64_t windowId = aWindow->WindowID();
3699 RefPtr<GetUserMediaWindowListener> windowListener =
3700 GetWindowListener(windowId);
3701 if (windowListener) {
3702 MOZ_ASSERT(PrincipalHandleMatches(windowListener->GetPrincipalHandle(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(PrincipalHandleMatches(windowListener->GetPrincipalHandle
(), principal))>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(PrincipalHandleMatches(windowListener
->GetPrincipalHandle(), principal)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
, "./../../../dom/media/MediaManager.cpp", 3703); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { MOZ_CrashSequence(__null, 3703); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3703 principal))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(PrincipalHandleMatches(windowListener->GetPrincipalHandle
(), principal))>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(PrincipalHandleMatches(windowListener
->GetPrincipalHandle(), principal)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
, "./../../../dom/media/MediaManager.cpp", 3703); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { MOZ_CrashSequence(__null, 3703); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3704 } else {
3705 windowListener = new GetUserMediaWindowListener(
3706 windowId, MakePrincipalHandle(principal));
3707 AddWindowID(windowId, windowListener);
3708 }
3709 return windowListener;
3710}
3711
3712void MediaManager::AddWindowID(uint64_t aWindowId,
3713 RefPtr<GetUserMediaWindowListener> aListener) {
3714 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3714); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3714); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3715 // Store the WindowID in a hash table and mark as active. The entry is removed
3716 // when this window is closed or navigated away from.
3717 // This is safe since we're on main-thread, and the windowlist can only
3718 // be invalidated from the main-thread (see OnNavigation)
3719 if (IsWindowStillActive(aWindowId)) {
3720 MOZ_ASSERT(false, "Window already added")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Window already added"
")", "./../../../dom/media/MediaManager.cpp", 3720); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "Window already added" ")"); do
{ MOZ_CrashSequence(__null, 3720); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
3721 return;
3722 }
3723
3724 aListener->MuteOrUnmuteCameras(mCamerasMuted);
3725 aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted);
3726 GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener));
3727
3728 RefPtr<WindowGlobalChild> wgc =
3729 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3730 if (wgc) {
3731 wgc->BlockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3732 }
3733}
3734
3735void MediaManager::RemoveWindowID(uint64_t aWindowId) {
3736 RefPtr<WindowGlobalChild> wgc =
3737 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3738 if (wgc) {
3739 wgc->UnblockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3740 }
3741
3742 mActiveWindows.Remove(aWindowId);
3743
3744 // get outer windowID
3745 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
3746 if (!window) {
3747 LOG("No inner window for {}", aWindowId)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "No inner window for {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "No inner window for {}", MOZ_LOG_EXPAND_ARGS
aWindowId); } } while (0)
;
3748 return;
3749 }
3750
3751 auto* outer = window->GetOuterWindow();
3752 if (!outer) {
3753 LOG("No outer window for inner {}", aWindowId)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "No outer window for inner {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "No outer window for inner {}", MOZ_LOG_EXPAND_ARGS
aWindowId); } } while (0)
;
3754 return;
3755 }
3756
3757 uint64_t outerID = outer->WindowID();
3758
3759 // Notify the UI that this window no longer has gUM active
3760 char windowBuffer[32];
3761 SprintfLiteral(windowBuffer, "%" PRIu64"l" "u", outerID);
3762 nsString data = NS_ConvertUTF8toUTF16(windowBuffer);
3763
3764 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3765 obs->NotifyWhenScriptSafe(nullptr, "recording-window-ended", data.get());
3766 LOG("Sent recording-window-ended for window {} (outer {})", aWindowId,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Sent recording-window-ended for window {} (outer {})")), 0
))) { mozilla::detail::log_print_fmt(moz_real_module, "Sent recording-window-ended for window {} (outer {})"
, MOZ_LOG_EXPAND_ARGS aWindowId, outerID); } } while (0)
3767 outerID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Sent recording-window-ended for window {} (outer {})")), 0
))) { mozilla::detail::log_print_fmt(moz_real_module, "Sent recording-window-ended for window {} (outer {})"
, MOZ_LOG_EXPAND_ARGS aWindowId, outerID); } } while (0)
;
3768}
3769
3770bool MediaManager::IsWindowListenerStillActive(
3771 const RefPtr<GetUserMediaWindowListener>& aListener) {
3772 MOZ_DIAGNOSTIC_ASSERT(aListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aListener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aListener", "./../../../dom/media/MediaManager.cpp"
, 3772); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aListener"
")"); do { MOZ_CrashSequence(__null, 3772); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3773 return aListener && aListener == GetWindowListener(aListener->WindowID());
3774}
3775
3776nsresult MediaManager::GetPref(nsIPrefBranch* aBranch, const char* aPref,
3777 const char* aData, int32_t* aVal) {
3778 if (aData && strcmp(aPref, aData) != 0) {
3779 return NS_ERROR_INVALID_ARG;
3780 }
3781
3782 int32_t temp;
3783 nsresult rv = aBranch->GetIntPref(aPref, &temp);
3784 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3785 *aVal = temp;
3786 }
3787
3788 return rv;
3789}
3790
3791nsresult MediaManager::GetPrefBool(nsIPrefBranch* aBranch, const char* aPref,
3792 const char* aData, bool* aVal) {
3793 if (aData && strcmp(aPref, aData) != 0) {
3794 return NS_ERROR_INVALID_ARG;
3795 }
3796
3797 bool temp;
3798 nsresult rv = aBranch->GetBoolPref(aPref, &temp);
3799 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3800 *aVal = temp;
3801 }
3802
3803 return rv;
3804}
3805
3806#ifdef MOZ_WEBRTC1
3807template <class Enum, class Int>
3808constexpr Enum ClampEnum(Int v) {
3809 return std::clamp(
3810 static_cast<Enum>(SaturatingCast<std::underlying_type_t<Enum>>(v)),
3811 ContiguousEnumValues<Enum>::min, ContiguousEnumValues<Enum>::max);
3812}
3813#endif
3814
3815void MediaManager::GetPrefs(nsIPrefBranch* aBranch, const char* aData) {
3816 GetPref(aBranch, "media.navigator.video.default_width", aData,
3817 &mPrefs.mWidth);
3818 GetPref(aBranch, "media.navigator.video.default_height", aData,
3819 &mPrefs.mHeight);
3820 GetPref(aBranch, "media.navigator.video.default_fps", aData, &mPrefs.mFPS);
3821 GetPref(aBranch, "media.navigator.audio.fake_frequency", aData,
3822 &mPrefs.mFreq);
3823#ifdef MOZ_WEBRTC1
3824 GetPrefBool(aBranch, "media.navigator.video.resize_mode.enabled", aData,
3825 &mPrefs.mResizeModeEnabled);
3826 int32_t resizeMode{};
3827 if (NS_SUCCEEDED(GetPref(aBranch, "media.navigator.video.default_resize_mode",((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetPref(aBranch, "media.navigator.video.default_resize_mode"
, aData, &resizeMode))), 1)))
3828 aData, &resizeMode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetPref(aBranch, "media.navigator.video.default_resize_mode"
, aData, &resizeMode))), 1)))
) {
3829 mPrefs.mResizeMode = ClampEnum<VideoResizeModeEnum>(resizeMode);
3830 }
3831 GetPrefBool(aBranch, "media.getusermedia.audio.processing.platform.enabled",
3832 aData, &mPrefs.mUsePlatformProcessing);
3833 GetPrefBool(aBranch, "media.getusermedia.audio.processing.aec.enabled", aData,
3834 &mPrefs.mAecOn);
3835 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc.enabled", aData,
3836 &mPrefs.mAgcOn);
3837 GetPrefBool(aBranch, "media.getusermedia.audio.processing.hpf.enabled", aData,
3838 &mPrefs.mHPFOn);
3839 GetPrefBool(aBranch, "media.getusermedia.audio.processing.noise.enabled",
3840 aData, &mPrefs.mNoiseOn);
3841 GetPrefBool(aBranch, "media.getusermedia.audio.processing.transient.enabled",
3842 aData, &mPrefs.mTransientOn);
3843 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc2.forced", aData,
3844 &mPrefs.mAgc2Forced);
3845 // Use 0 or 1 to force to false or true
3846 // EchoCanceller3Config::echo_removal_control.has_clock_drift.
3847 // -1 is the default, which means automatically set has_clock_drift as
3848 // deemed appropriate.
3849 GetPref(aBranch, "media.getusermedia.audio.processing.aec.expect_drift",
3850 aData, &mPrefs.mExpectDrift);
3851 GetPref(aBranch, "media.getusermedia.audio.processing.agc", aData,
3852 &mPrefs.mAgc);
3853 GetPref(aBranch, "media.getusermedia.audio.processing.noise", aData,
3854 &mPrefs.mNoise);
3855 GetPref(aBranch, "media.getusermedia.audio.max_channels", aData,
3856 &mPrefs.mChannels);
3857#endif
3858 LOG("{}: default prefs: {}x{} @{}fps, {}Hz test tones, "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3859 "resize mode: {}, platform processing: {}, "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3860 "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3861 "version: "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3862 "{}, noise level: {}, transient: {}, channels {}",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3863 __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight, mPrefs.mFPS, mPrefs.mFreq,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3864 mPrefs.mResizeModeEnabled ? dom::GetEnumString(mPrefs.mResizeMode).get()do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3865 : "disabled",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3866 mPrefs.mUsePlatformProcessing ? "on" : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3867 mPrefs.mAecOn ? "on" : "off", mPrefs.mAgcOn ? "on" : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3868 mPrefs.mHPFOn ? "on" : "off", mPrefs.mNoiseOn ? "on" : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3869 mPrefs.mExpectDrift < 0 ? "auto"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3870 : mPrefs.mExpectDrift ? "on"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3871 : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3872 mPrefs.mAgc, mPrefs.mAgc2Forced ? "2" : "1", mPrefs.mNoise,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
3873 mPrefs.mTransientOn ? "on" : "off", mPrefs.mChannels)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, " "resize mode: {}, platform processing: {}, "
"aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "{}: default prefs: {}x{} @{}fps, {}Hz test tones, "
"resize mode: {}, platform processing: {}, " "aec: {}, agc: {}, hpf: {}, noise: {}, drift: {}, agc level: {}, agc "
"version: " "{}, noise level: {}, transient: {}, channels {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight
, mPrefs.mFPS, mPrefs.mFreq, mPrefs.mResizeModeEnabled ? dom::
GetEnumString(mPrefs.mResizeMode).get() : "disabled", mPrefs.
mUsePlatformProcessing ? "on" : "off", mPrefs.mAecOn ? "on" :
"off", mPrefs.mAgcOn ? "on" : "off", mPrefs.mHPFOn ? "on" : "off"
, mPrefs.mNoiseOn ? "on" : "off", mPrefs.mExpectDrift < 0 ?
"auto" : mPrefs.mExpectDrift ? "on" : "off", mPrefs.mAgc, mPrefs
.mAgc2Forced ? "2" : "1", mPrefs.mNoise, mPrefs.mTransientOn ?
"on" : "off", mPrefs.mChannels); } } while (0)
;
3874}
3875
3876void MediaManager::Shutdown() {
3877 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 3877); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3877); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3878 if (sHasMainThreadShutdown) {
3879 return;
3880 }
3881
3882 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3883
3884 obs->RemoveObserver(this, "last-pb-context-exited");
3885 obs->RemoveObserver(this, "getUserMedia:privileged:allow");
3886 obs->RemoveObserver(this, "getUserMedia:response:allow");
3887 obs->RemoveObserver(this, "getUserMedia:response:deny");
3888 obs->RemoveObserver(this, "getUserMedia:response:noOSPermission");
3889 obs->RemoveObserver(this, "getUserMedia:revoke");
3890 obs->RemoveObserver(this, "getUserMedia:muteVideo");
3891 obs->RemoveObserver(this, "getUserMedia:unmuteVideo");
3892 obs->RemoveObserver(this, "getUserMedia:muteAudio");
3893 obs->RemoveObserver(this, "getUserMedia:unmuteAudio");
3894 obs->RemoveObserver(this, "application-background");
3895 obs->RemoveObserver(this, "application-foreground");
3896
3897 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
3898 if (prefs) {
3899 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
3900 prefs->RemoveObserver(aPrefName, this);
3901 });
3902 }
3903
3904 if (mDeviceChangeTimer) {
3905 mDeviceChangeTimer->Cancel();
3906 // Drop ref to MediaTimer early to avoid blocking SharedThreadPool shutdown
3907 mDeviceChangeTimer = nullptr;
3908 }
3909
3910 {
3911 // Close off any remaining active windows.
3912
3913 // Live capture at this point is rare but can happen. Stopping it will make
3914 // the window listeners attempt to remove themselves from the active windows
3915 // table. We cannot touch the table at point so we grab a copy of the window
3916 // listeners first.
3917 const auto listeners = ToArray(GetActiveWindows()->Values());
3918 for (const auto& listener : listeners) {
3919 listener->RemoveAll();
3920 }
3921 }
3922 MOZ_ASSERT(GetActiveWindows()->Count() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(GetActiveWindows()->Count() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(GetActiveWindows()->Count
() == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("GetActiveWindows()->Count() == 0", "./../../../dom/media/MediaManager.cpp"
, 3922); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetActiveWindows()->Count() == 0"
")"); do { MOZ_CrashSequence(__null, 3922); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3923
3924 GetActiveWindows()->Clear();
3925 mActiveCallbacks.Clear();
3926 mCallIds.Clear();
3927 mPendingGUMRequest.Clear();
3928#ifdef MOZ_WEBRTC1
3929 mLogHandle = nullptr;
3930#endif
3931
3932 // From main thread's point of view, shutdown is now done.
3933 // All that remains is shutting down the media thread.
3934 sHasMainThreadShutdown = true;
3935
3936 // Release the backend (and call Shutdown()) from within mMediaThread.
3937 // Don't use MediaManager::Dispatch() because we're
3938 // sHasMainThreadShutdown == true here!
3939 MOZ_ALWAYS_SUCCEEDS(mMediaThread->Dispatch(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3940 NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3941 LOG("MediaManager Thread Shutdown");do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3942 MOZ_ASSERT(IsInMediaThread());do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3943 // Must shutdown backend on MediaManager thread, since that'sdo { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3944 // where we started it from!do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3945 if (mBackend) {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3946 mBackend->Shutdown(); // idempotentdo { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3947 mDeviceListChangeListener.DisconnectIfExists();do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3948 }do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3949 // last reference, will invoke Shutdown() againdo { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3950 mBackend = nullptr;do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3951 })))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { do { const ::mozilla::LogModule
* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, "MediaManager Thread Shutdown"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "MediaManager Thread Shutdown"
, MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(IsInMediaThread(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 3942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { do
{ } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3951); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module, \"MediaManager Thread Shutdown\")), 0))) { mozilla::detail::log_print_fmt(moz_real_module, \"MediaManager Thread Shutdown\", MOZ_LOG_EXPAND_ARGS); } } while (0); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"./../../../dom/media/MediaManager.cpp\", 3942); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3942); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3951); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3952
3953 // note that this == sSingleton
3954 MOZ_ASSERT(this == sSingleton)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this == sSingleton)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this == sSingleton))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("this == sSingleton"
, "./../../../dom/media/MediaManager.cpp", 3954); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "this == sSingleton" ")"); do { MOZ_CrashSequence
(__null, 3954); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3955
3956 // Explicitly shut down the TaskQueue so that it releases its
3957 // SharedThreadPool when all tasks have completed. SharedThreadPool blocks
3958 // XPCOM shutdown from proceeding beyond "xpcom-shutdown-threads" until all
3959 // SharedThreadPools are released, but the nsComponentManager keeps a
3960 // reference to the MediaManager for the nsIMediaManagerService until much
3961 // later in shutdown. This also provides additional assurance that no
3962 // further tasks will be queued.
3963 mMediaThread->BeginShutdown()->Then(
3964 GetMainThreadSerialEventTarget(), __func__, [] {
3965 LOG("MediaManager shutdown lambda running, releasing MediaManager "do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "MediaManager shutdown lambda running, releasing MediaManager "
"singleton")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "MediaManager shutdown lambda running, releasing MediaManager "
"singleton", MOZ_LOG_EXPAND_ARGS); } } while (0)
3966 "singleton")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "MediaManager shutdown lambda running, releasing MediaManager "
"singleton")), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, "MediaManager shutdown lambda running, releasing MediaManager "
"singleton", MOZ_LOG_EXPAND_ARGS); } } while (0)
;
3967 // Remove async shutdown blocker
3968 media::MustGetShutdownBarrier()->RemoveBlocker(
3969 sSingleton->mShutdownBlocker);
3970
3971 sSingleton = nullptr;
3972 });
3973}
3974
3975void MediaManager::SendPendingGUMRequest() {
3976 if (mPendingGUMRequest.Length() > 0) {
3977 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3978 obs->NotifyObservers(mPendingGUMRequest[0], "getUserMedia:request",
3979 nullptr);
3980 mPendingGUMRequest.RemoveElementAt(0);
3981 }
3982}
3983
3984bool IsGUMResponseNoAccess(const char* aTopic,
3985 MediaMgrError::Name& aErrorName) {
3986 if (!strcmp(aTopic, "getUserMedia:response:deny")) {
3987 aErrorName = MediaMgrError::Name::NotAllowedError;
3988 return true;
3989 }
3990
3991 if (!strcmp(aTopic, "getUserMedia:response:noOSPermission")) {
3992 aErrorName = MediaMgrError::Name::NotFoundError;
3993 return true;
3994 }
3995
3996 return false;
3997}
3998
3999static MediaSourceEnum ParseScreenColonWindowID(const char16_t* aData,
4000 uint64_t* aWindowIDOut) {
4001 MOZ_ASSERT(aWindowIDOut)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aWindowIDOut)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aWindowIDOut))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aWindowIDOut", "./../../../dom/media/MediaManager.cpp"
, 4001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindowIDOut"
")"); do { MOZ_CrashSequence(__null, 4001); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4002 // may be windowid or screen:windowid
4003 const nsDependentString data(aData);
4004 if (Substring(data, 0, strlen("screen:")).EqualsLiteral("screen:")) {
4005 nsresult rv;
4006 *aWindowIDOut = Substring(data, strlen("screen:")).ToInteger64(&rv);
4007 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../dom/media/MediaManager.cpp"
, 4007); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 4007); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4008 return MediaSourceEnum::Screen;
4009 }
4010 nsresult rv;
4011 *aWindowIDOut = data.ToInteger64(&rv);
4012 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../dom/media/MediaManager.cpp"
, 4012); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 4012); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4013 return MediaSourceEnum::Camera;
4014}
4015
4016nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
4017 const char16_t* aData) {
4018 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4018); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4018); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4019
4020 MediaMgrError::Name gumNoAccessError = MediaMgrError::Name::NotAllowedError;
4021
4022 if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
4023 nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(aSubject));
4024 if (branch) {
4025 GetPrefs(branch, NS_ConvertUTF16toUTF8(aData).get());
4026 DeviceListChanged();
4027 }
4028 } else if (!strcmp(aTopic, "last-pb-context-exited")) {
4029 // Clear memory of private-browsing-specific deviceIds. Fire and forget.
4030 media::SanitizeOriginKeys(0, true);
4031 return NS_OK;
4032 } else if (!strcmp(aTopic, "getUserMedia:got-device-permission")) {
4033 MOZ_ASSERT(aSubject)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSubject)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSubject))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aSubject", "./../../../dom/media/MediaManager.cpp"
, 4033); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSubject" ")"
); do { MOZ_CrashSequence(__null, 4033); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4034 nsCOMPtr<nsIRunnable> task = do_QueryInterface(aSubject);
4035 MediaManager::Dispatch(NewTaskFrom([task] { task->Run(); }));
4036 return NS_OK;
4037 } else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
4038 !strcmp(aTopic, "getUserMedia:response:allow")) {
4039 nsString key(aData);
4040 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
4041 if (!task) {
4042 return NS_OK;
4043 }
4044
4045 if (sHasMainThreadShutdown) {
4046 task->Denied(MediaMgrError::Name::AbortError, "In shutdown"_ns);
4047 return NS_OK;
4048 }
4049 if (NS_WARN_IF(!aSubject)NS_warn_if_impl(!aSubject, "!aSubject", "./../../../dom/media/MediaManager.cpp"
, 4049)
) {
4050 return NS_ERROR_FAILURE; // ignored
4051 }
4052 // Permission has been granted. aSubject contains the particular device
4053 // or devices selected and approved by the user, if any.
4054 nsCOMPtr<nsIArray> array(do_QueryInterface(aSubject));
4055 MOZ_ASSERT(array)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(array)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(array))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("array", "./../../../dom/media/MediaManager.cpp"
, 4055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { MOZ_CrashSequence(__null, 4055); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4056 uint32_t len = 0;
4057 array->GetLength(&len);
4058 RefPtr<LocalMediaDevice> audioInput;
4059 RefPtr<LocalMediaDevice> videoInput;
4060 RefPtr<LocalMediaDevice> audioOutput;
4061 for (uint32_t i = 0; i < len; i++) {
4062 nsCOMPtr<nsIMediaDevice> device;
4063 array->QueryElementAt(i, NS_GET_IID(nsIMediaDevice)(nsIMediaDevice::kIID),
4064 getter_AddRefs(device));
4065 MOZ_ASSERT(device)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(device)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(device))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("device", "./../../../dom/media/MediaManager.cpp"
, 4065); AnnotateMozCrashReason("MOZ_ASSERT" "(" "device" ")"
); do { MOZ_CrashSequence(__null, 4065); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // shouldn't be returning anything else...
4066 if (!device) {
4067 continue;
4068 }
4069
4070 // Casting here is safe because a LocalMediaDevice is created
4071 // only in Gecko side, JS can only query for an instance.
4072 auto* dev = static_cast<LocalMediaDevice*>(device.get());
4073 switch (dev->Kind()) {
4074 case MediaDeviceKind::Videoinput:
4075 if (!videoInput) {
4076 videoInput = dev;
4077 }
4078 break;
4079 case MediaDeviceKind::Audioinput:
4080 if (!audioInput) {
4081 audioInput = dev;
4082 }
4083 break;
4084 case MediaDeviceKind::Audiooutput:
4085 if (!audioOutput) {
4086 audioOutput = dev;
4087 }
4088 break;
4089 default:
4090 MOZ_CRASH("Unexpected device kind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected device kind"
, "./../../../dom/media/MediaManager.cpp", 4090); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected device kind" ")"); do { MOZ_CrashSequence
(__null, 4090); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
4091 }
4092 }
4093
4094 if (GetUserMediaStreamTask* streamTask = task->AsGetUserMediaStreamTask()) {
4095 bool needVideo = IsOn(streamTask->GetConstraints().mVideo);
4096 bool needAudio = IsOn(streamTask->GetConstraints().mAudio);
4097 MOZ_ASSERT(needVideo || needAudio)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(needVideo || needAudio)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(needVideo || needAudio))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("needVideo || needAudio"
, "./../../../dom/media/MediaManager.cpp", 4097); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "needVideo || needAudio" ")"); do { MOZ_CrashSequence
(__null, 4097); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4098
4099 if ((needVideo && !videoInput) || (needAudio && !audioInput)) {
4100 task->Denied(MediaMgrError::Name::NotAllowedError);
4101 return NS_OK;
4102 }
4103 streamTask->Allowed(std::move(audioInput), std::move(videoInput));
4104 return NS_OK;
4105 }
4106 if (SelectAudioOutputTask* outputTask = task->AsSelectAudioOutputTask()) {
4107 if (!audioOutput) {
4108 task->Denied(MediaMgrError::Name::NotAllowedError);
4109 return NS_OK;
4110 }
4111 outputTask->Allowed(std::move(audioOutput));
4112 return NS_OK;
4113 }
4114
4115 NS_WARNING("Unknown task type in getUserMedia")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown task type in getUserMedia"
, nullptr, "./../../../dom/media/MediaManager.cpp", 4115)
;
4116 return NS_ERROR_FAILURE;
4117
4118 } else if (IsGUMResponseNoAccess(aTopic, gumNoAccessError)) {
4119 nsString key(aData);
4120 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
4121 if (task) {
4122 task->Denied(gumNoAccessError);
4123 SendPendingGUMRequest();
4124 }
4125 return NS_OK;
4126
4127 } else if (!strcmp(aTopic, "getUserMedia:revoke")) {
4128 uint64_t windowID;
4129 if (ParseScreenColonWindowID(aData, &windowID) == MediaSourceEnum::Screen) {
4130 LOG("Revoking ScreenCapture access for window {}", windowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Revoking ScreenCapture access for window {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Revoking ScreenCapture access for window {}"
, MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
;
4131 StopScreensharing(windowID);
4132 } else {
4133 LOG("Revoking MediaCapture access for window {}", windowID)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Revoking MediaCapture access for window {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Revoking MediaCapture access for window {}"
, MOZ_LOG_EXPAND_ARGS windowID); } } while (0)
;
4134 OnNavigation(windowID);
4135 }
4136 return NS_OK;
4137 } else if (!strcmp(aTopic, "getUserMedia:muteVideo") ||
4138 !strcmp(aTopic, "getUserMedia:unmuteVideo")) {
4139 OnCameraMute(!strcmp(aTopic, "getUserMedia:muteVideo"));
4140 return NS_OK;
4141 } else if (!strcmp(aTopic, "getUserMedia:muteAudio") ||
4142 !strcmp(aTopic, "getUserMedia:unmuteAudio")) {
4143 OnMicrophoneMute(!strcmp(aTopic, "getUserMedia:muteAudio"));
4144 return NS_OK;
4145 } else if ((!strcmp(aTopic, "application-background") ||
4146 !strcmp(aTopic, "application-foreground")) &&
4147 StaticPrefs::media_getusermedia_camera_background_mute_enabled()) {
4148 // On mobile we turn off any cameras (but not mics) while in the background.
4149 // Keeping things simple for now by duplicating test-covered code above.
4150 //
4151 // NOTE: If a mobile device ever wants to implement "getUserMedia:muteVideo"
4152 // as well, it'd need to update this code to handle & test the combinations.
4153 OnCameraMute(!strcmp(aTopic, "application-background"));
4154 }
4155
4156 return NS_OK;
4157}
4158
4159NS_IMETHODIMPnsresult
4160MediaManager::CollectReports(nsIHandleReportCallback* aHandleReport,
4161 nsISupports* aData, bool aAnonymize) {
4162 size_t amount = 0;
4163 amount += mActiveWindows.ShallowSizeOfExcludingThis(MallocSizeOf);
4164 for (const GetUserMediaWindowListener* listener : mActiveWindows.Values()) {
4165 amount += listener->SizeOfIncludingThis(MallocSizeOf);
4166 }
4167 amount += mActiveCallbacks.ShallowSizeOfExcludingThis(MallocSizeOf);
4168 for (const GetUserMediaTask* task : mActiveCallbacks.Values()) {
4169 // Assume nsString buffers for keys are accounted in mCallIds.
4170 amount += task->SizeOfIncludingThis(MallocSizeOf);
4171 }
4172 amount += mCallIds.ShallowSizeOfExcludingThis(MallocSizeOf);
4173 for (const auto& array : mCallIds.Values()) {
4174 amount += array->ShallowSizeOfExcludingThis(MallocSizeOf);
4175 for (const nsString& callID : *array) {
4176 amount += callID.SizeOfExcludingThisEvenIfShared(MallocSizeOf);
4177 }
4178 }
4179 amount += mPendingGUMRequest.ShallowSizeOfExcludingThis(MallocSizeOf);
4180 // GetUserMediaRequest pointees of mPendingGUMRequest do not have support
4181 // for memory accounting. mPendingGUMRequest logic should probably be moved
4182 // to the front end (bug 1691625).
4183 MOZ_COLLECT_REPORT("explicit/media/media-manager-aggregates", KIND_HEAP,(void)aHandleReport->Callback(""_ns, nsLiteralCString("explicit/media/media-manager-aggregates"
), KIND_HEAP, UNITS_BYTES, amount, nsLiteralCString("Memory used by MediaManager variable length members."
), aData)
4184 UNITS_BYTES, amount,(void)aHandleReport->Callback(""_ns, nsLiteralCString("explicit/media/media-manager-aggregates"
), KIND_HEAP, UNITS_BYTES, amount, nsLiteralCString("Memory used by MediaManager variable length members."
), aData)
4185 "Memory used by MediaManager variable length members.")(void)aHandleReport->Callback(""_ns, nsLiteralCString("explicit/media/media-manager-aggregates"
), KIND_HEAP, UNITS_BYTES, amount, nsLiteralCString("Memory used by MediaManager variable length members."
), aData)
;
4186 return NS_OK;
4187}
4188
4189nsresult MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray) {
4190 MOZ_ASSERT(aArray)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aArray)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aArray))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aArray", "./../../../dom/media/MediaManager.cpp"
, 4190); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aArray" ")"
); do { MOZ_CrashSequence(__null, 4190); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4191
4192 nsCOMPtr<nsIMutableArray> array = nsArray::Create();
4193
4194 for (const auto& entry : mActiveWindows) {
4195 const uint64_t& id = entry.GetKey();
4196 RefPtr<GetUserMediaWindowListener> winListener = entry.GetData();
4197 if (!winListener) {
4198 continue;
4199 }
4200
4201 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(id);
4202 MOZ_ASSERT(window)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(window)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(window))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("window", "./../../../dom/media/MediaManager.cpp"
, 4202); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { MOZ_CrashSequence(__null, 4202); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4203 // XXXkhuey ...
4204 if (!window) {
4205 continue;
4206 }
4207
4208 if (winListener->CapturingVideo() || winListener->CapturingAudio()) {
4209 array->AppendElement(ToSupports(window));
4210 }
4211 }
4212
4213 array.forget(aArray);
4214 return NS_OK;
4215}
4216
4217struct CaptureWindowStateData {
4218 uint16_t* mCamera;
4219 uint16_t* mMicrophone;
4220 uint16_t* mScreenShare;
4221 uint16_t* mWindowShare;
4222 uint16_t* mAppShare;
4223 uint16_t* mBrowserShare;
4224};
4225
4226NS_IMETHODIMPnsresult
4227MediaManager::MediaCaptureWindowState(
4228 nsIDOMWindow* aCapturedWindow, uint16_t* aCamera, uint16_t* aMicrophone,
4229 uint16_t* aScreen, uint16_t* aWindow, uint16_t* aBrowser,
4230 nsTArray<RefPtr<nsIMediaDevice>>& aDevices) {
4231 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4231); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4231); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4232
4233 CaptureState camera = CaptureState::Off;
4234 CaptureState microphone = CaptureState::Off;
4235 CaptureState screen = CaptureState::Off;
4236 CaptureState window = CaptureState::Off;
4237 CaptureState browser = CaptureState::Off;
4238 RefPtr<LocalMediaDeviceSetRefCnt> devices;
4239
4240 nsCOMPtr<nsPIDOMWindowInner> piWin = do_QueryInterface(aCapturedWindow);
4241 if (piWin) {
4242 if (RefPtr<GetUserMediaWindowListener> listener =
4243 GetWindowListener(piWin->WindowID())) {
4244 camera = listener->CapturingSource(MediaSourceEnum::Camera);
4245 microphone = listener->CapturingSource(MediaSourceEnum::Microphone);
4246 screen = listener->CapturingSource(MediaSourceEnum::Screen);
4247 window = listener->CapturingSource(MediaSourceEnum::Window);
4248 browser = listener->CapturingSource(MediaSourceEnum::Browser);
4249 devices = listener->GetDevices();
4250 }
4251 }
4252
4253 *aCamera = FromCaptureState(camera);
4254 *aMicrophone = FromCaptureState(microphone);
4255 *aScreen = FromCaptureState(screen);
4256 *aWindow = FromCaptureState(window);
4257 *aBrowser = FromCaptureState(browser);
4258 if (devices) {
4259 for (auto& device : *devices) {
4260 aDevices.AppendElement(device);
4261 }
4262 }
4263
4264 LOG("{}: window {} capturing {} {} {} {} {}", __FUNCTION__,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4265 piWin ? piWin->WindowID() : -1,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4266 *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLEDdo { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4267 ? "camera (enabled)"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4268 : (*aCamera == nsIMediaManagerService::STATE_CAPTURE_DISABLEDdo { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4269 ? "camera (disabled)"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4270 : ""),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4271 *aMicrophone == nsIMediaManagerService::STATE_CAPTURE_ENABLEDdo { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4272 ? "microphone (enabled)"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4273 : (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLEDdo { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4274 ? "microphone (disabled)"do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4275 : ""),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4276 *aScreen ? "screenshare" : "", *aWindow ? "windowshare" : "",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
4277 *aBrowser ? "browsershare" : "")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: window {} capturing {} {} {} {} {}")), 0))) { mozilla::
detail::log_print_fmt(moz_real_module, "{}: window {} capturing {} {} {} {} {}"
, MOZ_LOG_EXPAND_ARGS __FUNCTION__, piWin ? piWin->WindowID
() : -1, *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
? "camera (enabled)" : (*aCamera == nsIMediaManagerService::
STATE_CAPTURE_DISABLED ? "camera (disabled)" : ""), *aMicrophone
== nsIMediaManagerService::STATE_CAPTURE_ENABLED ? "microphone (enabled)"
: (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
? "microphone (disabled)" : ""), *aScreen ? "screenshare" : ""
, *aWindow ? "windowshare" : "", *aBrowser ? "browsershare" :
""); } } while (0)
;
4278
4279 return NS_OK;
4280}
4281
4282NS_IMETHODIMPnsresult
4283MediaManager::SanitizeDeviceIds(int64_t aSinceWhen) {
4284 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4284); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4284); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4285 LOG("{}: sinceWhen = {}", __FUNCTION__, aSinceWhen)do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "{}: sinceWhen = {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "{}: sinceWhen = {}", MOZ_LOG_EXPAND_ARGS __FUNCTION__
, aSinceWhen); } } while (0)
;
4286
4287 media::SanitizeOriginKeys(aSinceWhen, false); // we fire and forget
4288 return NS_OK;
4289}
4290
4291void MediaManager::StopScreensharing(uint64_t aWindowID) {
4292 // We need to stop window/screensharing for all streams in this innerwindow.
4293
4294 if (RefPtr<GetUserMediaWindowListener> listener =
4295 GetWindowListener(aWindowID)) {
4296 listener->StopSharing();
4297 }
4298}
4299
4300bool MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId) {
4301 // Does page currently have a gUM stream active?
4302
4303 nsCOMPtr<nsIArray> array;
4304 GetActiveMediaCaptureWindows(getter_AddRefs(array));
4305 uint32_t len;
4306 array->GetLength(&len);
4307 for (uint32_t i = 0; i < len; i++) {
4308 nsCOMPtr<nsPIDOMWindowInner> win;
4309 array->QueryElementAt(i, NS_GET_IID(nsPIDOMWindowInner)(nsPIDOMWindowInner::kIID),
4310 getter_AddRefs(win));
4311 if (win && win->WindowID() == aWindowId) {
4312 return true;
4313 }
4314 }
4315
4316 // Or are persistent permissions (audio or video) granted?
4317
4318 return GetPersistentPermissions(aWindowId)
4319 .map([](auto&& aState) {
4320 return aState.mMicrophonePermission ==
4321 PersistentPermissionState::Allow ||
4322 aState.mCameraPermission == PersistentPermissionState::Allow;
4323 })
4324 .unwrapOr(false);
4325}
4326
4327DeviceListener::DeviceListener()
4328 : mStopped(false),
4329 mMainThreadCheck(nullptr),
4330 mPrincipalHandle(PRINCIPAL_HANDLE_NONEnullptr),
4331 mWindowListener(nullptr) {}
4332
4333void DeviceListener::Register(GetUserMediaWindowListener* aListener) {
4334 LOG("DeviceListener {} registering with window listener {}", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} registering with window listener {}")), 0
))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} registering with window listener {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(aListener)); }
} while (0)
4335 fmt::ptr(aListener))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} registering with window listener {}")), 0
))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} registering with window listener {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(aListener)); }
} while (0)
;
4336
4337 MOZ_ASSERT(aListener, "No listener")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aListener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aListener" " (" "No listener"
")", "./../../../dom/media/MediaManager.cpp", 4337); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aListener" ") (" "No listener" ")"); do { MOZ_CrashSequence
(__null, 4337); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4338 MOZ_ASSERT(!mWindowListener, "Already registered")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWindowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWindowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mWindowListener"
" (" "Already registered" ")", "./../../../dom/media/MediaManager.cpp"
, 4338); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mWindowListener"
") (" "Already registered" ")"); do { MOZ_CrashSequence(__null
, 4338); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4339 MOZ_ASSERT(!Activated(), "Already activated")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!Activated()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!Activated()" " ("
"Already activated" ")", "./../../../dom/media/MediaManager.cpp"
, 4339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 4339); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4340
4341 mPrincipalHandle = aListener->GetPrincipalHandle();
4342 mWindowListener = aListener;
4343}
4344
4345void DeviceListener::Activate(RefPtr<LocalMediaDevice> aDevice,
4346 RefPtr<LocalTrackSource> aTrackSource,
4347 bool aStartMuted, bool aIsAllocated) {
4348 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4348); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4348); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4349
4350 LOG("DeviceListener {} activating {} device {}", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} activating {} device {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} activating {} device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), dom::GetEnumString(aDevice
->Kind()).get(), fmt::ptr(aDevice.get())); } } while (0)
4351 dom::GetEnumString(aDevice->Kind()).get(), fmt::ptr(aDevice.get()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} activating {} device {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} activating {} device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), dom::GetEnumString(aDevice
->Kind()).get(), fmt::ptr(aDevice.get())); } } while (0)
;
4352
4353 MOZ_ASSERT(!mStopped, "Cannot activate stopped device listener")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mStopped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mStopped))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mStopped" " (" "Cannot activate stopped device listener"
")", "./../../../dom/media/MediaManager.cpp", 4353); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mStopped" ") (" "Cannot activate stopped device listener"
")"); do { MOZ_CrashSequence(__null, 4353); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4354 MOZ_ASSERT(!Activated(), "Already activated")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!Activated()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!Activated()" " ("
"Already activated" ")", "./../../../dom/media/MediaManager.cpp"
, 4354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 4354); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4355
4356 mMainThreadCheck = PR_GetCurrentThread();
4357 bool offWhileDisabled =
4358 (aDevice->GetMediaSource() == MediaSourceEnum::Microphone &&
4359 Preferences::GetBool(
4360 "media.getusermedia.microphone.off_while_disabled.enabled", true)) ||
4361 (aDevice->GetMediaSource() == MediaSourceEnum::Camera &&
4362 Preferences::GetBool(
4363 "media.getusermedia.camera.off_while_disabled.enabled", true));
4364
4365 if (MediaEventSource<void>* event = aDevice->Source()->CaptureEndedEvent()) {
4366 mCaptureEndedListener = event->Connect(AbstractThread::MainThread(), this,
4367 &DeviceListener::Stop);
4368 }
4369
4370 mDeviceState = MakeUnique<DeviceState>(
4371 std::move(aDevice), std::move(aTrackSource), offWhileDisabled);
4372 mDeviceState->mDeviceMuted = aStartMuted;
4373 mDeviceState->mAllocated = aIsAllocated;
4374 if (aStartMuted) {
4375 mDeviceState->mTrackSource->Mute();
4376 }
4377}
4378
4379RefPtr<DeviceListener::DeviceListenerPromise>
4380DeviceListener::InitializeAsync() {
4381 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4381); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4382 MOZ_DIAGNOSTIC_ASSERT(!mStopped)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mStopped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mStopped))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mStopped", "./../../../dom/media/MediaManager.cpp"
, 4382); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mStopped"
")"); do { MOZ_CrashSequence(__null, 4382); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4383
4384 return InvokeAsync(
4385 MediaManager::Get()->mMediaThread, __func__,
4386 [this, self = RefPtr(this), principal = GetPrincipalHandle(),
4387 device = mDeviceState->mDevice,
4388 track = mDeviceState->mTrackSource->mTrack] {
4389 // Start the device if not muted, or if mOffWhileDisabled is
4390 // false (the device should remain on even when muted).
4391 bool startDevice = !mDeviceState->mDeviceMuted ||
4392 !mDeviceState->mOffWhileDisabled;
4393 nsresult rv = Initialize(principal, device, track, startDevice);
4394 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4395 return GenericPromise::CreateAndResolve(
4396 true, "DeviceListener::InitializeAsync success");
4397 }
4398 return GenericPromise::CreateAndReject(
4399 rv, "DeviceListener::InitializeAsync failure");
4400 })
4401 ->Then(
4402 GetMainThreadSerialEventTarget(), __func__,
4403 [self = RefPtr<DeviceListener>(this), this](bool) {
4404 if (mStopped) {
4405 // We were shut down during the async init
4406 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4407 }
4408
4409 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mTrackEnabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mTrackEnabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mTrackEnabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mDeviceState->mTrackEnabled", "./../../../dom/media/MediaManager.cpp"
, 4409); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { MOZ_CrashSequence(__null, 4409); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4410 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mDeviceEnabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mDeviceEnabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mDeviceEnabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mDeviceState->mDeviceEnabled", "./../../../dom/media/MediaManager.cpp"
, 4410); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { MOZ_CrashSequence(__null, 4410); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4411 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mStopped)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mStopped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mStopped))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mDeviceState->mStopped"
, "./../../../dom/media/MediaManager.cpp", 4411); AnnotateMozCrashReason
("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped" ")"
); do { MOZ_CrashSequence(__null, 4411); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4412
4413 mDeviceState->mDeviceEnabled = true;
4414 mDeviceState->mTrackEnabled = true;
4415 mDeviceState->mTrackEnabledTime = TimeStamp::Now();
4416 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4417 },
4418 [self = RefPtr<DeviceListener>(this), this](nsresult aRv) {
4419 auto kind = mDeviceState->mDevice->Kind();
4420 RefPtr<MediaMgrError> err;
4421 if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) {
4422 auto name =
4423 (aRv == NS_ERROR_FAILURE || aRv == NS_ERROR_NOT_AVAILABLE)
4424 ? MediaMgrError::Name::NotReadableError
4425 : MediaMgrError::Name::AbortError;
4426 nsCString log;
4427 log.AppendPrintf("Starting %s failed",
4428 dom::GetEnumString(kind).get());
4429 err = MakeRefPtr<MediaMgrError>(name, std::move(log));
4430 }
4431
4432 if (mStopped) {
4433 return DeviceListenerPromise::CreateAndReject(err, __func__);
4434 }
4435
4436 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mTrackEnabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mTrackEnabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mTrackEnabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mDeviceState->mTrackEnabled", "./../../../dom/media/MediaManager.cpp"
, 4436); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { MOZ_CrashSequence(__null, 4436); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4437 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mDeviceEnabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mDeviceEnabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mDeviceEnabled
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mDeviceState->mDeviceEnabled", "./../../../dom/media/MediaManager.cpp"
, 4437); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { MOZ_CrashSequence(__null, 4437); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4438 MOZ_DIAGNOSTIC_ASSERT(!mDeviceState->mStopped)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDeviceState->mStopped)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDeviceState->mStopped))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mDeviceState->mStopped"
, "./../../../dom/media/MediaManager.cpp", 4438); AnnotateMozCrashReason
("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped" ")"
); do { MOZ_CrashSequence(__null, 4438); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4439
4440 Stop();
4441
4442 return DeviceListenerPromise::CreateAndReject(err, __func__);
4443 });
4444}
4445
4446nsresult DeviceListener::Initialize(PrincipalHandle aPrincipal,
4447 LocalMediaDevice* aDevice,
4448 MediaTrack* aTrack, bool aStartDevice) {
4449 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 4449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 4449); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4450
4451 auto kind = aDevice->Kind();
4452 aDevice->SetTrack(aTrack, aPrincipal);
4453 nsresult rv = aStartDevice ? aDevice->Start() : NS_OK;
4454 if (kind == MediaDeviceKind::Audioinput ||
4455 kind == MediaDeviceKind::Videoinput) {
4456 if ((rv == NS_ERROR_NOT_AVAILABLE && kind == MediaDeviceKind::Audioinput) ||
4457 (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && kind == MediaDeviceKind::Videoinput)) {
4458 PR_Sleep(200);
4459 rv = aDevice->Start();
4460 }
4461 }
4462 LOG("started {} device {}", dom::GetEnumString(kind).get(),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "started {} device {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "started {} device {}", MOZ_LOG_EXPAND_ARGS
dom::GetEnumString(kind).get(), fmt::ptr(aDevice)); } } while
(0)
4463 fmt::ptr(aDevice))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "started {} device {}")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "started {} device {}", MOZ_LOG_EXPAND_ARGS
dom::GetEnumString(kind).get(), fmt::ptr(aDevice)); } } while
(0)
;
4464 return rv;
4465}
4466
4467already_AddRefed<DeviceListener> DeviceListener::Clone() const {
4468 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4468); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4468); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4469 MediaManager* mgr = MediaManager::GetIfExists();
4470 if (!mgr) {
4471 return nullptr;
4472 }
4473 if (!mWindowListener) {
4474 return nullptr;
4475 }
4476 auto* thisDevice = GetDevice();
4477 if (!thisDevice) {
4478 return nullptr;
4479 }
4480
4481 auto* thisTrackSource = GetTrackSource();
4482 if (!thisTrackSource) {
4483 return nullptr;
4484 }
4485
4486 // See PrepareDOMStream for how a gUM/gDM track is created.
4487 RefPtr<MediaTrack> track;
4488 MediaTrackGraph* mtg = thisTrackSource->mTrack->Graph();
4489 if (const auto source = thisDevice->GetMediaSource();
4490 source == dom::MediaSourceEnum::Microphone) {
4491#ifdef MOZ_WEBRTC1
4492 if (thisDevice->IsFake()) {
4493 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
4494 } else {
4495 track = AudioProcessingTrack::Create(mtg);
4496 track->Suspend(); // Microphone source resumes in SetTrack
4497 }
4498#else
4499 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
4500#endif
4501 } else if (source == dom::MediaSourceEnum::Camera ||
4502 source == dom::MediaSourceEnum::Screen ||
4503 source == dom::MediaSourceEnum::Window ||
4504 source == dom::MediaSourceEnum::Browser) {
4505 track = mtg->CreateSourceTrack(MediaSegment::VIDEO);
4506 }
4507
4508 if (!track) {
4509 return nullptr;
4510 }
4511
4512 RefPtr device = thisDevice->Clone();
4513 auto listener = MakeRefPtr<DeviceListener>();
4514 auto trackSource = MakeRefPtr<LocalTrackSource>(
4515 thisTrackSource->GetPrincipal(), thisTrackSource->mLabel, listener,
4516 thisTrackSource->mSource, track, thisTrackSource->mPeerIdentity,
4517 thisTrackSource->mTrackingId);
4518
4519 LOG("DeviceListener {} registering clone", fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} registering clone")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "DeviceListener {} registering clone"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
;
4520 mWindowListener->Register(listener);
4521 LOG("DeviceListener {} activating clone", fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} activating clone")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "DeviceListener {} activating clone"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this)); } } while (0)
;
4522 mWindowListener->Activate(listener, device, trackSource,
4523 /*aIsAllocated=*/false);
4524
4525 listener->mDeviceState->mDeviceEnabled = mDeviceState->mDeviceEnabled;
4526 listener->mDeviceState->mDeviceMuted = mDeviceState->mDeviceMuted;
4527 listener->mDeviceState->mTrackEnabled = mDeviceState->mTrackEnabled;
4528 listener->mDeviceState->mTrackEnabledTime = TimeStamp::Now();
4529
4530 // We have to do an async operation here, even though Clone() is sync.
4531 // This is fine because JS will not be able to trigger any operation to run
4532 // async on the media thread.
4533 LOG("DeviceListener {} allocating clone device {} async", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} allocating clone device {} async")), 0))
) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} allocating clone device {} async"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(device.get()))
; } } while (0)
4534 fmt::ptr(device.get()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} allocating clone device {} async")), 0))
) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} allocating clone device {} async"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), fmt::ptr(device.get()))
; } } while (0)
;
4535 InvokeAsync(
4536 mgr->mMediaThread, __func__,
4537 [thisDevice = RefPtr(thisDevice), device, prefs = mgr->mPrefs,
4538 windowId = mWindowListener->WindowID(), listener,
4539 principal = GetPrincipalHandle(), track,
4540 startDevice = !listener->mDeviceState->mOffWhileDisabled ||
4541 (!listener->mDeviceState->mDeviceMuted &&
4542 listener->mDeviceState->mDeviceEnabled)] {
4543 const char* outBadConstraint{};
4544 nsresult rv = device->Source()->Allocate(
4545 thisDevice->Constraints(), prefs, windowId, &outBadConstraint);
4546 LOG("Allocated clone device {}. rv={}", fmt::ptr(device.get()),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Allocated clone device {}. rv={}")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "Allocated clone device {}. rv={}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(device.get()), GetStaticErrorName
(rv)); } } while (0)
4547 GetStaticErrorName(rv))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Allocated clone device {}. rv={}")), 0))) { mozilla::detail
::log_print_fmt(moz_real_module, "Allocated clone device {}. rv={}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(device.get()), GetStaticErrorName
(rv)); } } while (0)
;
4548 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4549 return GenericPromise::CreateAndReject(
4550 rv, "DeviceListener::Clone failure #1");
4551 }
4552 rv = listener->Initialize(principal, device, track, startDevice);
4553 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4554 return GenericPromise::CreateAndResolve(
4555 true, "DeviceListener::Clone success");
4556 }
4557 return GenericPromise::CreateAndReject(
4558 rv, "DeviceListener::Clone failure #2");
4559 })
4560 ->Then(
4561 GetMainThreadSerialEventTarget(), __func__,
4562 [listener, device,
4563 trackSource](GenericPromise::ResolveOrRejectValue&& aValue) {
4564 if (aValue.IsReject()) {
4565 // Allocating/initializing failed. Stopping the device listener
4566 // will destroy the MediaStreamTrackSource's MediaTrack, which
4567 // will make the MediaStreamTrack's mTrack MediaTrack auto-end
4568 // due to lack of inputs. This makes the MediaStreamTrack's
4569 // readyState transition to "ended" as expected.
4570 LOG("Allocating clone device {} failed. Stopping.",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Allocating clone device {} failed. Stopping.")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Allocating clone device {} failed. Stopping."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(device.get())); } } while (0)
4571 fmt::ptr(device.get()))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Allocating clone device {} failed. Stopping.")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "Allocating clone device {} failed. Stopping."
, MOZ_LOG_EXPAND_ARGS fmt::ptr(device.get())); } } while (0)
;
4572 listener->Stop();
4573 return;
4574 }
4575 listener->mDeviceState->mAllocated = true;
4576 if (listener->mDeviceState->mStopped && !sHasMainThreadShutdown) {
4577 MediaManager::Dispatch(NS_NewRunnableFunction(
4578 "DeviceListener::Clone::Stop",
4579 [device = listener->mDeviceState->mDevice]() {
4580 device->Stop();
4581 device->Deallocate();
4582 }));
4583 }
4584 });
4585
4586 return listener.forget();
4587}
4588
4589void DeviceListener::Stop() {
4590 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4590); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4591
4592 if (mStopped) {
4593 return;
4594 }
4595 mStopped = true;
4596
4597 LOG("DeviceListener {} stopping", fmt::ptr(this))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} stopping")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "DeviceListener {} stopping", MOZ_LOG_EXPAND_ARGS
fmt::ptr(this)); } } while (0)
;
4598
4599 if (mDeviceState) {
4600 mDeviceState->mDisableTimer->Cancel();
4601
4602 if (mDeviceState->mStopped) {
4603 // device already stopped.
4604 return;
4605 }
4606 mDeviceState->mStopped = true;
4607
4608 mDeviceState->mTrackSource->Stop();
4609
4610 if (mDeviceState->mAllocated) {
4611 MediaManager::Dispatch(NewTaskFrom([device = mDeviceState->mDevice]() {
4612 device->Stop();
4613 device->Deallocate();
4614 }));
4615 }
4616
4617 mWindowListener->ChromeAffectingStateChanged();
4618 }
4619
4620 mCaptureEndedListener.DisconnectIfExists();
4621
4622 // Keep a strong ref to the removed window listener.
4623 RefPtr<GetUserMediaWindowListener> windowListener = mWindowListener;
4624 mWindowListener = nullptr;
4625 windowListener->Remove(this);
4626}
4627
4628void DeviceListener::GetSettings(MediaTrackSettings& aOutSettings) const {
4629 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4629); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4629); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4630 LocalMediaDevice* device = GetDevice();
4631 device->GetSettings(aOutSettings);
4632
4633 MediaSourceEnum mediaSource = device->GetMediaSource();
4634 if (mediaSource == MediaSourceEnum::Camera ||
4635 mediaSource == MediaSourceEnum::Microphone) {
4636 aOutSettings.mDeviceId.Construct(device->mID);
4637 aOutSettings.mGroupId.Construct(device->mGroupID);
4638 }
4639}
4640
4641void DeviceListener::GetCapabilities(
4642 MediaTrackCapabilities& aOutCapabilities) const {
4643 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4643); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4643); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4644 LocalMediaDevice* device = GetDevice();
4645 device->GetCapabilities(aOutCapabilities);
4646
4647 MediaSourceEnum mediaSource = device->GetMediaSource();
4648 if (mediaSource == MediaSourceEnum::Camera ||
4649 mediaSource == MediaSourceEnum::Microphone) {
4650 aOutCapabilities.mDeviceId.Construct(device->mID);
4651 aOutCapabilities.mGroupId.Construct(device->mGroupID);
4652 }
4653}
4654
4655auto DeviceListener::UpdateDevice(bool aOn) -> RefPtr<DeviceOperationPromise> {
4656 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4656); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4656); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4657 RefPtr<DeviceListener> self = this;
4658 DeviceState& state = *mDeviceState;
4659 return MediaManager::Dispatch<DeviceOperationPromise>(
4660 __func__,
4661 [self, device = state.mDevice,
4662 aOn](MozPromiseHolder<DeviceOperationPromise>& h) {
4663 LOG("Turning {} device ({})", aOn ? "on" : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Turning {} device ({})")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "Turning {} device ({})", MOZ_LOG_EXPAND_ARGS
aOn ? "on" : "off", NS_ConvertUTF16toUTF8(device->mName).
get()); } } while (0)
4664 NS_ConvertUTF16toUTF8(device->mName).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "Turning {} device ({})")), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, "Turning {} device ({})", MOZ_LOG_EXPAND_ARGS
aOn ? "on" : "off", NS_ConvertUTF16toUTF8(device->mName).
get()); } } while (0)
;
4665 h.Resolve(aOn ? device->Start() : device->Stop(), __func__);
4666 })
4667 ->Then(
4668 GetMainThreadSerialEventTarget(), __func__,
4669 [self, this, &state, aOn](nsresult aResult) {
4670 if (state.mStopped) {
4671 // Device was stopped on main thread during the operation. Done.
4672 return DeviceOperationPromise::CreateAndResolve(aResult,
4673 __func__);
4674 }
4675 LOG("DeviceListener {} turning {} {} input device {}",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} turning {} {} input device {}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} turning {} {} input device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aOn ? "on" : "off", dom
::GetEnumString(GetDevice()->Kind()).get(), ((bool)(__builtin_expect
(!!(!NS_FAILED_impl(aResult)), 1))) ? "succeeded" : "failed")
; } } while (0)
4676 fmt::ptr(this), aOn ? "on" : "off",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} turning {} {} input device {}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} turning {} {} input device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aOn ? "on" : "off", dom
::GetEnumString(GetDevice()->Kind()).get(), ((bool)(__builtin_expect
(!!(!NS_FAILED_impl(aResult)), 1))) ? "succeeded" : "failed")
; } } while (0)
4677 dom::GetEnumString(GetDevice()->Kind()).get(),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} turning {} {} input device {}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} turning {} {} input device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aOn ? "on" : "off", dom
::GetEnumString(GetDevice()->Kind()).get(), ((bool)(__builtin_expect
(!!(!NS_FAILED_impl(aResult)), 1))) ? "succeeded" : "failed")
; } } while (0)
4678 NS_SUCCEEDED(aResult) ? "succeeded" : "failed")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} turning {} {} input device {}")), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} turning {} {} input device {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aOn ? "on" : "off", dom
::GetEnumString(GetDevice()->Kind()).get(), ((bool)(__builtin_expect
(!!(!NS_FAILED_impl(aResult)), 1))) ? "succeeded" : "failed")
; } } while (0)
;
4679
4680 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT) {
4681 // This path handles errors from starting or stopping the
4682 // device. NS_ERROR_ABORT are for cases where *we* aborted. They
4683 // need graceful handling.
4684 if (aOn) {
4685 // Starting the device failed. Stopping the track here will
4686 // make the MediaStreamTrack end after a pass through the
4687 // MediaTrackGraph.
4688 Stop();
4689 } else {
4690 // Stopping the device failed. This is odd, but not fatal.
4691 MOZ_ASSERT_UNREACHABLE("The device should be stoppable")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"The device should be stoppable" ")", "./../../../dom/media/MediaManager.cpp"
, 4691); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "The device should be stoppable" ")"
); do { MOZ_CrashSequence(__null, 4691); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4692 }
4693 }
4694 return DeviceOperationPromise::CreateAndResolve(aResult, __func__);
4695 },
4696 []() {
4697 MOZ_ASSERT_UNREACHABLE("Unexpected and unhandled reject")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected and unhandled reject" ")", "./../../../dom/media/MediaManager.cpp"
, 4697); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { MOZ_CrashSequence(__null, 4697); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4698 return DeviceOperationPromise::CreateAndReject(false, __func__);
4699 });
4700}
4701
4702void DeviceListener::SetDeviceEnabled(bool aEnable) {
4703 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4703); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4703); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4704 MOZ_ASSERT(Activated(), "No device to set enabled state for")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(Activated()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("Activated()" " ("
"No device to set enabled state for" ")", "./../../../dom/media/MediaManager.cpp"
, 4704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set enabled state for" ")"); do { MOZ_CrashSequence
(__null, 4704); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4705
4706 DeviceState& state = *mDeviceState;
4707
4708 LOG("DeviceListener {} {} {} device", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4709 aEnable ? "enabling" : "disabling",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4710 dom::GetEnumString(GetDevice()->Kind()).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
;
4711
4712 state.mTrackEnabled = aEnable;
4713
4714 if (state.mStopped) {
4715 // Device terminally stopped. Updating device state is pointless.
4716 return;
4717 }
4718
4719 if (state.mOperationInProgress) {
4720 // If a timer is in progress, it needs to be canceled now so the next
4721 // DisableTrack() gets a fresh start. Canceling will trigger another
4722 // operation.
4723 state.mDisableTimer->Cancel();
4724 return;
4725 }
4726
4727 if (state.mDeviceEnabled == aEnable) {
4728 // Device is already in the desired state.
4729 return;
4730 }
4731
4732 // All paths from here on must end in setting
4733 // `state.mOperationInProgress` to false.
4734 state.mOperationInProgress = true;
4735
4736 RefPtr<MediaTimerPromise> timerPromise;
4737 if (aEnable) {
4738 timerPromise = MediaTimerPromise::CreateAndResolve(true, __func__);
4739 state.mTrackEnabledTime = TimeStamp::Now();
4740 } else {
4741 const TimeDuration maxDelay =
4742 TimeDuration::FromMilliseconds(Preferences::GetUint(
4743 GetDevice()->Kind() == MediaDeviceKind::Audioinput
4744 ? "media.getusermedia.microphone.off_while_disabled.delay_ms"
4745 : "media.getusermedia.camera.off_while_disabled.delay_ms",
4746 3000));
4747 const TimeDuration durationEnabled =
4748 TimeStamp::Now() - state.mTrackEnabledTime;
4749 const TimeDuration delay = TimeDuration::Max(
4750 TimeDuration::FromMilliseconds(0), maxDelay - durationEnabled);
4751 timerPromise = state.mDisableTimer->WaitFor(delay, __func__);
4752 }
4753
4754 RefPtr<DeviceListener> self = this;
4755 timerPromise
4756 ->Then(
4757 GetMainThreadSerialEventTarget(), __func__,
4758 [self, this, &state, aEnable]() mutable {
4759 MOZ_ASSERT(state.mDeviceEnabled != aEnable,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state.mDeviceEnabled != aEnable)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state.mDeviceEnabled != aEnable
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"state.mDeviceEnabled != aEnable" " (" "Device operation hasn't started"
")", "./../../../dom/media/MediaManager.cpp", 4760); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable" ") (" "Device operation hasn't started"
")"); do { MOZ_CrashSequence(__null, 4760); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4760 "Device operation hasn't started")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state.mDeviceEnabled != aEnable)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state.mDeviceEnabled != aEnable
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"state.mDeviceEnabled != aEnable" " (" "Device operation hasn't started"
")", "./../../../dom/media/MediaManager.cpp", 4760); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable" ") (" "Device operation hasn't started"
")"); do { MOZ_CrashSequence(__null, 4760); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4761 MOZ_ASSERT(state.mOperationInProgress,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state.mOperationInProgress)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state.mOperationInProgress))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("state.mOperationInProgress"
" (" "It's our responsibility to reset the inProgress state"
")", "./../../../dom/media/MediaManager.cpp", 4762); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ") (" "It's our responsibility to reset the inProgress state"
")"); do { MOZ_CrashSequence(__null, 4762); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4762 "It's our responsibility to reset the inProgress state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state.mOperationInProgress)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state.mOperationInProgress))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("state.mOperationInProgress"
" (" "It's our responsibility to reset the inProgress state"
")", "./../../../dom/media/MediaManager.cpp", 4762); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ") (" "It's our responsibility to reset the inProgress state"
")"); do { MOZ_CrashSequence(__null, 4762); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4763
4764 LOG("DeviceListener {} {} {} device - starting device operation",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4765 fmt::ptr(this), aEnable ? "enabling" : "disabling",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4766 dom::GetEnumString(GetDevice()->Kind()).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aEnable ? "enabling" : "disabling"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
;
4767
4768 if (state.mStopped) {
4769 // Source was stopped between timer resolving and this runnable.
4770 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4771 __func__);
4772 }
4773
4774 state.mDeviceEnabled = aEnable;
4775
4776 if (mWindowListener) {
4777 mWindowListener->ChromeAffectingStateChanged();
4778 }
4779 if (!state.mOffWhileDisabled || state.mDeviceMuted) {
4780 // If the feature to turn a device off while disabled is itself
4781 // disabled, or the device is currently user agent muted, then
4782 // we shortcut the device operation and tell the
4783 // ux-updating code that everything went fine.
4784 return DeviceOperationPromise::CreateAndResolve(NS_OK, __func__);
4785 }
4786 return UpdateDevice(aEnable);
4787 },
4788 []() {
4789 // Timer was canceled by us. We signal this with NS_ERROR_ABORT.
4790 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4791 __func__);
4792 })
4793 ->Then(
4794 GetMainThreadSerialEventTarget(), __func__,
4795 [self, this, &state, aEnable](nsresult aResult) mutable {
4796 MOZ_ASSERT_IF(aResult != NS_ERROR_ABORT,do { if (aResult != NS_ERROR_ABORT) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(state.mDeviceEnabled
== aEnable)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(state.mDeviceEnabled == aEnable))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("state.mDeviceEnabled == aEnable"
, "./../../../dom/media/MediaManager.cpp", 4797); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable" ")"); do {
MOZ_CrashSequence(__null, 4797); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (false
)
4797 state.mDeviceEnabled == aEnable)do { if (aResult != NS_ERROR_ABORT) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(state.mDeviceEnabled
== aEnable)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(state.mDeviceEnabled == aEnable))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("state.mDeviceEnabled == aEnable"
, "./../../../dom/media/MediaManager.cpp", 4797); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable" ")"); do {
MOZ_CrashSequence(__null, 4797); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (false
)
;
4798 MOZ_ASSERT(state.mOperationInProgress)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state.mOperationInProgress)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state.mOperationInProgress))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("state.mOperationInProgress"
, "./../../../dom/media/MediaManager.cpp", 4798); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ")"); do { MOZ_CrashSequence
(__null, 4798); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4799 state.mOperationInProgress = false;
4800
4801 if (state.mStopped) {
4802 // Device was stopped on main thread during the operation.
4803 // Nothing to do.
4804 return;
4805 }
4806
4807 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT && !aEnable) {
4808 // To keep our internal state sane in this case, we disallow
4809 // future stops due to disable.
4810 state.mOffWhileDisabled = false;
4811 return;
4812 }
4813
4814 // This path is for a device operation aResult that was success or
4815 // NS_ERROR_ABORT (*we* canceled the operation).
4816 // At this point we have to follow up on the intended state, i.e.,
4817 // update the device state if the track state changed in the
4818 // meantime.
4819
4820 if (state.mTrackEnabled != state.mDeviceEnabled) {
4821 // Track state changed during this operation. We'll start over.
4822 SetDeviceEnabled(state.mTrackEnabled);
4823 }
4824 },
4825 []() { MOZ_ASSERT_UNREACHABLE("Unexpected and unhandled reject")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected and unhandled reject" ")", "./../../../dom/media/MediaManager.cpp"
, 4825); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { MOZ_CrashSequence(__null, 4825); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; });
4826}
4827
4828void DeviceListener::SetDeviceMuted(bool aMute) {
4829 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 4829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4829); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4830 MOZ_ASSERT(Activated(), "No device to set muted state for")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(Activated())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(Activated()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("Activated()" " ("
"No device to set muted state for" ")", "./../../../dom/media/MediaManager.cpp"
, 4830); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set muted state for" ")"); do { MOZ_CrashSequence
(__null, 4830); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4831
4832 DeviceState& state = *mDeviceState;
4833
4834 LOG("DeviceListener {} {} {} device", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4835 aMute ? "muting" : "unmuting",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4836 dom::GetEnumString(GetDevice()->Kind()).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device")), 0))) { mozilla::detail::
log_print_fmt(moz_real_module, "DeviceListener {} {} {} device"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
;
4837
4838 if (state.mStopped) {
4839 // Device terminally stopped. Updating device state is pointless.
4840 return;
4841 }
4842
4843 if (state.mDeviceMuted == aMute) {
4844 // Device is already in the desired state.
4845 return;
4846 }
4847
4848 LOG("DeviceListener {} {} {} device - starting device operation",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4849 fmt::ptr(this), aMute ? "muting" : "unmuting",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
4850 dom::GetEnumString(GetDevice()->Kind()).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} {} device - starting device operation"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} {} device - starting device operation"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "muting" : "unmuting"
, dom::GetEnumString(GetDevice()->Kind()).get()); } } while
(0)
;
4851
4852 state.mDeviceMuted = aMute;
4853
4854 if (mWindowListener) {
4855 mWindowListener->ChromeAffectingStateChanged();
4856 }
4857 // Update trackSource to fire mute/unmute events on all its tracks
4858 if (aMute) {
4859 state.mTrackSource->Mute();
4860 } else {
4861 state.mTrackSource->Unmute();
4862 }
4863 if (!state.mOffWhileDisabled || !state.mDeviceEnabled) {
4864 // If the pref to turn the underlying device is itself off, or the device
4865 // is already off, it's unecessary to do anything else.
4866 return;
4867 }
4868 UpdateDevice(!aMute);
4869}
4870
4871void DeviceListener::MuteOrUnmuteCamera(bool aMute) {
4872 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4872); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4872); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4873
4874 if (mStopped) {
4875 return;
4876 }
4877
4878 MOZ_RELEASE_ASSERT(mWindowListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mWindowListener"
, "./../../../dom/media/MediaManager.cpp", 4878); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "mWindowListener" ")"); do { MOZ_CrashSequence
(__null, 4878); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4879 LOG("DeviceListener {} MuteOrUnmuteCamera: {}", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} MuteOrUnmuteCamera: {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} MuteOrUnmuteCamera: {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "mute" : "unmute"
); } } while (0)
4880 aMute ? "mute" : "unmute")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} MuteOrUnmuteCamera: {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} MuteOrUnmuteCamera: {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "mute" : "unmute"
); } } while (0)
;
4881
4882 if (GetDevice() &&
4883 (GetDevice()->GetMediaSource() == MediaSourceEnum::Camera)) {
4884 SetDeviceMuted(aMute);
4885 }
4886}
4887
4888void DeviceListener::MuteOrUnmuteMicrophone(bool aMute) {
4889 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4889); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4889); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4890
4891 if (mStopped) {
4892 return;
4893 }
4894
4895 MOZ_RELEASE_ASSERT(mWindowListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindowListener))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mWindowListener"
, "./../../../dom/media/MediaManager.cpp", 4895); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "mWindowListener" ")"); do { MOZ_CrashSequence
(__null, 4895); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4896 LOG("DeviceListener {} MuteOrUnmuteMicrophone: {}", fmt::ptr(this),do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} MuteOrUnmuteMicrophone: {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} MuteOrUnmuteMicrophone: {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "mute" : "unmute"
); } } while (0)
4897 aMute ? "mute" : "unmute")do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} MuteOrUnmuteMicrophone: {}")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "DeviceListener {} MuteOrUnmuteMicrophone: {}"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), aMute ? "mute" : "unmute"
); } } while (0)
;
4898
4899 if (GetDevice() &&
4900 (GetDevice()->GetMediaSource() == MediaSourceEnum::Microphone)) {
4901 SetDeviceMuted(aMute);
4902 }
4903}
4904
4905bool DeviceListener::CapturingVideo() const {
4906 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4906); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4906); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4907 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4908 MediaEngineSource::IsVideo(GetDevice()->GetMediaSource()) &&
4909 (!GetDevice()->IsFake() ||
4910 Preferences::GetBool("media.navigator.permission.fake"));
4911}
4912
4913bool DeviceListener::CapturingAudio() const {
4914 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4914); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4914); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4915 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4916 MediaEngineSource::IsAudio(GetDevice()->GetMediaSource()) &&
4917 (!GetDevice()->IsFake() ||
4918 Preferences::GetBool("media.navigator.permission.fake"));
4919}
4920
4921CaptureState DeviceListener::CapturingSource(MediaSourceEnum aSource) const {
4922 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4922); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4922); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4923 if (GetDevice()->GetMediaSource() != aSource) {
4924 // This DeviceListener doesn't capture a matching source
4925 return CaptureState::Off;
4926 }
4927
4928 if (mDeviceState->mStopped) {
4929 // The source is a match but has been permanently stopped
4930 return CaptureState::Off;
4931 }
4932
4933 if ((aSource == MediaSourceEnum::Camera ||
4934 aSource == MediaSourceEnum::Microphone) &&
4935 GetDevice()->IsFake() &&
4936 !Preferences::GetBool("media.navigator.permission.fake")) {
4937 // Fake Camera and Microphone only count if there is no fake permission
4938 return CaptureState::Off;
4939 }
4940
4941 // Source is a match and is active and unmuted
4942
4943 if (mDeviceState->mDeviceEnabled && !mDeviceState->mDeviceMuted) {
4944 return CaptureState::Enabled;
4945 }
4946
4947 return CaptureState::Disabled;
4948}
4949
4950RefPtr<DeviceListener::DeviceListenerPromise> DeviceListener::ApplyConstraints(
4951 const MediaTrackConstraints& aConstraints, CallerType aCallerType) {
4952 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 4952); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4952); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4953
4954 if (mStopped || mDeviceState->mStopped) {
4955 LOG("DeviceListener {} {} device applyConstraints, but device is stopped",do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} device applyConstraints, but device is stopped"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} device applyConstraints, but device is stopped"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), dom::GetEnumString(GetDevice
()->Kind()).get()); } } while (0)
4956 fmt::ptr(this), dom::GetEnumString(GetDevice()->Kind()).get())do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "DeviceListener {} {} device applyConstraints, but device is stopped"
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, "DeviceListener {} {} device applyConstraints, but device is stopped"
, MOZ_LOG_EXPAND_ARGS fmt::ptr(this), dom::GetEnumString(GetDevice
()->Kind()).get()); } } while (0)
;
4957 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4958 }
4959
4960 MediaManager* mgr = MediaManager::GetIfExists();
4961 if (!mgr) {
4962 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4963 }
4964
4965 return InvokeAsync(
4966 mgr->mMediaThread, __func__,
4967 [device = mDeviceState->mDevice, aConstraints, prefs = mgr->mPrefs,
4968 aCallerType]() mutable -> RefPtr<DeviceListenerPromise> {
4969 MOZ_ASSERT(MediaManager::IsInMediaThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(MediaManager::IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(MediaManager::IsInMediaThread
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("MediaManager::IsInMediaThread()", "./../../../dom/media/MediaManager.cpp"
, 4969); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 4969); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4970 MediaManager* mgr = MediaManager::GetIfExists();
4971 MOZ_RELEASE_ASSERT(mgr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mgr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mgr))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mgr", "./../../../dom/media/MediaManager.cpp"
, 4971); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mgr"
")"); do { MOZ_CrashSequence(__null, 4971); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // Must exist while media thread is alive
4972 const char* badConstraint = nullptr;
4973 nsresult rv =
4974 device->Reconfigure(aConstraints, mgr->mPrefs, &badConstraint);
4975 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4976 if (rv == NS_ERROR_INVALID_ARG) {
4977 // Reconfigure failed due to constraints
4978 if (!badConstraint) {
4979 nsTArray<RefPtr<LocalMediaDevice>> devices;
4980 devices.AppendElement(device);
4981 badConstraint = MediaConstraintsHelper::SelectSettings(
4982 NormalizedConstraints(aConstraints), prefs, devices,
4983 aCallerType);
4984 }
4985 } else {
4986 // Unexpected. ApplyConstraints* cannot fail with any other error.
4987 badConstraint = "";
4988 LOG("ApplyConstraints-Task: Unexpected fail %" PRIx32,do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "ApplyConstraints-Task: Unexpected fail %" "x")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "ApplyConstraints-Task: Unexpected fail %"
"x", MOZ_LOG_EXPAND_ARGS static_cast<uint32_t>(rv)); }
} while (0)
4989 static_cast<uint32_t>(rv))do { const ::mozilla::LogModule* moz_real_module = gMediaTrackGraphLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, "ApplyConstraints-Task: Unexpected fail %" "x")), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, "ApplyConstraints-Task: Unexpected fail %"
"x", MOZ_LOG_EXPAND_ARGS static_cast<uint32_t>(rv)); }
} while (0)
;
4990 }
4991
4992 return DeviceListenerPromise::CreateAndReject(
4993 MakeRefPtr<MediaMgrError>(
4994 MediaMgrError::Name::OverconstrainedError, "",
4995 NS_ConvertASCIItoUTF16(badConstraint)),
4996 __func__);
4997 }
4998 // Reconfigure was successful
4999 return DeviceListenerPromise::CreateAndResolve(false, __func__);
5000 });
5001}
5002
5003PrincipalHandle DeviceListener::GetPrincipalHandle() const {
5004 return mPrincipalHandle;
5005}
5006
5007void GetUserMediaWindowListener::StopSharing() {
5008 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 5008); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5008); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5009
5010 for (auto& l : mActiveListeners.Clone()) {
5011 MediaSourceEnum source = l->GetDevice()->GetMediaSource();
5012 if (source == MediaSourceEnum::Screen ||
5013 source == MediaSourceEnum::Window ||
5014 source == MediaSourceEnum::AudioCapture ||
5015 source == MediaSourceEnum::Browser) {
5016 l->Stop();
5017 }
5018 }
5019}
5020
5021void GetUserMediaWindowListener::StopRawID(const nsString& removedDeviceID) {
5022 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 5022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5022); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5023
5024 for (auto& l : mActiveListeners.Clone()) {
5025 if (removedDeviceID.Equals(l->GetDevice()->RawID())) {
5026 l->Stop();
5027 }
5028 }
5029}
5030
5031void GetUserMediaWindowListener::MuteOrUnmuteCameras(bool aMute) {
5032 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 5032); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5032); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5033
5034 if (mCamerasAreMuted == aMute) {
5035 return;
5036 }
5037 mCamerasAreMuted = aMute;
5038
5039 for (auto& l : mActiveListeners.Clone()) {
5040 if (l->GetDevice()->Kind() == MediaDeviceKind::Videoinput) {
5041 l->MuteOrUnmuteCamera(aMute);
5042 }
5043 }
5044}
5045
5046void GetUserMediaWindowListener::MuteOrUnmuteMicrophones(bool aMute) {
5047 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Only call on main thread" ")", "./../../../dom/media/MediaManager.cpp"
, 5047); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5047); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5048
5049 if (mMicrophonesAreMuted == aMute) {
5050 return;
5051 }
5052 mMicrophonesAreMuted = aMute;
5053
5054 for (auto& l : mActiveListeners.Clone()) {
5055 if (l->GetDevice()->Kind() == MediaDeviceKind::Audioinput) {
5056 l->MuteOrUnmuteMicrophone(aMute);
5057 }
5058 }
5059}
5060
5061void GetUserMediaWindowListener::ChromeAffectingStateChanged() {
5062 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../dom/media/MediaManager.cpp", 5062); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 5062); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5063
5064 // We wait until stable state before notifying chrome so chrome only does
5065 // one update if more updates happen in this event loop.
5066
5067 if (mChromeNotificationTaskPosted) {
5068 return;
5069 }
5070
5071 nsCOMPtr<nsIRunnable> runnable =
5072 NewRunnableMethod("GetUserMediaWindowListener::NotifyChrome", this,
5073 &GetUserMediaWindowListener::NotifyChrome);
5074 nsContentUtils::RunInStableState(runnable.forget());
5075 mChromeNotificationTaskPosted = true;
5076}
5077
5078void GetUserMediaWindowListener::NotifyChrome() {
5079 MOZ_ASSERT(mChromeNotificationTaskPosted)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mChromeNotificationTaskPosted)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mChromeNotificationTaskPosted
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mChromeNotificationTaskPosted", "./../../../dom/media/MediaManager.cpp"
, 5079); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mChromeNotificationTaskPosted"
")"); do { MOZ_CrashSequence(__null, 5079); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5080 mChromeNotificationTaskPosted = false;
5081
5082 NS_DispatchToMainThread(NS_NewRunnableFunction(
5083 "MediaManager::NotifyChrome", [windowID = mWindowID]() {
5084 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowID);
5085 if (!window) {
5086 MOZ_ASSERT_UNREACHABLE("Should have window")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Should have window" ")", "./../../../dom/media/MediaManager.cpp"
, 5086); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should have window" ")"); do { MOZ_CrashSequence
(__null, 5086); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5087 return;
5088 }
5089
5090 nsresult rv = MediaManager::NotifyRecordingStatusChange(window);
5091 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5092 MOZ_ASSERT_UNREACHABLE("Should be able to notify chrome")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Should be able to notify chrome" ")", "./../../../dom/media/MediaManager.cpp"
, 5092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should be able to notify chrome"
")"); do { MOZ_CrashSequence(__null, 5092); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5093 return;
5094 }
5095 }));
5096}
5097
5098#undef LOG
5099
5100} // namespace mozilla