Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/./../../../dom/media/MediaManager.cpp
Warning:line 2986, 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/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-11-12-001017-1011516-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/File.h"
31#include "mozilla/dom/GetUserMediaRequestBinding.h"
32#include "mozilla/dom/MediaDeviceInfo.h"
33#include "mozilla/dom/MediaDevices.h"
34#include "mozilla/dom/MediaDevicesBinding.h"
35#include "mozilla/dom/MediaStreamBinding.h"
36#include "mozilla/dom/MediaStreamTrackBinding.h"
37#include "mozilla/dom/PermissionsPolicyUtils.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::File;
166using dom::GetUserMediaRequest;
167using dom::MediaDeviceKind;
168using dom::MediaDevices;
169using dom::MediaSourceEnum;
170using dom::MediaStreamConstraints;
171using dom::MediaStreamError;
172using dom::MediaStreamTrack;
173using dom::MediaStreamTrackSource;
174using dom::MediaTrackCapabilities;
175using dom::MediaTrackConstraints;
176using dom::MediaTrackConstraintSet;
177using dom::MediaTrackSettings;
178using dom::OwningBooleanOrMediaTrackConstraints;
179using dom::OwningStringOrStringSequence;
180using dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters;
181using dom::PermissionsPolicyUtils;
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// Glean label names must be lowercase, unlike dom::GetEnumString(), so this
1492// cannot just reuse the WebIDL enum strings (e.g. "audioCapture").
1493static const char* GleanLabelForMediaSource(MediaSourceEnum aSource) {
1494 switch (aSource) {
1495 case MediaSourceEnum::Camera:
1496 return "camera";
1497 case MediaSourceEnum::Screen:
1498 return "screen";
1499 case MediaSourceEnum::Application:
1500 return "application";
1501 case MediaSourceEnum::Window:
1502 return "window";
1503 case MediaSourceEnum::Browser:
1504 return "browser";
1505 case MediaSourceEnum::Microphone:
1506 return "microphone";
1507 case MediaSourceEnum::AudioCapture:
1508 return "audiocapture";
1509 case MediaSourceEnum::Other:
1510 return "other";
1511 }
1512 MOZ_CRASH("Unexpected MediaSourceEnum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected MediaSourceEnum value"
, "./../../../dom/media/MediaManager.cpp", 1512); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected MediaSourceEnum value" ")"); do { MOZ_CrashSequence
(__null, 1512); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
1513}
1514
1515/**
1516 * Describes a requested task that handles response from the UI to a
1517 * getUserMedia() request and sends results back to content. If the request
1518 * is allowed and device initialization succeeds, then the MozPromise is
1519 * resolved with a DOMMediaStream having a track or tracks for the approved
1520 * device or devices.
1521 */
1522class GetUserMediaStreamTask final : public GetUserMediaTask {
1523 public:
1524 GetUserMediaStreamTask(
1525 const MediaStreamConstraints& aConstraints,
1526 MozPromiseHolder<MediaManager::StreamPromise>&& aHolder,
1527 uint64_t aWindowID, RefPtr<GetUserMediaWindowListener> aWindowListener,
1528 RefPtr<DeviceListener> aAudioDeviceListener,
1529 RefPtr<DeviceListener> aVideoDeviceListener,
1530 const MediaEnginePrefs& aPrefs, const ipc::PrincipalInfo& aPrincipalInfo,
1531 enum CallerType aCallerType, bool aShouldFocusSource)
1532 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1533 mConstraints(aConstraints),
1534 mHolder(std::move(aHolder)),
1535 mWindowListener(std::move(aWindowListener)),
1536 mAudioDeviceListener(std::move(aAudioDeviceListener)),
1537 mVideoDeviceListener(std::move(aVideoDeviceListener)),
1538 mPrefs(aPrefs),
1539 mShouldFocusSource(aShouldFocusSource),
1540 mManager(MediaManager::GetInstance()) {}
1541
1542 void Allowed(RefPtr<LocalMediaDevice> aAudioDevice,
1543 RefPtr<LocalMediaDevice> aVideoDevice) {
1544 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"
, 1544); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioDevice || aVideoDevice"
")"); do { MOZ_CrashSequence(__null, 1544); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1545 if (aAudioDevice) {
1546 glean::webrtc::get_user_media_source_granted
1547 .Get(nsDependentCString(
1548 GleanLabelForMediaSource(aAudioDevice->GetMediaSource())))
1549 .Add();
1550 }
1551 if (aVideoDevice) {
1552 glean::webrtc::get_user_media_source_granted
1553 .Get(nsDependentCString(
1554 GleanLabelForMediaSource(aVideoDevice->GetMediaSource())))
1555 .Add();
1556 }
1557 mAudioDevice = std::move(aAudioDevice);
1558 mVideoDevice = std::move(aVideoDevice);
1559 // Reuse the same thread to save memory.
1560 MediaManager::Dispatch(
1561 NewRunnableMethod("GetUserMediaStreamTask::AllocateDevices", this,
1562 &GetUserMediaStreamTask::AllocateDevices));
1563 }
1564
1565 GetUserMediaStreamTask* AsGetUserMediaStreamTask() override { return this; }
1566
1567 private:
1568 ~GetUserMediaStreamTask() override {
1569 if (!mHolder.IsEmpty()) {
1570 Fail(MediaMgrError::Name::NotAllowedError);
1571 }
1572 }
1573
1574 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns,
1575 const nsString& aConstraint = u""_ns) {
1576 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage, aConstraint),
1577 __func__);
1578 // We add a disabled listener to the StreamListeners array until accepted
1579 // If this was the only active MediaStream, remove the window from the list.
1580 NS_DispatchToMainThread(NS_NewRunnableFunction(
1581 "DeviceListener::Stop",
1582 [audio = mAudioDeviceListener, video = mVideoDeviceListener] {
1583 if (audio) {
1584 audio->Stop();
1585 }
1586 if (video) {
1587 video->Stop();
1588 }
1589 }));
1590 }
1591
1592 /**
1593 * Runs on a separate thread and is responsible for allocating devices.
1594 *
1595 * Do not run this on the main thread.
1596 */
1597 void AllocateDevices() {
1598 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", 1598); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1598); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1599 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)
;
1600
1601 // Allocate a video or audio device and return a MediaStream via
1602 // PrepareDOMStream().
1603
1604 nsresult rv;
1605 const char* errorMsg = nullptr;
1606 const char* badConstraint = nullptr;
1607
1608 if (mAudioDevice) {
1609 auto& constraints = GetInvariant(mConstraints.mAudio);
1610 rv = mAudioDevice->Allocate(constraints, mPrefs, mWindowID,
1611 &badConstraint);
1612 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1613 errorMsg = "Failed to allocate audiosource";
1614 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1615 nsTArray<RefPtr<LocalMediaDevice>> devices;
1616 devices.AppendElement(mAudioDevice);
1617 badConstraint = MediaConstraintsHelper::SelectSettings(
1618 NormalizedConstraints(constraints), mPrefs, devices, mCallerType);
1619 }
1620 }
1621 }
1622 if (!errorMsg && mVideoDevice) {
1623 auto& constraints = GetInvariant(mConstraints.mVideo);
1624 rv = mVideoDevice->Allocate(constraints, mPrefs, mWindowID,
1625 &badConstraint);
1626 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1627 errorMsg = "Failed to allocate videosource";
1628 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1629 nsTArray<RefPtr<LocalMediaDevice>> devices;
1630 devices.AppendElement(mVideoDevice);
1631 badConstraint = MediaConstraintsHelper::SelectSettings(
1632 NormalizedConstraints(constraints), mPrefs, devices, mCallerType);
1633 }
1634 if (mAudioDevice) {
1635 mAudioDevice->Deallocate();
1636 }
1637 } else {
1638 mVideoTrackingId.emplace(mVideoDevice->GetTrackingId());
1639 }
1640 }
1641 if (errorMsg) {
1642 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)
;
1643 if (badConstraint) {
1644 Fail(MediaMgrError::Name::OverconstrainedError, ""_ns,
1645 NS_ConvertUTF8toUTF16(badConstraint));
1646 } else {
1647 Fail(MediaMgrError::Name::NotReadableError, nsCString(errorMsg));
1648 }
1649 NS_DispatchToMainThread(
1650 NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest", []() {
1651 if (MediaManager* manager = MediaManager::GetIfExists()) {
1652 manager->SendPendingGUMRequest();
1653 }
1654 }));
1655 return;
1656 }
1657 NS_DispatchToMainThread(
1658 NewRunnableMethod("GetUserMediaStreamTask::PrepareDOMStream", this,
1659 &GetUserMediaStreamTask::PrepareDOMStream));
1660 }
1661
1662 public:
1663 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1664 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", 1664); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1664); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1665 Fail(aName, aMessage);
1666 }
1667
1668 const MediaStreamConstraints& GetConstraints() { return mConstraints; }
1669
1670 void PrimeVoiceProcessing() {
1671 mPrimingStream = MakeAndAddRef<PrimingCubebVoiceInputStream>();
1672 mPrimingStream->Init();
1673 }
1674
1675 private:
1676 void PrepareDOMStream();
1677
1678 class PrimingCubebVoiceInputStream {
1679 class Listener final : public CubebInputStream::Listener {
1680 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"
, 1680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1680
); __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"
, 1680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1680
); __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:
;
1681
1682 private:
1683 ~Listener() = default;
1684
1685 long DataCallback(const void*, long) override {
1686 MOZ_CRASH("Unexpected data callback")do { do { } while (false); MOZ_ReportCrash("" "Unexpected data callback"
, "./../../../dom/media/MediaManager.cpp", 1686); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected data callback" ")"); do { MOZ_CrashSequence
(__null, 1686); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
1687 }
1688 void StateCallback(cubeb_state) override {}
1689 void DeviceChangedCallback() override {}
1690 };
1691
1692 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"
, 1693); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1693
); __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"
, 1693); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1693
); __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:
1693 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"
, 1693); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1693
); __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"
, 1693); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1693
); __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:
1694
1695 public:
1696 void Init() {
1697 mCubebThread.GetEventTarget()->Dispatch(
1698 NS_NewRunnableFunction(__func__, [this, self = RefPtr(this)] {
1699 mCubebThread.AssertOnCurrentThread();
1700 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)
;
1701 TRACE("PrimingCubebVoiceInputStream::Init")AutoTracer trace(gAudioCallbackTraceLogger, "PrimingCubebVoiceInputStream::Init"
);
;
1702 const cubeb_devid default_device = nullptr;
1703 const uint32_t mono = 1;
1704 const uint32_t rate = CubebUtils::PreferredSampleRate(false);
1705 const bool isVoice = true;
1706 mCubebStream =
1707 CubebInputStream::Create(default_device, mono, rate, isVoice,
1708 MakeRefPtr<Listener>().get());
1709 }));
1710 }
1711
1712 private:
1713 ~PrimingCubebVoiceInputStream() {
1714 mCubebThread.AssertOnCurrentThread();
1715 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)
;
1716 mCubebStream = nullptr;
1717 }
1718
1719 const EventTargetCapability<nsISerialEventTarget> mCubebThread =
1720 EventTargetCapability<nsISerialEventTarget>(
1721 TaskQueue::Create(CubebUtils::GetCubebOperationThread(),
1722 "PrimingCubebInputStream::mCubebThread")
1723 .get());
1724 UniquePtr<CubebInputStream> mCubebStream MOZ_GUARDED_BY(mCubebThread)__attribute__((guarded_by(mCubebThread)));
1725 };
1726
1727 // Constraints derived from those passed to getUserMedia() but adjusted for
1728 // preferences, defaults, and security
1729 const MediaStreamConstraints mConstraints;
1730
1731 MozPromiseHolder<MediaManager::StreamPromise> mHolder;
1732 // GetUserMediaWindowListener with which DeviceListeners are registered
1733 const RefPtr<GetUserMediaWindowListener> mWindowListener;
1734 const RefPtr<DeviceListener> mAudioDeviceListener;
1735 const RefPtr<DeviceListener> mVideoDeviceListener;
1736 // MediaDevices are set when selected and Allowed() by the UI.
1737 RefPtr<LocalMediaDevice> mAudioDevice;
1738 RefPtr<LocalMediaDevice> mVideoDevice;
1739 RefPtr<PrimingCubebVoiceInputStream> mPrimingStream;
1740 // Tracking id unique for a video frame source. Set when the corresponding
1741 // device has been allocated.
1742 Maybe<TrackingId> mVideoTrackingId;
1743 // Copy of MediaManager::mPrefs
1744 const MediaEnginePrefs mPrefs;
1745 // media.getusermedia.window.focus_source.enabled
1746 const bool mShouldFocusSource;
1747 // The MediaManager is referenced at construction so that it won't be
1748 // created after its ShutdownBlocker would run.
1749 const RefPtr<MediaManager> mManager;
1750};
1751
1752/**
1753 * Creates a MediaTrack, attaches a listener and resolves a MozPromise to
1754 * provide the stream to the DOM.
1755 *
1756 * All of this must be done on the main thread!
1757 */
1758void GetUserMediaStreamTask::PrepareDOMStream() {
1759 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", 1759); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1759); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1760 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)
;
1761 nsGlobalWindowInner* window =
1762 nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
1763
1764 // We're on main-thread, and the windowlist can only
1765 // be invalidated from the main-thread (see OnNavigation)
1766 if (!mManager->IsWindowListenerStillActive(mWindowListener)) {
1767 // This window is no longer live. mListener has already been removed.
1768 return;
1769 }
1770
1771 MediaTrackGraph::GraphDriverType graphDriverType =
1772 mAudioDevice ? MediaTrackGraph::AUDIO_THREAD_DRIVER
1773 : MediaTrackGraph::SYSTEM_THREAD_DRIVER;
1774 MediaTrackGraph* mtg = MediaTrackGraph::GetInstance(
1775 graphDriverType, window, MediaTrackGraph::REQUEST_DEFAULT_SAMPLE_RATE,
1776 MediaTrackGraph::DEFAULT_OUTPUT_DEVICE);
1777
1778 auto domStream = MakeRefPtr<DOMMediaStream>(window);
1779 RefPtr<LocalTrackSource> audioTrackSource;
1780 RefPtr<LocalTrackSource> videoTrackSource;
1781 nsCOMPtr<nsIPrincipal> principal;
1782 RefPtr<PeerIdentity> peerIdentity = nullptr;
1783 if (!mConstraints.mPeerIdentity.IsEmpty()) {
1784 peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
1785 principal = NullPrincipal::CreateWithInheritedAttributes(
1786 window->GetExtantDoc()->NodePrincipal());
1787 } else {
1788 principal = window->GetExtantDoc()->NodePrincipal();
1789 }
1790 RefPtr<GenericNonExclusivePromise> firstFramePromise;
1791 if (mAudioDevice) {
1792 if (mAudioDevice->GetMediaSource() == MediaSourceEnum::AudioCapture) {
1793 // AudioCapture is a special case, here, in the sense that we're not
1794 // really using the audio source and the SourceMediaTrack, which acts
1795 // as placeholders. We re-route a number of tracks internally in the
1796 // MTG and mix them down instead.
1797 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"
, 1800)
1798 "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"
, 1800)
1799 "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"
, 1800)
1800 "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"
, 1800)
;
1801 auto audioCaptureSource = MakeRefPtr<AudioCaptureTrackSource>(
1802 principal, window, u"Window audio capture"_ns,
1803 mtg->CreateAudioCaptureTrack(), peerIdentity);
1804 audioTrackSource = audioCaptureSource;
1805 RefPtr<MediaStreamTrack> track = new dom::AudioStreamTrack(
1806 window, audioCaptureSource->InputTrack(), audioCaptureSource);
1807 domStream->AddTrackInternal(track);
1808 } else {
1809 const nsString& audioDeviceName = mAudioDevice->mName;
1810 RefPtr<MediaTrack> track;
1811#ifdef MOZ_WEBRTC1
1812 if (mAudioDevice->IsFake()) {
1813 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1814 } else {
1815 track = AudioProcessingTrack::Create(mtg);
1816 track->Suspend(); // Microphone source resumes in SetTrack
1817 }
1818#else
1819 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1820#endif
1821 audioTrackSource = new LocalTrackSource(
1822 principal, audioDeviceName, mAudioDeviceListener,
1823 mAudioDevice->GetMediaSource(), track, peerIdentity);
1824 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", 1824); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mAudio)" ")"
); do { MOZ_CrashSequence(__null, 1824); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1825 RefPtr<MediaStreamTrack> domTrack = new dom::AudioStreamTrack(
1826 window, track, audioTrackSource, dom::MediaStreamTrackState::Live,
1827 false, GetInvariant(mConstraints.mAudio));
1828 domStream->AddTrackInternal(domTrack);
1829 }
1830 }
1831 if (mVideoDevice) {
1832 const nsString& videoDeviceName = mVideoDevice->mName;
1833 RefPtr<MediaTrack> track = mtg->CreateSourceTrack(MediaSegment::VIDEO);
1834 videoTrackSource = new LocalTrackSource(
1835 principal, videoDeviceName, mVideoDeviceListener,
1836 mVideoDevice->GetMediaSource(), track, peerIdentity, *mVideoTrackingId);
1837 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", 1837); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mVideo)" ")"
); do { MOZ_CrashSequence(__null, 1837); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1838 RefPtr<MediaStreamTrack> domTrack = new dom::VideoStreamTrack(
1839 window, track, videoTrackSource, dom::MediaStreamTrackState::Live,
1840 false, GetInvariant(mConstraints.mVideo));
1841 domStream->AddTrackInternal(domTrack);
1842 switch (mVideoDevice->GetMediaSource()) {
1843 case MediaSourceEnum::Browser:
1844 case MediaSourceEnum::Screen:
1845 case MediaSourceEnum::Window:
1846 // Wait for first frame for screen-sharing devices, to ensure
1847 // with and height settings are available immediately, to pass wpt.
1848 firstFramePromise = mVideoDevice->Source()->GetFirstFramePromise();
1849 break;
1850 default:
1851 break;
1852 }
1853 }
1854
1855 if (!domStream || (!audioTrackSource && !videoTrackSource) ||
1856 sHasMainThreadShutdown) {
1857 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)
;
1858
1859 mHolder.Reject(
1860 MakeRefPtr<MediaMgrError>(
1861 MediaMgrError::Name::AbortError,
1862 sHasMainThreadShutdown ? "In shutdown"_ns : "No stream."_ns),
1863 __func__);
1864 return;
1865 }
1866
1867 // Activate our device listeners. We'll call Start() on the source when we
1868 // get a callback that the MediaStream has started consuming. The listener
1869 // is freed when the page is invalidated (on navigation or close).
1870 if (mAudioDeviceListener) {
1871 mWindowListener->Activate(mAudioDeviceListener, mAudioDevice,
1872 std::move(audioTrackSource),
1873 /*aIsAllocated=*/true);
1874 }
1875 if (mVideoDeviceListener) {
1876 mWindowListener->Activate(mVideoDeviceListener, mVideoDevice,
1877 std::move(videoTrackSource),
1878 /*aIsAllocated=*/true);
1879 }
1880
1881 // Dispatch to the media thread to ask it to start the sources, because that
1882 // can take a while.
1883 typedef DeviceListener::DeviceListenerPromise PromiseType;
1884 AutoTArray<RefPtr<PromiseType>, 2> promises;
1885 if (mAudioDeviceListener) {
1886 promises.AppendElement(mAudioDeviceListener->InitializeAsync());
1887 }
1888 if (mVideoDeviceListener) {
1889 promises.AppendElement(mVideoDeviceListener->InitializeAsync());
1890 }
1891 PromiseType::All(GetMainThreadSerialEventTarget(), promises)
1892 ->Then(
1893 GetMainThreadSerialEventTarget(), __func__,
1894 [manager = mManager, windowListener = mWindowListener,
1895 firstFramePromise] {
1896 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)
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 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)
;
1898 // Initiating and starting devices succeeded.
1899 windowListener->ChromeAffectingStateChanged();
1900 manager->SendPendingGUMRequest();
1901 if (!firstFramePromise) {
1902 return DeviceListener::DeviceListenerPromise::CreateAndResolve(
1903 true, __func__);
1904 }
1905 RefPtr<DeviceListener::DeviceListenerPromise> resolvePromise =
1906 firstFramePromise->Then(
1907 GetMainThreadSerialEventTarget(), __func__,
1908 [] {
1909 return DeviceListener::DeviceListenerPromise::
1910 CreateAndResolve(true, __func__);
1911 },
1912 [](nsresult aError) {
1913 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", 1913); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)), 0)))"
")"); do { MOZ_CrashSequence(__null, 1913); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1914 if (aError == NS_ERROR_UNEXPECTED) {
1915 return DeviceListener::DeviceListenerPromise::
1916 CreateAndReject(
1917 MakeRefPtr<MediaMgrError>(
1918 MediaMgrError::Name::NotAllowedError),
1919 __func__);
1920 }
1921 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", 1921); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aError == NS_ERROR_ABORT" ")"); do { MOZ_CrashSequence
(__null, 1921); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1922 return DeviceListener::DeviceListenerPromise::
1923 CreateAndReject(MakeRefPtr<MediaMgrError>(
1924 MediaMgrError::Name::AbortError,
1925 "In shutdown"),
1926 __func__);
1927 });
1928 return resolvePromise;
1929 },
1930 [audio = mAudioDeviceListener,
1931 video = mVideoDeviceListener](const RefPtr<MediaMgrError>& aError) {
1932 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)
1933 "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)
;
1934 if (audio) {
1935 audio->Stop();
1936 }
1937 if (video) {
1938 video->Stop();
1939 }
1940 return DeviceListener::DeviceListenerPromise::CreateAndReject(
1941 aError, __func__);
1942 })
1943 ->Then(
1944 GetMainThreadSerialEventTarget(), __func__,
1945 [holder = std::move(mHolder), domStream, callerType = mCallerType,
1946 shouldFocus = mShouldFocusSource, videoDevice = mVideoDevice](
1947 const DeviceListener::DeviceListenerPromise::ResolveOrRejectValue&
1948 aValue) mutable {
1949 if (aValue.IsResolve()) {
1950 if (auto* mgr = MediaManager::GetIfExists();
1951 mgr && !sHasMainThreadShutdown && videoDevice &&
1952 callerType == CallerType::NonSystem && shouldFocus) {
1953 // Device was successfully started. Attempt to focus the
1954 // source.
1955 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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1956 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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1957 "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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1958 [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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1959 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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1960 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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1961 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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1962 }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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1963 })))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", 1963); 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, 1963); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1964 }
1965
1966 holder.Resolve(domStream, __func__);
1967 } else {
1968 holder.Reject(aValue.RejectValue(), __func__);
1969 }
1970 });
1971
1972 PersistPrincipalKey();
1973}
1974
1975/**
1976 * Describes a requested task that handles response from the UI to a
1977 * selectAudioOutput() request and sends results back to content. If the
1978 * request is allowed, then the MozPromise is resolved with a MediaDevice
1979 * for the approved device.
1980 */
1981class SelectAudioOutputTask final : public GetUserMediaTask {
1982 public:
1983 SelectAudioOutputTask(MozPromiseHolder<LocalDevicePromise>&& aHolder,
1984 uint64_t aWindowID, enum CallerType aCallerType,
1985 const ipc::PrincipalInfo& aPrincipalInfo)
1986 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1987 mHolder(std::move(aHolder)) {}
1988
1989 void Allowed(RefPtr<LocalMediaDevice> aAudioOutput) {
1990 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"
, 1990); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioOutput"
")"); do { MOZ_CrashSequence(__null, 1990); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1991 mHolder.Resolve(std::move(aAudioOutput), __func__);
1992 PersistPrincipalKey();
1993 }
1994
1995 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1996 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", 1996); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 1996); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1997 Fail(aName, aMessage);
1998 }
1999
2000 SelectAudioOutputTask* AsSelectAudioOutputTask() override { return this; }
2001
2002 private:
2003 ~SelectAudioOutputTask() override {
2004 if (!mHolder.IsEmpty()) {
2005 Fail(MediaMgrError::Name::NotAllowedError);
2006 }
2007 }
2008
2009 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns) {
2010 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage), __func__);
2011 }
2012
2013 private:
2014 MozPromiseHolder<LocalDevicePromise> mHolder;
2015};
2016
2017/* static */
2018void MediaManager::GuessVideoDeviceGroupIDs(MediaDeviceSet& aDevices,
2019 const MediaDeviceSet& aAudios) {
2020 // Run the logic in a lambda to avoid duplication.
2021 auto updateGroupIdIfNeeded = [&](RefPtr<MediaDevice>& aVideo,
2022 const MediaDeviceKind aKind) -> bool {
2023 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", 2023); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideo->mKind == MediaDeviceKind::Videoinput"
")"); do { MOZ_CrashSequence(__null, 2023); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2024 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", 2025); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { MOZ_CrashSequence(__null, 2025); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2025 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", 2025); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { MOZ_CrashSequence(__null, 2025); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2026 // This will store the new group id if a match is found.
2027 nsString newVideoGroupID;
2028 // If the group id needs to be updated this will become true. It is
2029 // necessary when the new group id is an empty string. Without this extra
2030 // variable to signal the update, we would resort to test if
2031 // `newVideoGroupId` is empty. However,
2032 // that check does not work when the new group id is an empty string.
2033 bool updateGroupId = false;
2034 for (const RefPtr<MediaDevice>& dev : aAudios) {
2035 if (dev->mKind != aKind) {
2036 continue;
2037 }
2038 if (!FindInReadable(aVideo->mRawName, dev->mRawName)) {
2039 continue;
2040 }
2041 if (newVideoGroupID.IsEmpty()) {
2042 // This is only expected on first match. If that's the only match group
2043 // id will be updated to this one at the end of the loop.
2044 updateGroupId = true;
2045 newVideoGroupID = dev->mRawGroupID;
2046 } else {
2047 // More than one device found, it is impossible to know which group id
2048 // is the correct one.
2049 updateGroupId = false;
2050 newVideoGroupID = u""_ns;
2051 break;
2052 }
2053 }
2054 if (updateGroupId) {
2055 aVideo = MediaDevice::CopyWithNewRawGroupId(aVideo, newVideoGroupID);
2056 return true;
2057 }
2058 return false;
2059 };
2060
2061 for (RefPtr<MediaDevice>& video : aDevices) {
2062 if (video->mKind != MediaDeviceKind::Videoinput) {
2063 continue;
2064 }
2065 if (updateGroupIdIfNeeded(video, MediaDeviceKind::Audioinput)) {
2066 // GroupId has been updated, continue to the next video device
2067 continue;
2068 }
2069 // GroupId has not been updated, check among the outputs
2070 updateGroupIdIfNeeded(video, MediaDeviceKind::Audiooutput);
2071 }
2072}
2073
2074namespace {
2075
2076// Class to hold the promise used to request device access and to resolve
2077// even if |task| does not run, either because GeckoViewPermissionProcessChild
2078// gets destroyed before ask-device-permission receives its
2079// got-device-permission reply, or because the media thread is no longer
2080// available. In either case, the process is shutting down so the result is
2081// not important. Reject with a dummy error so the following Then-handler can
2082// resolve with an empty set, so that callers do not need to handle rejection.
2083class DeviceAccessRequestPromiseHolderWithFallback
2084 : public MozPromiseHolder<MozPromise<
2085 CamerasAccessStatus, mozilla::ipc::ResponseRejectReason, true>> {
2086 public:
2087 DeviceAccessRequestPromiseHolderWithFallback() = default;
2088 DeviceAccessRequestPromiseHolderWithFallback(
2089 DeviceAccessRequestPromiseHolderWithFallback&&) = default;
2090 ~DeviceAccessRequestPromiseHolderWithFallback() {
2091 if (!IsEmpty()) {
2092 Reject(ipc::ResponseRejectReason::ChannelClosed, __func__);
2093 }
2094 }
2095};
2096
2097} // anonymous namespace
2098
2099MediaManager::DeviceEnumerationParams::DeviceEnumerationParams(
2100 dom::MediaSourceEnum aInputType, DeviceType aType,
2101 nsAutoCString aForcedDeviceName)
2102 : mInputType(aInputType),
2103 mType(aType),
2104 mForcedDeviceName(std::move(aForcedDeviceName)) {
2105 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", 2105); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2105); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2106 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", 2106); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mInputType != dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2106); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2107 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"
, 2107); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mType == DeviceType::Real"
")"); do { MOZ_CrashSequence(__null, 2107); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2108}
2109
2110MediaManager::VideoDeviceEnumerationParams::VideoDeviceEnumerationParams(
2111 dom::MediaSourceEnum aInputType, DeviceType aType,
2112 nsAutoCString aForcedDeviceName, nsAutoCString aForcedMicrophoneName)
2113 : DeviceEnumerationParams(aInputType, aType, std::move(aForcedDeviceName)),
2114 mForcedMicrophoneName(std::move(aForcedMicrophoneName)) {
2115 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", 2115); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2115); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2116 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"
, 2117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2117); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2117 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"
, 2117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2117); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2118 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", 2118); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mType == DeviceType::Real" ")"); do { MOZ_CrashSequence
(__null, 2118); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
2119}
2120
2121MediaManager::EnumerationParams::EnumerationParams(
2122 EnumerationFlags aFlags, Maybe<VideoDeviceEnumerationParams> aVideo,
2123 Maybe<DeviceEnumerationParams> aAudio)
2124 : mFlags(aFlags), mVideo(std::move(aVideo)), mAudio(std::move(aAudio)) {
2125 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", 2125); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2125); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2126 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", 2126); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaEngineSource::IsVideo(mVideo->mInputType)"
")"); do { MOZ_CrashSequence(__null, 2126); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2127 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"
, 2128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2128); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2128 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"
, 2128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2128); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2129 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"
, 2130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2130); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2130 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"
, 2130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { MOZ_CrashSequence(__null, 2130); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2131 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", 2131); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "MediaEngineSource::IsAudio(mAudio->mInputType)"
")"); do { MOZ_CrashSequence(__null, 2131); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2132 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"
, 2133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2133); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2133 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"
, 2133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2133); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2134 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"
, 2135); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2135); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2135 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"
, 2135); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { MOZ_CrashSequence(__null, 2135); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2136}
2137
2138bool MediaManager::EnumerationParams::HasFakeCams() const {
2139 return mVideo
2140 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2141 .valueOr(false);
2142}
2143
2144bool MediaManager::EnumerationParams::HasFakeMics() const {
2145 return mAudio
2146 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2147 .valueOr(false);
2148}
2149
2150bool MediaManager::EnumerationParams::RealDeviceRequested() const {
2151 auto isReal = [](const auto& aDev) { return aDev.mType == DeviceType::Real; };
2152 return mVideo.map(isReal).valueOr(false) ||
2153 mAudio.map(isReal).valueOr(false) ||
2154 mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2155}
2156
2157MediaSourceEnum MediaManager::EnumerationParams::VideoInputType() const {
2158 return mVideo.map([](const auto& aDev) { return aDev.mInputType; })
2159 .valueOr(MediaSourceEnum::Other);
2160}
2161
2162MediaSourceEnum MediaManager::EnumerationParams::AudioInputType() const {
2163 return mAudio.map([](const auto& aDev) { return aDev.mInputType; })
2164 .valueOr(MediaSourceEnum::Other);
2165}
2166
2167/* static */ MediaManager::EnumerationParams
2168MediaManager::CreateEnumerationParams(dom::MediaSourceEnum aVideoInputType,
2169 dom::MediaSourceEnum aAudioInputType,
2170 EnumerationFlags aFlags) {
2171 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", 2171); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2171); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2172 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", 2173); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2173); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2173 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", 2173); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2173); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2174 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", 2175); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2175); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2175 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", 2175); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { MOZ_CrashSequence(__null, 2175); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2176 const bool forceFakes = aFlags.contains(EnumerationFlag::ForceFakes);
2177 const bool fakeByPref = Preferences::GetBool("media.navigator.streams.fake");
2178 Maybe<VideoDeviceEnumerationParams> videoParams;
2179 Maybe<DeviceEnumerationParams> audioParams;
2180 nsAutoCString audioDev;
2181 bool audioDevRead = false;
2182 constexpr const char* VIDEO_DEV_NAME = "media.video_loopback_dev";
2183 constexpr const char* AUDIO_DEV_NAME = "media.audio_loopback_dev";
2184 const auto ensureDev = [](const char* aPref, nsAutoCString* aLoopDev,
2185 bool* aPrefRead) {
2186 if (aPrefRead) {
2187 if (*aPrefRead) {
2188 return;
2189 }
2190 *aPrefRead = true;
2191 }
2192
2193 if (NS_FAILED(Preferences::GetCString(aPref, *aLoopDev))((bool)(__builtin_expect(!!(NS_FAILED_impl(Preferences::GetCString
(aPref, *aLoopDev))), 0)))
) {
2194 // Ensure we fall back to an empty string if reading the pref failed.
2195 aLoopDev->SetIsVoid(true);
2196 }
2197 };
2198 if (MediaEngineSource::IsVideo(aVideoInputType)) {
2199 nsAutoCString videoDev;
2200 DeviceType type = DeviceType::Real;
2201 if (aVideoInputType == MediaSourceEnum::Camera) {
2202 // Fake and loopback devices are supported for only Camera.
2203 if (forceFakes) {
2204 type = DeviceType::Fake;
2205 } else {
2206 ensureDev(VIDEO_DEV_NAME, &videoDev, nullptr);
2207 // Loopback prefs take precedence over fake prefs
2208 if (fakeByPref && videoDev.IsEmpty()) {
2209 type = DeviceType::Fake;
2210 } else {
2211 // For groupId correlation we need the audio device name.
2212 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2213 }
2214 }
2215 }
2216 videoParams = Some(VideoDeviceEnumerationParams(
2217 aVideoInputType, type, std::move(videoDev), audioDev));
2218 }
2219 if (MediaEngineSource::IsAudio(aAudioInputType)) {
2220 nsAutoCString realAudioDev;
2221 DeviceType type = DeviceType::Real;
2222 if (aAudioInputType == MediaSourceEnum::Microphone) {
2223 // Fake and loopback devices are supported for only Microphone.
2224 if (forceFakes) {
2225 type = DeviceType::Fake;
2226 } else {
2227 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2228 // Loopback prefs take precedence over fake prefs
2229 if (fakeByPref && audioDev.IsEmpty()) {
2230 type = DeviceType::Fake;
2231 } else {
2232 realAudioDev = std::move(audioDev);
2233 }
2234 }
2235 }
2236 audioParams = Some(DeviceEnumerationParams(aAudioInputType, type,
2237 std::move(realAudioDev)));
2238 }
2239 return EnumerationParams(aFlags, std::move(videoParams),
2240 std::move(audioParams));
2241}
2242
2243RefPtr<DeviceSetPromise>
2244MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
2245 EnumerationParams aParams) {
2246 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", 2246); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2246); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2247 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", 2248); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { MOZ_CrashSequence(__null, 2248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2248 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", 2248); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { MOZ_CrashSequence(__null, 2248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2249
2250 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)
2251 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)
2252 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)
;
2253
2254 if (sHasMainThreadShutdown) {
2255 // The media thread is no longer available but the result will not be
2256 // observable.
2257 return DeviceSetPromise::CreateAndResolve(
2258 new MediaDeviceSetRefCnt(),
2259 "MaybeRequestPermissionAndEnumerateRawDevices: sync shutdown");
2260 }
2261
2262 const bool hasVideo = aParams.mVideo.isSome();
2263 const bool hasAudio = aParams.mAudio.isSome();
2264 const bool hasAudioOutput =
2265 aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2266 const bool hasFakeCams = aParams.HasFakeCams();
2267 const bool hasFakeMics = aParams.HasFakeMics();
2268 // True if at least one of video input or audio input is a real device
2269 // or there is audio output.
2270 const bool realDeviceRequested = (!hasFakeCams && hasVideo) ||
2271 (!hasFakeMics && hasAudio) || hasAudioOutput;
2272
2273 using NativePromise =
2274 MozPromise<CamerasAccessStatus, mozilla::ipc::ResponseRejectReason,
2275 /* IsExclusive = */ true>;
2276 RefPtr<NativePromise> deviceAccessPromise;
2277 if (realDeviceRequested &&
2278 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
2279 Preferences::GetBool("media.navigator.permission.device", false)) {
2280 // Need to ask permission to retrieve list of all devices;
2281 // notify frontend observer and wait for callback notification to post
2282 // task.
2283 const char16_t* const type =
2284 (aParams.VideoInputType() != MediaSourceEnum::Camera) ? u"audio"
2285 : (aParams.AudioInputType() != MediaSourceEnum::Microphone) ? u"video"
2286 : u"all";
2287 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2288 DeviceAccessRequestPromiseHolderWithFallback deviceAccessPromiseHolder;
2289 deviceAccessPromise = deviceAccessPromiseHolder.Ensure(__func__);
2290 RefPtr task = NS_NewRunnableFunction(
2291 __func__, [holder = std::move(deviceAccessPromiseHolder)]() mutable {
2292 holder.Resolve(CamerasAccessStatus::Granted,
2293 "getUserMedia:got-device-permission");
2294 });
2295 obs->NotifyObservers(static_cast<nsIRunnable*>(task),
2296 "getUserMedia:ask-device-permission", type);
2297 } else if (realDeviceRequested && hasVideo &&
2298 aParams.VideoInputType() == MediaSourceEnum::Camera) {
2299 ipc::PBackgroundChild* backgroundChild =
2300 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2301 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(
2302 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest));
2303 }
2304
2305 if (!deviceAccessPromise) {
2306 // No device access request needed. We can proceed directly, but we still
2307 // need to update camera availability, because the camera engine is always
2308 // created together with the WebRTC backend, which is done because
2309 // devicechange events must work before prompting in cases where persistent
2310 // permission has already been given. Making a request to camera access not
2311 // allowing a permission request does exactly what we need in this case.
2312 ipc::PBackgroundChild* backgroundChild =
2313 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2314 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(false);
2315 }
2316
2317 return deviceAccessPromise->Then(
2318 GetCurrentSerialEventTarget(), __func__,
2319 [this, self = RefPtr(this), aParams = std::move(aParams)](
2320 NativePromise::ResolveOrRejectValue&& aValue) mutable {
2321 if (sHasMainThreadShutdown) {
2322 return DeviceSetPromise::CreateAndResolve(
2323 new MediaDeviceSetRefCnt(),
2324 "MaybeRequestPermissionAndEnumerateRawDevices: async shutdown");
2325 }
2326
2327 if (aValue.IsReject()) {
2328 // IPC failure probably means we're in shutdown. Resolve with
2329 // an empty set, so that callers do not need to handle rejection.
2330 return DeviceSetPromise::CreateAndResolve(
2331 new MediaDeviceSetRefCnt(),
2332 "MaybeRequestPermissionAndEnumerateRawDevices: ipc failure");
2333 }
2334
2335 if (auto v = aValue.ResolveValue();
2336 v == CamerasAccessStatus::Error ||
2337 v == CamerasAccessStatus::Rejected) {
2338 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)
2339 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)
;
2340 if (v == CamerasAccessStatus::Error) {
2341 NS_WARNING("Failed to request camera access")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to request camera access"
, nullptr, "./../../../dom/media/MediaManager.cpp", 2341)
;
2342 }
2343 return DeviceSetPromise::CreateAndReject(
2344 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2345 "MaybeRequestPermissionAndEnumerateRawDevices: camera access "
2346 "rejected");
2347 }
2348
2349 // We have to nest this, unfortunately, since we have no guarantees that
2350 // mMediaThread is alive. If we'd reject due to shutdown above, and have
2351 // the below async operation in a Then handler on the media thread the
2352 // Then handler would fail to dispatch and trip an assert on
2353 // destruction, for instance.
2354 return InvokeAsync(
2355 mMediaThread, __func__, [aParams = std::move(aParams)]() mutable {
2356 return DeviceSetPromise::CreateAndResolve(
2357 EnumerateRawDevices(std::move(aParams)),
2358 "MaybeRequestPermissionAndEnumerateRawDevices: success");
2359 });
2360 });
2361}
2362
2363/**
2364 * EnumerateRawDevices - Enumerate a list of audio & video devices that
2365 * satisfy passed-in constraints. List contains raw id's.
2366 */
2367
2368/* static */ RefPtr<MediaManager::MediaDeviceSetRefCnt>
2369MediaManager::EnumerateRawDevices(EnumerationParams aParams) {
2370 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", 2370); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "IsInMediaThread()" ")"); do { MOZ_CrashSequence
(__null, 2370); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2371 // Only enumerate what's asked for, and only fake cams and mics.
2372 RefPtr<MediaEngine> fakeBackend, realBackend;
2373 if (aParams.HasFakeCams() || aParams.HasFakeMics()) {
2374 fakeBackend = new MediaEngineFake();
2375 }
2376 if (aParams.RealDeviceRequested()) {
2377 MediaManager* manager = MediaManager::GetIfExists();
2378 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", 2378); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "manager" ") (" "Must exist while media thread is alive"
")"); do { MOZ_CrashSequence(__null, 2378); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2379 realBackend = manager->GetBackend();
2380 }
2381
2382 RefPtr<MediaEngine> videoBackend;
2383 RefPtr<MediaEngine> audioBackend;
2384 Maybe<MediaDeviceSet> micsOfVideoBackend;
2385 Maybe<MediaDeviceSet> speakers;
2386 RefPtr devices = new MediaDeviceSetRefCnt();
2387
2388 // Enumerate microphones first, then cameras, then speakers, since
2389 // the enumerateDevices() algorithm expects them listed in that order.
2390 if (const auto& audio = aParams.mAudio; audio.isSome()) {
2391 audioBackend = aParams.HasFakeMics() ? fakeBackend : realBackend;
2392 MediaDeviceSet audios;
2393 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)
2394 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)
;
2395 GetMediaDevices(audioBackend, audio->mInputType, audios,
2396 audio->mForcedDeviceName.get());
2397 if (audio->mInputType == MediaSourceEnum::Microphone &&
2398 audioBackend == videoBackend) {
2399 micsOfVideoBackend.emplace();
2400 micsOfVideoBackend->AppendElements(audios);
2401 }
2402 devices->AppendElements(std::move(audios));
2403 }
2404 if (const auto& video = aParams.mVideo; video.isSome()) {
2405 videoBackend = aParams.HasFakeCams() ? fakeBackend : realBackend;
2406 MediaDeviceSet videos;
2407 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)
2408 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)
;
2409 GetMediaDevices(videoBackend, video->mInputType, videos,
2410 video->mForcedDeviceName.get());
2411 devices->AppendElements(std::move(videos));
2412 }
2413 if (aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)) {
2414 MediaDeviceSet outputs;
2415 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"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "realBackend"
")"); do { MOZ_CrashSequence(__null, 2415); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2416 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2417 MediaSinkEnum::Speaker, &outputs);
2418 speakers = Some(MediaDeviceSet());
2419 speakers->AppendElements(outputs);
2420 devices->AppendElements(std::move(outputs));
2421 }
2422 if (aParams.VideoInputType() == MediaSourceEnum::Camera) {
2423 MediaDeviceSet audios;
2424 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)
2425 "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)
2426 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)
;
2427 // We need to correlate cameras with audio groupIds. We use the backend of
2428 // the camera to always do correlation on devices in the same scope. If we
2429 // don't do this, video-only getUserMedia will not apply groupId constraints
2430 // to the same set of groupIds as gets returned by enumerateDevices.
2431 if (micsOfVideoBackend.isSome()) {
2432 // Microphones from the same backend used for the cameras have
2433 // already been enumerated. Avoid doing it again.
2434 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", 2435); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { MOZ_CrashSequence(__null, 2435); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2435 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", 2435); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { MOZ_CrashSequence(__null, 2435); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2436 audios.AppendElements(micsOfVideoBackend.extract());
2437 } else {
2438 GetMediaDevices(videoBackend, MediaSourceEnum::Microphone, audios,
2439 aParams.mVideo->mForcedMicrophoneName.get());
2440 }
2441 if (videoBackend == realBackend) {
2442 // When using the real backend for video, there could also be
2443 // speakers to correlate with. There are no fake speakers.
2444 if (speakers.isSome()) {
2445 // Speakers have already been enumerated. Avoid doing it again.
2446 audios.AppendElements(speakers.extract());
2447 } else {
2448 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2449 MediaSinkEnum::Speaker, &audios);
2450 }
2451 }
2452 GuessVideoDeviceGroupIDs(*devices, audios);
2453 }
2454
2455 return devices;
2456}
2457
2458RefPtr<ConstDeviceSetPromise> MediaManager::GetPhysicalDevices() {
2459 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", 2459); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2459); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2460 if (mPhysicalDevices) {
2461 return ConstDeviceSetPromise::CreateAndResolve(mPhysicalDevices, __func__);
2462 }
2463 if (mPendingDevicesPromises) {
2464 // Enumeration is already in progress.
2465 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2466 }
2467 mPendingDevicesPromises =
2468 new Refcountable<nsTArray<MozPromiseHolder<ConstDeviceSetPromise>>>;
2469 MaybeRequestPermissionAndEnumerateRawDevices(
2470 CreateEnumerationParams(MediaSourceEnum::Camera,
2471 MediaSourceEnum::Microphone,
2472 EnumerationFlag::EnumerateAudioOutputs))
2473 ->Then(
2474 GetCurrentSerialEventTarget(), __func__,
2475 [self = RefPtr(this), this, promises = mPendingDevicesPromises](
2476 RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
2477 for (auto& promiseHolder : *promises) {
2478 promiseHolder.Resolve(aDevices, __func__);
2479 }
2480 // mPendingDevicesPromises may have changed if devices have changed.
2481 if (promises == mPendingDevicesPromises) {
2482 mPendingDevicesPromises = nullptr;
2483 mPhysicalDevices = std::move(aDevices);
2484 }
2485 },
2486 [](RefPtr<MediaMgrError>&& reason) {
2487 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", 2488); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2488); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2488 "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", 2488); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2488); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2489 });
2490
2491 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2492}
2493
2494MediaManager::MediaManager(already_AddRefed<TaskQueue> aMediaThread)
2495 : mMediaThread(aMediaThread), mBackend(nullptr) {
2496 mPrefs.mFreq = 1000; // 1KHz test tone
2497 mPrefs.mWidth = 0; // adaptive default
2498 mPrefs.mHeight = 0; // adaptive default
2499 mPrefs.mResizeModeEnabled = false;
2500 mPrefs.mResizeMode = VideoResizeModeEnum::None;
2501 mPrefs.mFPS = MediaEnginePrefs::DEFAULT_VIDEO_FPS;
2502 mPrefs.mUsePlatformProcessing = false;
2503 mPrefs.mAecOn = false;
2504 mPrefs.mAgcOn = false;
2505 mPrefs.mHPFOn = false;
2506 mPrefs.mNoiseOn = false;
2507 mPrefs.mTransientOn = false;
2508 mPrefs.mAgc2Forced = false;
2509 mPrefs.mExpectDrift = -1; // auto
2510#ifdef MOZ_WEBRTC1
2511 mPrefs.mAgc =
2512 webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
2513 mPrefs.mNoise =
2514 webrtc::AudioProcessing::Config::NoiseSuppression::Level::kModerate;
2515#else
2516 mPrefs.mAgc = 0;
2517 mPrefs.mNoise = 0;
2518#endif
2519 mPrefs.mChannels = 0; // max channels default
2520 nsresult rv;
2521 nsCOMPtr<nsIPrefService> prefs =
2522 do_GetService("@mozilla.org/preferences-service;1", &rv);
2523 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2524 nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
2525 if (branch) {
2526 GetPrefs(branch, nullptr);
2527 }
2528 }
2529}
2530
2531NS_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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 2532
); __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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2532); __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", 2532); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release"
")"); do { MOZ_CrashSequence(__null, 2532); __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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2532); __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", 2532); 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; }
2532 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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 2532
); __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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2532); __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", 2532); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release"
")"); do { MOZ_CrashSequence(__null, 2532); __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"
, 2532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 2532); __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", 2532); 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; }
2533
2534/* static */
2535StaticRefPtr<MediaManager> MediaManager::sSingleton;
2536
2537#ifdef DEBUG1
2538/* static */
2539bool MediaManager::IsInMediaThread() {
2540 return sSingleton && sSingleton->mMediaThread->IsOnCurrentThread();
2541}
2542#endif
2543
2544template <typename Function>
2545static void ForeachObservedPref(const Function& aFunction) {
2546 aFunction("media.navigator.video.default_width"_ns);
2547 aFunction("media.navigator.video.default_height"_ns);
2548 aFunction("media.navigator.video.default_fps"_ns);
2549 aFunction("media.navigator.audio.fake_frequency"_ns);
2550 aFunction("media.audio_loopback_dev"_ns);
2551 aFunction("media.video_loopback_dev"_ns);
2552 aFunction("media.getusermedia.fake-camera-name"_ns);
2553#ifdef MOZ_WEBRTC1
2554 aFunction("media.navigator.video.resize_mode.enabled"_ns);
2555 aFunction("media.navigator.video.default_resize_mode"_ns);
2556 aFunction("media.getusermedia.audio.processing.aec.enabled"_ns);
2557 aFunction("media.getusermedia.audio.processing.aec"_ns);
2558 aFunction("media.getusermedia.audio.processing.agc.enabled"_ns);
2559 aFunction("media.getusermedia.audio.processing.agc"_ns);
2560 aFunction("media.getusermedia.audio.processing.agc2.forced"_ns);
2561 aFunction("media.getusermedia.audio.processing.hpf.enabled"_ns);
2562 aFunction("media.getusermedia.audio.processing.noise.enabled"_ns);
2563 aFunction("media.getusermedia.audio.processing.noise"_ns);
2564 aFunction("media.getusermedia.audio.max_channels"_ns);
2565 aFunction("media.navigator.streams.fake"_ns);
2566#endif
2567}
2568
2569// NOTE: never NS_DispatchAndSpinEventLoopUntilComplete to the MediaManager
2570// thread from the MainThread, as we NS_DispatchAndSpinEventLoopUntilComplete to
2571// MainThread from MediaManager thread.
2572
2573// Guaranteed never to return nullptr.
2574/* static */
2575MediaManager* MediaManager::Get() {
2576 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", 2576); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2576); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2577
2578 if (!sSingleton) {
2579 static int timesCreated = 0;
2580 timesCreated++;
2581 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", 2581); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "timesCreated == 1" ")"); do { MOZ_CrashSequence
(__null, 2581); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2582
2583 RefPtr<TaskQueue> mediaThread =
2584#ifdef MOZ_WEBRTC1
2585 CreateWebrtcTaskQueueWrapper(
2586 GetMediaThreadPool(MediaThreadType::SUPERVISOR), "MediaManager"_ns,
2587 TailDispatchPolicy::NoTailDispatch);
2588#else
2589 TaskQueue::Create(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
2590 "MediaManager", TailDispatchPolicy::NoTailDispatch);
2591#endif
2592 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)
;
2593
2594 sSingleton = new MediaManager(mediaThread.forget());
2595
2596 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2597 if (obs) {
2598 obs->AddObserver(sSingleton, "last-pb-context-exited", false);
2599 obs->AddObserver(sSingleton, "getUserMedia:got-device-permission", false);
2600 obs->AddObserver(sSingleton, "getUserMedia:privileged:allow", false);
2601 obs->AddObserver(sSingleton, "getUserMedia:response:allow", false);
2602 obs->AddObserver(sSingleton, "getUserMedia:response:deny", false);
2603 obs->AddObserver(sSingleton, "getUserMedia:response:noOSPermission",
2604 false);
2605 obs->AddObserver(sSingleton, "getUserMedia:revoke", false);
2606 obs->AddObserver(sSingleton, "getUserMedia:muteVideo", false);
2607 obs->AddObserver(sSingleton, "getUserMedia:unmuteVideo", false);
2608 obs->AddObserver(sSingleton, "getUserMedia:muteAudio", false);
2609 obs->AddObserver(sSingleton, "getUserMedia:unmuteAudio", false);
2610 obs->AddObserver(sSingleton, "application-background", false);
2611 obs->AddObserver(sSingleton, "application-foreground", false);
2612 }
2613 // else MediaManager won't work properly and will leak (see bug 837874)
2614 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
2615 if (prefs) {
2616 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
2617 prefs->AddObserver(aPrefName, sSingleton, false);
2618 });
2619 }
2620 RegisterStrongMemoryReporter(do_AddRef(sSingleton));
2621
2622 // Prepare async shutdown
2623
2624 class Blocker : public media::ShutdownBlocker {
2625 public:
2626 Blocker()
2627 : media::ShutdownBlocker(
2628 u"Media shutdown: blocking on media thread"_ns) {}
2629
2630 NS_IMETHODvirtual nsresult BlockShutdown(nsIAsyncShutdownClient*) override {
2631 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", 2631); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "MediaManager::GetIfExists()" ")");
do { MOZ_CrashSequence(__null, 2631); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2632 MediaManager::GetIfExists()->Shutdown();
2633 return NS_OK;
2634 }
2635 };
2636
2637 sSingleton->mShutdownBlocker = new Blocker();
2638 nsresult rv = media::MustGetShutdownBarrier()->AddBlocker(
2639 sSingleton->mShutdownBlocker, NS_LITERAL_STRING_FROM_CSTRING(__FILE__)static_cast<const nsLiteralString&>( nsLiteralString
(u"" "./../../../dom/media/MediaManager.cpp"))
,
2640 __LINE__2640, u""_ns);
2641 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"
, 2641); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 2641); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2642 }
2643 return sSingleton;
2644}
2645
2646/* static */
2647MediaManager* MediaManager::GetIfExists() {
2648 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", 2648); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread() || IsInMediaThread()" ")"
); do { MOZ_CrashSequence(__null, 2648); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2649 return sSingleton;
2650}
2651
2652/* static */
2653already_AddRefed<MediaManager> MediaManager::GetInstance() {
2654 // so we can have non-refcounted getters
2655 RefPtr<MediaManager> service = MediaManager::Get();
2656 return service.forget();
2657}
2658
2659media::Parent<media::NonE10s>* MediaManager::GetNonE10sParent() {
2660 if (!mNonE10sParent) {
2661 mNonE10sParent = new media::Parent<media::NonE10s>();
2662 }
2663 return mNonE10sParent;
2664}
2665
2666/* static */
2667void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
2668 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", 2668); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2668); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2669 if (sHasMainThreadShutdown) {
2670 // Can't safely delete task here since it may have items with specific
2671 // thread-release requirements.
2672 // XXXkhuey well then who is supposed to delete it?! We don't signal
2673 // that we failed ...
2674 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "./../../../dom/media/MediaManager.cpp"
, 2674); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { MOZ_CrashSequence
(__null, 2674); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
2675 return;
2676 }
2677 NS_ASSERTION(Get(), "MediaManager singleton?")do { if (!(Get())) { NS_DebugBreak(NS_DEBUG_ASSERTION, "MediaManager singleton?"
, "Get()", "./../../../dom/media/MediaManager.cpp", 2677); MOZ_PretendNoReturn
(); } } while (0)
;
2678 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"
, 2678); MOZ_PretendNoReturn(); } } while (0)
;
2679 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", 2679); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(Get()->mMediaThread->Dispatch(std::move(task)))"
")"); do { MOZ_CrashSequence(__null, 2679); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2680}
2681
2682template <typename MozPromiseType, typename FunctionType>
2683/* static */
2684RefPtr<MozPromiseType> MediaManager::Dispatch(StaticString aName,
2685 FunctionType&& aFunction) {
2686 MozPromiseHolder<MozPromiseType> holder;
2687 RefPtr<MozPromiseType> promise = holder.Ensure(aName);
2688 MediaManager::Dispatch(NS_NewRunnableFunction(
2689 aName, [h = std::move(holder), func = std::forward<FunctionType>(
2690 aFunction)]() mutable { func(h); }));
2691 return promise;
2692}
2693
2694/* static */
2695nsresult MediaManager::NotifyRecordingStatusChange(
2696 nsPIDOMWindowInner* aWindow) {
2697 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", 2697); return NS_ERROR_INVALID_ARG
; } } while (false)
;
2698
2699 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2700 if (!obs) {
2701 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 2703)
2702 "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"
, 2703)
2703 "notification.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "./../../../dom/media/MediaManager.cpp"
, 2703)
;
2704 return NS_ERROR_FAILURE;
2705 }
2706
2707 auto props = MakeRefPtr<nsHashPropertyBag>();
2708
2709 nsCString pageURL;
2710 nsCOMPtr<nsIURI> docURI = aWindow->GetDocumentURI();
2711 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", 2711); return NS_ERROR_FAILURE
; } } while (false)
;
2712
2713 nsresult rv = docURI->GetSpec(pageURL);
2714 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"
, 2714); return rv; } } while (false)
;
2715
2716 NS_ConvertUTF8toUTF16 requestURL(pageURL);
2717
2718 props->SetPropertyAsAString(u"requestURL"_ns, requestURL);
2719 props->SetPropertyAsInterface(u"window"_ns, aWindow);
2720
2721 obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
2722 "recording-device-events", nullptr);
2723 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)
;
2724
2725 return NS_OK;
2726}
2727
2728void MediaManager::DeviceListChanged() {
2729 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", 2729); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2729); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2730 if (sHasMainThreadShutdown) {
2731 return;
2732 }
2733 // Invalidate immediately to provide an up-to-date device list for future
2734 // enumerations on platforms with sane device-list-changed events.
2735 InvalidateDeviceCache();
2736
2737 // Wait 200 ms, because
2738 // A) on some Windows machines, if we call EnumerateRawDevices immediately
2739 // after receiving devicechange event, we'd get an outdated devices list.
2740 // B) Waiting helps coalesce multiple calls on us into one, which can happen
2741 // if a device with both audio input and output is attached or removed.
2742 // We want to react & fire a devicechange event only once in that case.
2743
2744 // The wait is extended if another hardware device-list-changed notification
2745 // is received to provide the full 200ms for EnumerateRawDevices().
2746 if (mDeviceChangeTimer) {
2747 mDeviceChangeTimer->Cancel();
2748 } else {
2749 mDeviceChangeTimer = MakeRefPtr<MediaTimer<TimeStamp>>();
2750 }
2751 // However, if this would cause a delay of over 1000ms in handling the
2752 // oldest unhandled event, then respond now and set the timer to run
2753 // EnumerateRawDevices() again in 200ms.
2754 auto now = TimeStamp::NowLoRes();
2755 auto enumerateDelay = TimeDuration::FromMilliseconds(200);
2756 auto coalescenceLimit = TimeDuration::FromMilliseconds(1000) - enumerateDelay;
2757 if (!mUnhandledDeviceChangeTime) {
2758 mUnhandledDeviceChangeTime = now;
2759 } else if (now - mUnhandledDeviceChangeTime > coalescenceLimit) {
2760 HandleDeviceListChanged();
2761 mUnhandledDeviceChangeTime = now;
2762 }
2763 RefPtr<MediaManager> self = this;
2764 mDeviceChangeTimer->WaitFor(enumerateDelay, __func__)
2765 ->Then(
2766 GetCurrentSerialEventTarget(), __func__,
2767 [self, this] {
2768 // Invalidate again for the sake of platforms with inconsistent
2769 // timing between device-list-changed notification and enumeration.
2770 InvalidateDeviceCache();
2771
2772 mUnhandledDeviceChangeTime = TimeStamp();
2773 HandleDeviceListChanged();
2774 },
2775 [] { /* Timer was canceled by us, or we're in shutdown. */ });
2776}
2777
2778void MediaManager::InvalidateDeviceCache() {
2779 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", 2779); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2779); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2780
2781 mPhysicalDevices = nullptr;
2782 // Disconnect any in-progress enumeration, which may now be out of date,
2783 // from updating mPhysicalDevices or resolving future device request
2784 // promises.
2785 mPendingDevicesPromises = nullptr;
2786}
2787
2788void MediaManager::HandleDeviceListChanged() {
2789 mDeviceListChangeEvent.Notify();
2790
2791 GetPhysicalDevices()->Then(
2792 GetCurrentSerialEventTarget(), __func__,
2793 [self = RefPtr(this), this](RefPtr<const MediaDeviceSetRefCnt> aDevices) {
2794 if (!MediaManager::GetIfExists()) {
2795 return;
2796 }
2797
2798 nsTHashSet<nsString> deviceIDs;
2799 for (const auto& device : *aDevices) {
2800 deviceIDs.Insert(device->mRawID);
2801 }
2802 // For any real removed cameras or microphones, notify their
2803 // listeners cleanly that the source has stopped, so JS knows and
2804 // usage indicators update.
2805 // First collect the listeners in an array to stop them after
2806 // iterating the hashtable. The StopRawID() method indirectly
2807 // modifies the mActiveWindows and would assert-crash if the
2808 // iterator were active while the table is being enumerated.
2809 const auto windowListeners = ToArray(mActiveWindows.Values());
2810 for (const RefPtr<GetUserMediaWindowListener>& l : windowListeners) {
2811 const auto activeDevices = l->GetDevices();
2812 for (const RefPtr<LocalMediaDevice>& device : *activeDevices) {
2813 if (device->IsFake()) {
2814 continue;
2815 }
2816 MediaSourceEnum mediaSource = device->GetMediaSource();
2817 if (mediaSource != MediaSourceEnum::Microphone &&
2818 mediaSource != MediaSourceEnum::Camera) {
2819 continue;
2820 }
2821 if (!deviceIDs.Contains(device->RawID())) {
2822 // Device has been removed
2823 l->StopRawID(device->RawID());
2824 }
2825 }
2826 }
2827 },
2828 [](RefPtr<MediaMgrError>&& reason) {
2829 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"
, 2829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "EnumerateRawDevices does not reject"
")"); do { MOZ_CrashSequence(__null, 2829); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2830 });
2831}
2832
2833size_t MediaManager::AddTaskAndGetCount(uint64_t aWindowID,
2834 const nsAString& aCallID,
2835 RefPtr<GetUserMediaTask> aTask) {
2836 // Store the task w/callbacks.
2837 mActiveCallbacks.InsertOrUpdate(aCallID, std::move(aTask));
2838
2839 // Add a WindowID cross-reference so OnNavigation can tear things down
2840 nsTArray<nsString>* const array = mCallIds.GetOrInsertNew(aWindowID);
2841 array->AppendElement(aCallID);
2842
2843 return array->Length();
2844}
2845
2846RefPtr<GetUserMediaTask> MediaManager::TakeGetUserMediaTask(
2847 const nsAString& aCallID) {
2848 RefPtr<GetUserMediaTask> task;
2849 mActiveCallbacks.Remove(aCallID, getter_AddRefs(task));
2850 if (!task) {
2851 return nullptr;
2852 }
2853 nsTArray<nsString>* array;
2854 mCallIds.Get(task->GetWindowID(), &array);
2855 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"
, 2855); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { MOZ_CrashSequence(__null, 2855); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2856 array->RemoveElement(aCallID);
2857 return task;
2858}
2859
2860void MediaManager::NotifyAllowed(const nsString& aCallID,
2861 const LocalMediaDeviceSet& aDevices) {
2862 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2863 nsCOMPtr<nsIMutableArray> devicesCopy = nsArray::Create();
2864 for (const auto& device : aDevices) {
2865 nsresult rv = devicesCopy->AppendElement(device);
2866 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"
, 2866)
) {
2867 obs->NotifyObservers(nullptr, "getUserMedia:response:deny",
2868 aCallID.get());
2869 return;
2870 }
2871 }
2872 obs->NotifyObservers(devicesCopy, "getUserMedia:privileged:allow",
2873 aCallID.get());
2874}
2875
2876nsresult MediaManager::GenerateUUID(nsAString& aResult) {
2877 nsresult rv;
2878 nsCOMPtr<nsIUUIDGenerator> uuidgen =
2879 do_GetService("@mozilla.org/uuid-generator;1", &rv);
2880 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"
, 2880); return rv; } } while (false)
;
2881
2882 // Generate a call ID.
2883 nsID id;
2884 rv = uuidgen->GenerateUUIDInPlace(&id);
2885 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"
, 2885); return rv; } } while (false)
;
2886
2887 char buffer[NSID_LENGTH39];
2888 id.ToProvidedString(buffer);
2889 aResult.Assign(NS_ConvertUTF8toUTF16(buffer));
2890 return NS_OK;
2891}
2892
2893enum class GetUserMediaSecurityState {
2894 Other = 0,
2895 HTTPS = 1,
2896 File = 2,
2897 App = 3,
2898 Localhost = 4,
2899 Loop = 5,
2900 Privileged = 6
2901};
2902
2903/**
2904 * This function is used in getUserMedia when privacy.resistFingerprinting is
2905 * true. Only mediaSource of audio/video constraint will be kept. On mobile
2906 * facing mode is also kept.
2907 */
2908static void ReduceConstraint(
2909 OwningBooleanOrMediaTrackConstraints& aConstraint) {
2910 // Not requesting stream.
2911 if (!MediaManager::IsOn(aConstraint)) {
2912 return;
2913 }
2914
2915 // It looks like {audio: true}, do nothing.
2916 if (!aConstraint.IsMediaTrackConstraints()) {
2917 return;
2918 }
2919
2920 // Keep mediaSource.
2921 Maybe<nsString> mediaSource;
2922 if (aConstraint.GetAsMediaTrackConstraints().mMediaSource.WasPassed()) {
2923 mediaSource =
2924 Some(aConstraint.GetAsMediaTrackConstraints().mMediaSource.Value());
2925 }
2926
2927 Maybe<OwningStringOrStringSequenceOrConstrainDOMStringParameters> facingMode;
2928 if (aConstraint.GetAsMediaTrackConstraints().mFacingMode.WasPassed()) {
2929 facingMode =
2930 Some(aConstraint.GetAsMediaTrackConstraints().mFacingMode.Value());
2931 }
2932
2933 aConstraint.Uninit();
2934 if (mediaSource) {
2935 aConstraint.SetAsMediaTrackConstraints().mMediaSource.Construct(
2936 *mediaSource);
2937 } else {
2938 (void)aConstraint.SetAsMediaTrackConstraints();
2939 }
2940
2941#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_UIKIT)
2942 if (facingMode) {
2943 aConstraint.SetAsMediaTrackConstraints().mFacingMode.Construct(*facingMode);
2944 } else {
2945 (void)aConstraint.SetAsMediaTrackConstraints();
2946 }
2947#endif
2948}
2949
2950/**
2951 * The entry point for this file. A call from MediaDevices::GetUserMedia
2952 * will end up here. MediaManager is a singleton that is responsible
2953 * for handling all incoming getUserMedia calls from every window.
2954 */
2955RefPtr<MediaManager::StreamPromise> MediaManager::GetUserMedia(
2956 nsPIDOMWindowInner* aWindow,
2957 const MediaStreamConstraints& aConstraintsPassedIn,
2958 CallerType aCallerType) {
2959 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", 2959); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 2959); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
2960 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"
, 2960); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindow" ")"
); do { MOZ_CrashSequence(__null, 2960); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2961 uint64_t windowID = aWindow->WindowID();
2962
2963 MediaStreamConstraints c(aConstraintsPassedIn); // use a modifiable copy
2964
2965 if (sHasMainThreadShutdown) {
2966 return StreamPromise::CreateAndReject(
2967 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError,
2968 "In shutdown"),
2969 __func__);
2970 }
2971
2972 // Determine permissions early (while we still have a stack).
2973
2974 nsIURI* docURI = aWindow->GetDocumentURI();
2975 if (!docURI) {
2976 return StreamPromise::CreateAndReject(
2977 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError), __func__);
2978 }
2979 bool isChrome = (aCallerType == CallerType::System);
2980 bool privileged =
2981 isChrome ||
2982 Preferences::GetBool("media.navigator.permission.disabled", false);
2983 bool isSecure = aWindow->IsSecureContext();
2984 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
2985 nsCString host;
2986 nsresult rv = docURI->GetHost(host);
Value stored to 'rv' during its initialization is never read
2987
2988 nsCOMPtr<nsIPrincipal> principal =
2989 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
2990 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "./../../../dom/media/MediaManager.cpp"
, 2990)
) {
2991 return StreamPromise::CreateAndReject(
2992 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2993 __func__);
2994 }
2995
2996 Document* doc = aWindow->GetExtantDoc();
2997 if (NS_WARN_IF(!doc)NS_warn_if_impl(!doc, "!doc", "./../../../dom/media/MediaManager.cpp"
, 2997)
) {
2998 return StreamPromise::CreateAndReject(
2999 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3000 __func__);
3001 }
3002
3003 // Disallow access to null principal pages and http pages (unless pref)
3004 if (principal->GetIsNullPrincipal() ||
3005 !(isSecure || StaticPrefs::media_getusermedia_insecure_enabled())) {
3006 return StreamPromise::CreateAndReject(
3007 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3008 __func__);
3009 }
3010
3011 // This principal needs to be sent to different threads and so via IPC.
3012 // For this reason it's better to convert it to PrincipalInfo right now.
3013 ipc::PrincipalInfo principalInfo;
3014 rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3015 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"
, 3015)
) {
3016 return StreamPromise::CreateAndReject(
3017 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3018 __func__);
3019 }
3020
3021 const bool resistFingerprinting =
3022 !isChrome && doc->ShouldResistFingerprinting(RFPTarget::MediaDevices);
3023 if (resistFingerprinting) {
3024 ReduceConstraint(c.mVideo);
3025 ReduceConstraint(c.mAudio);
3026 }
3027
3028 if (!Preferences::GetBool("media.navigator.video.enabled", true)) {
3029 c.mVideo.SetAsBoolean() = false;
3030 }
3031
3032 MediaSourceEnum videoType = MediaSourceEnum::Other; // none
3033 MediaSourceEnum audioType = MediaSourceEnum::Other; // none
3034
3035 if (c.mVideo.IsMediaTrackConstraints()) {
3036 auto& vc = c.mVideo.GetAsMediaTrackConstraints();
3037 if (!vc.mMediaSource.WasPassed()) {
3038 vc.mMediaSource.Construct().AssignASCII(
3039 dom::GetEnumString(MediaSourceEnum::Camera));
3040 }
3041 videoType = dom::StringToEnum<MediaSourceEnum>(vc.mMediaSource.Value())
3042 .valueOr(MediaSourceEnum::Other);
3043 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3044 (uint32_t)videoType);
3045 switch (videoType) {
3046 case MediaSourceEnum::Camera:
3047 break;
3048
3049 case MediaSourceEnum::Browser:
3050 // If no window id is passed in then default to the caller's window.
3051 // Functional defaults are helpful in tests, but also a natural outcome
3052 // of the constraints API's limited semantics for requiring input.
3053 if (!vc.mBrowserWindow.WasPassed()) {
3054 nsPIDOMWindowOuter* outer = aWindow->GetOuterWindow();
3055 vc.mBrowserWindow.Construct(outer->WindowID());
3056 }
3057 // Allow tab capture requests from chrome context if device id is
3058 // specified, since no prompt is needed.
3059 if (isChrome && videoType == MediaSourceEnum::Browser &&
3060 c.mVideo.IsMediaTrackConstraints() &&
3061 c.mVideo.GetAsMediaTrackConstraints().mDeviceId.WasPassed()) {
3062 break;
3063 }
3064 [[fallthrough]];
3065 case MediaSourceEnum::Screen:
3066 case MediaSourceEnum::Window:
3067 // Deny screensharing request if support is disabled, or
3068 // the requesting document is not from a host on the whitelist.
3069 if (!Preferences::GetBool(
3070 ((videoType == MediaSourceEnum::Browser)
3071 ? "media.getusermedia.browser.enabled"
3072 : "media.getusermedia.screensharing.enabled"),
3073 false) ||
3074 (!privileged && !aWindow->IsSecureContext())) {
3075 return StreamPromise::CreateAndReject(
3076 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3077 __func__);
3078 }
3079 break;
3080
3081 case MediaSourceEnum::Microphone:
3082 case MediaSourceEnum::Other:
3083 default: {
3084 return StreamPromise::CreateAndReject(
3085 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
3086 "", u"mediaSource"_ns),
3087 __func__);
3088 }
3089 }
3090
3091 if (!privileged) {
3092 // Only allow privileged content to explicitly pick full-screen,
3093 // application or tabsharing, since these modes are still available for
3094 // testing. All others get "Window" (*) sharing.
3095 //
3096 // *) We overload "Window" with the new default getDisplayMedia spec-
3097 // mandated behavior of not influencing user-choice, which we currently
3098 // implement as a list containing BOTH windows AND screen(s).
3099 //
3100 // Notes on why we chose "Window" as the one to overload. Two reasons:
3101 //
3102 // 1. It's the closest logically & behaviorally (multi-choice, no default)
3103 // 2. Screen is still useful in tests (implicit default is entire screen)
3104 //
3105 // For UX reasons we don't want "Entire Screen" to be the first/default
3106 // choice (in our code first=default). It's a "scary" source that comes
3107 // with complicated warnings on-top that would be confusing as the first
3108 // thing people see, and also deserves to be listed as last resort for
3109 // privacy reasons.
3110
3111 if (videoType == MediaSourceEnum::Screen ||
3112 videoType == MediaSourceEnum::Browser) {
3113 videoType = MediaSourceEnum::Window;
3114 vc.mMediaSource.Value().AssignASCII(dom::GetEnumString(videoType));
3115 }
3116 // only allow privileged content to set the window id
3117 if (vc.mBrowserWindow.WasPassed()) {
3118 vc.mBrowserWindow.Value() = -1;
3119 }
3120 if (vc.mAdvanced.WasPassed()) {
3121 for (MediaTrackConstraintSet& cs : vc.mAdvanced.Value()) {
3122 if (cs.mBrowserWindow.WasPassed()) {
3123 cs.mBrowserWindow.Value() = -1;
3124 }
3125 }
3126 }
3127 }
3128 } else if (IsOn(c.mVideo)) {
3129 videoType = MediaSourceEnum::Camera;
3130 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3131 (uint32_t)videoType);
3132 }
3133
3134 if (c.mAudio.IsMediaTrackConstraints()) {
3135 auto& ac = c.mAudio.GetAsMediaTrackConstraints();
3136 if (!ac.mMediaSource.WasPassed()) {
3137 ac.mMediaSource.Construct(NS_ConvertASCIItoUTF16(
3138 dom::GetEnumString(MediaSourceEnum::Microphone)));
3139 }
3140 audioType = dom::StringToEnum<MediaSourceEnum>(ac.mMediaSource.Value())
3141 .valueOr(MediaSourceEnum::Other);
3142 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3143 (uint32_t)audioType);
3144
3145 switch (audioType) {
3146 case MediaSourceEnum::Microphone:
3147 break;
3148
3149 case MediaSourceEnum::AudioCapture:
3150 // Only enable AudioCapture if the pref is enabled. If it's not, we can
3151 // deny right away.
3152 if (!Preferences::GetBool("media.getusermedia.audio.capture.enabled")) {
3153 return StreamPromise::CreateAndReject(
3154 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3155 __func__);
3156 }
3157 break;
3158
3159 case MediaSourceEnum::Other:
3160 default: {
3161 return StreamPromise::CreateAndReject(
3162 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
3163 "", u"mediaSource"_ns),
3164 __func__);
3165 }
3166 }
3167 } else if (IsOn(c.mAudio)) {
3168 audioType = MediaSourceEnum::Microphone;
3169 glean::webrtc::get_user_media_type.AccumulateSingleSample(
3170 (uint32_t)audioType);
3171 }
3172
3173 // Create a window listener if it doesn't already exist.
3174 RefPtr<GetUserMediaWindowListener> windowListener =
3175 GetOrMakeWindowListener(aWindow);
3176 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", 3176); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener" ")"); do { MOZ_CrashSequence
(__null, 3176); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3177 // Create an inactive DeviceListener to act as a placeholder, so the
3178 // window listener doesn't clean itself up until we're done.
3179 auto placeholderListener = MakeRefPtr<DeviceListener>();
3180 windowListener->Register(placeholderListener);
3181
3182 { // Check Permissions Policy. Reject if a requested feature is disabled.
3183 bool disabled = !IsOn(c.mAudio) && !IsOn(c.mVideo);
3184 if (IsOn(c.mAudio)) {
3185 if (audioType == MediaSourceEnum::Microphone) {
3186 if (Preferences::GetBool("media.getusermedia.microphone.deny", false) ||
3187 !PermissionsPolicyUtils::IsFeatureAllowed(doc, u"microphone"_ns)) {
3188 disabled = true;
3189 }
3190 } else if (!PermissionsPolicyUtils::IsFeatureAllowed(
3191 doc, u"display-capture"_ns)) {
3192 disabled = true;
3193 }
3194 }
3195 if (IsOn(c.mVideo)) {
3196 if (videoType == MediaSourceEnum::Camera) {
3197 if (Preferences::GetBool("media.getusermedia.camera.deny", false) ||
3198 !PermissionsPolicyUtils::IsFeatureAllowed(doc, u"camera"_ns)) {
3199 disabled = true;
3200 }
3201 } else if (!PermissionsPolicyUtils::IsFeatureAllowed(
3202 doc, u"display-capture"_ns)) {
3203 disabled = true;
3204 }
3205 }
3206
3207 if (disabled) {
3208 placeholderListener->Stop();
3209 return StreamPromise::CreateAndReject(
3210 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3211 __func__);
3212 }
3213 }
3214
3215 // Get list of all devices, with origin-specific device ids.
3216
3217 MediaEnginePrefs prefs = mPrefs;
3218
3219 nsString callID;
3220 rv = GenerateUUID(callID);
3221 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"
, 3221); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 3221); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3222
3223 bool hasVideo = videoType != MediaSourceEnum::Other;
3224 bool hasAudio = audioType != MediaSourceEnum::Other;
3225
3226 // Handle fake requests from content. For gUM we don't consider resist
3227 // fingerprinting as users should be prompted anyway.
3228 bool forceFakes = c.mFake.WasPassed() && c.mFake.Value();
3229 // fake:true is effective only for microphone and camera devices, so
3230 // permission must be requested for screen capture even if fake:true is set.
3231 bool hasOnlyForcedFakes =
3232 forceFakes && (!hasVideo || videoType == MediaSourceEnum::Camera) &&
3233 (!hasAudio || audioType == MediaSourceEnum::Microphone);
3234 bool askPermission =
3235 (!privileged ||
3236 Preferences::GetBool("media.navigator.permission.force")) &&
3237 (!hasOnlyForcedFakes ||
3238 Preferences::GetBool("media.navigator.permission.fake"));
3239
3240 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)
3241 "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)
3242 __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)
3243 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)
3244 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)
;
3245
3246 EnumerationFlags flags = EnumerationFlag::AllowPermissionRequest;
3247 if (forceFakes) {
3248 flags += EnumerationFlag::ForceFakes;
3249 }
3250 if (privileged && videoType == MediaSourceEnum::Browser &&
3251 c.mVideo.IsMediaTrackConstraints() &&
3252 c.mVideo.GetAsMediaTrackConstraints().mDeviceId.WasPassed()) {
3253 // Bug 2041678: For automation purposes when calling getUserMedia
3254 // in privileged context to record a browser window, since we avoid
3255 // the interface to choose the device and just provide it directly,
3256 // we have to invalidate the device cache.
3257 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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3258 __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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3259 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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3260 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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3261 }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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3262 })))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", 3262); AnnotateMozCrashReason
("MOZ_CRASH(" "NS_SUCCEEDED(mMediaThread->Dispatch(NS_NewRunnableFunction( __func__, [self = RefPtr(this), this, videoType] { if (mBackend) { mBackend->InvalidateDesktopCaptureDeviceCache(videoType); } })))"
")"); do { MOZ_CrashSequence(__null, 3262); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3263 }
3264 RefPtr<MediaManager> self = this;
3265 return EnumerateDevicesImpl(
3266 aWindow, CreateEnumerationParams(videoType, audioType, flags))
3267 ->Then(
3268 GetCurrentSerialEventTarget(), __func__,
3269 [self, windowID, c, windowListener,
3270 aCallerType](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) {
3271 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)
3272 "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)
;
3273 // Ensure that our windowID is still good.
3274 RefPtr<nsPIDOMWindowInner> window =
3275 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3276 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3277 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)
3278 "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)
3279 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)
;
3280 return LocalDeviceSetPromise::CreateAndReject(
3281 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3282 __func__);
3283 }
3284 // Apply any constraints. This modifies the passed-in list.
3285 return self->SelectSettings(c, aCallerType, std::move(aDevices));
3286 },
3287 [](RefPtr<MediaMgrError>&& aError) {
3288 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)
3289 "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)
;
3290 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3291 __func__);
3292 })
3293 ->Then(
3294 GetCurrentSerialEventTarget(), __func__,
3295 [self, windowID, c, windowListener, placeholderListener, hasAudio,
3296 hasVideo, askPermission, prefs, isSecure, isHandlingUserInput,
3297 callID, principalInfo, aCallerType, resistFingerprinting, audioType,
3298 forceFakes](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3299 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)
3300 "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)
;
3301
3302 // Ensure that the window is still good.
3303 RefPtr<nsPIDOMWindowInner> window =
3304 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3305 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3306 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)
3307 "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)
3308 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)
;
3309 placeholderListener->Stop();
3310 return StreamPromise::CreateAndReject(
3311 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3312 __func__);
3313 }
3314 if (!aDevices->Length()) {
3315 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)
3316 "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)
;
3317 placeholderListener->Stop();
3318 // When privacy.resistFingerprinting = true, no
3319 // available device implies content script is requesting
3320 // a fake device, so report NotAllowedError.
3321 auto error = resistFingerprinting
3322 ? MediaMgrError::Name::NotAllowedError
3323 : MediaMgrError::Name::NotFoundError;
3324 return StreamPromise::CreateAndReject(
3325 MakeRefPtr<MediaMgrError>(error), __func__);
3326 }
3327
3328 // Time to start devices. Create the necessary device listeners and
3329 // remove the placeholder.
3330 RefPtr<DeviceListener> audioListener;
3331 RefPtr<DeviceListener> videoListener;
3332 if (hasAudio) {
3333 audioListener = MakeRefPtr<DeviceListener>();
3334 windowListener->Register(audioListener);
3335 }
3336 if (hasVideo) {
3337 videoListener = MakeRefPtr<DeviceListener>();
3338 windowListener->Register(videoListener);
3339 }
3340 placeholderListener->Stop();
3341
3342 bool focusSource = mozilla::Preferences::GetBool(
3343 "media.getusermedia.window.focus_source.enabled", true);
3344
3345 // Incremental hack to compile. To be replaced by deeper
3346 // refactoring. MediaManager allows
3347 // "neither-resolve-nor-reject" semantics, so we cannot
3348 // use MozPromiseHolder here.
3349 MozPromiseHolder<StreamPromise> holder;
3350 RefPtr<StreamPromise> p = holder.Ensure(__func__);
3351
3352 // Pass callbacks and listeners along to GetUserMediaStreamTask.
3353 auto task = MakeRefPtr<GetUserMediaStreamTask>(
3354 c, std::move(holder), windowID, std::move(windowListener),
3355 std::move(audioListener), std::move(videoListener), prefs,
3356 principalInfo, aCallerType, focusSource);
3357
3358 // It is time to ask for user permission, prime voice processing
3359 // now. Use a local lambda to enable a guard pattern.
3360 [&] {
3361 if (forceFakes) {
3362 return;
3363 }
3364
3365 if (audioType != MediaSourceEnum::Microphone) {
3366 return;
3367 }
3368
3369 if (!StaticPrefs::
3370 media_getusermedia_microphone_voice_stream_priming_enabled() ||
3371 !StaticPrefs::
3372 media_getusermedia_microphone_prefer_voice_stream_with_processing_enabled()) {
3373 return;
3374 }
3375
3376 if (const auto fc = FlattenedConstraints(
3377 NormalizedConstraints(GetInvariant(c.mAudio)));
3378 !fc.mEchoCancellation.Get(prefs.mAecOn) &&
3379 !fc.mAutoGainControl.Get(prefs.mAgcOn && prefs.mAecOn) &&
3380 !fc.mNoiseSuppression.Get(prefs.mNoiseOn && prefs.mAecOn)) {
3381 return;
3382 }
3383
3384 if (GetPersistentPermissions(windowID)
3385 .map([](auto&& aState) {
3386 return aState.mMicrophonePermission ==
3387 PersistentPermissionState::Deny;
3388 })
3389 .unwrapOr(true)) {
3390 return;
3391 }
3392
3393 task->PrimeVoiceProcessing();
3394 }();
3395
3396 size_t taskCount =
3397 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3398
3399 if (!askPermission) {
3400 self->NotifyAllowed(callID, *aDevices);
3401 } else {
3402 auto req = MakeRefPtr<GetUserMediaRequest>(
3403 window, callID, std::move(aDevices), c, isSecure,
3404 isHandlingUserInput);
3405 if (!Preferences::GetBool("media.navigator.permission.force") &&
3406 taskCount > 1) {
3407 // there is at least 1 pending gUM request
3408 // For the scarySources test case, always send the
3409 // request
3410 self->mPendingGUMRequest.AppendElement(req.forget());
3411 } else {
3412 nsCOMPtr<nsIObserverService> obs =
3413 services::GetObserverService();
3414 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3415 }
3416 }
3417#ifdef MOZ_WEBRTC1
3418 self->mLogHandle = EnsureWebrtcLogging();
3419#endif
3420 return p;
3421 },
3422 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3423 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)
3424 "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)
;
3425 placeholderListener->Stop();
3426 return StreamPromise::CreateAndReject(std::move(aError), __func__);
3427 });
3428};
3429
3430RefPtr<LocalDeviceSetPromise> MediaManager::AnonymizeDevices(
3431 nsPIDOMWindowInner* aWindow, RefPtr<const MediaDeviceSetRefCnt> aDevices) {
3432 // Get an origin-key (for either regular or private browsing).
3433 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", 3433); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3433); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3434 uint64_t windowId = aWindow->WindowID();
3435 nsCOMPtr<nsIPrincipal> principal =
3436 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3437 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"
, 3437); AnnotateMozCrashReason("MOZ_ASSERT" "(" "principal" ")"
); do { MOZ_CrashSequence(__null, 3437); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3438 ipc::PrincipalInfo principalInfo;
3439 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3440 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"
, 3440)
) {
3441 return LocalDeviceSetPromise::CreateAndReject(
3442 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3443 __func__);
3444 }
3445 bool resistFingerprinting =
3446 aWindow->AsGlobal()->ShouldResistFingerprinting(RFPTarget::MediaDevices);
3447 bool persist =
3448 IsActivelyCapturingOrHasAPermission(windowId) && !resistFingerprinting;
3449 return media::GetPrincipalKey(principalInfo, persist)
3450 ->Then(
3451 GetMainThreadSerialEventTarget(), __func__,
3452 [rawDevices = std::move(aDevices), windowId,
3453 resistFingerprinting](const nsCString& aOriginKey) {
3454 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", 3454); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!aOriginKey.IsEmpty()" ")"); do { MOZ_CrashSequence
(__null, 3454); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3455 RefPtr anonymized = new LocalMediaDeviceSetRefCnt();
3456 for (const RefPtr<MediaDevice>& device : *rawDevices) {
3457 nsString name = device->mRawName;
3458 if (name.Find(u"AirPods"_ns) != -1) {
3459 name = u"AirPods"_ns;
3460 }
3461
3462 nsString id = device->mRawID;
3463 if (resistFingerprinting) {
3464 nsRFPService::GetMediaDeviceName(name, device->mKind);
3465 id = name;
3466 id.AppendInt(windowId);
3467 }
3468 // An empty id represents a virtual default device, for which
3469 // the exposed deviceId is the empty string.
3470 if (!id.IsEmpty()) {
3471 nsContentUtils::AnonymizeId(id, aOriginKey);
3472 }
3473
3474 nsString groupId = device->mRawGroupID;
3475 if (resistFingerprinting) {
3476 nsRFPService::GetMediaDeviceGroup(groupId, device->mKind);
3477 }
3478 // Use window id to salt group id in order to make it session
3479 // based as required by the spec. This does not provide unique
3480 // group ids through out a browser restart. However, this is not
3481 // against the spec. Furthermore, since device ids are the same
3482 // after a browser restart the fingerprint is not bigger.
3483 groupId.AppendInt(windowId);
3484 nsContentUtils::AnonymizeId(groupId, aOriginKey);
3485 anonymized->EmplaceBack(
3486 new LocalMediaDevice(device, id, groupId, name));
3487 }
3488 return LocalDeviceSetPromise::CreateAndResolve(anonymized,
3489 __func__);
3490 },
3491 [](nsresult rs) {
3492 NS_WARNING("AnonymizeDevices failed to get Principal Key")NS_DebugBreak(NS_DEBUG_WARNING, "AnonymizeDevices failed to get Principal Key"
, nullptr, "./../../../dom/media/MediaManager.cpp", 3492)
;
3493 return LocalDeviceSetPromise::CreateAndReject(
3494 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3495 __func__);
3496 });
3497}
3498
3499RefPtr<LocalDeviceSetPromise> MediaManager::EnumerateDevicesImpl(
3500 nsPIDOMWindowInner* aWindow, EnumerationParams aParams) {
3501 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", 3501); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3501); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3502
3503 uint64_t windowId = aWindow->WindowID();
3504 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)
3505 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)
3506 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)
;
3507
3508 // To get a device list anonymized for a particular origin, we must:
3509 // 1. Get the raw devices list
3510 // 2. Anonymize the raw list with an origin-key.
3511
3512 // Add the window id here to check for that and abort silently if no longer
3513 // exists.
3514 RefPtr<GetUserMediaWindowListener> windowListener =
3515 GetOrMakeWindowListener(aWindow);
3516 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", 3516); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "windowListener" ")"); do { MOZ_CrashSequence
(__null, 3516); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3517 // Create an inactive DeviceListener to act as a placeholder, so the
3518 // window listener doesn't clean itself up until we're done.
3519 auto placeholderListener = MakeRefPtr<DeviceListener>();
3520 windowListener->Register(placeholderListener);
3521
3522 return MaybeRequestPermissionAndEnumerateRawDevices(std::move(aParams))
3523 ->Then(
3524 GetMainThreadSerialEventTarget(), __func__,
3525 [self = RefPtr(this), this, window = nsCOMPtr(aWindow),
3526 placeholderListener](RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
3527 // Only run if window is still on our active list.
3528 MediaManager* mgr = MediaManager::GetIfExists();
3529 if (!mgr || placeholderListener->Stopped()) {
3530 // The listener has already been removed if the window is no
3531 // longer active.
3532 return LocalDeviceSetPromise::CreateAndReject(
3533 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3534 __func__);
3535 }
3536 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", 3536); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mgr->IsWindowStillActive(window->WindowID())"
")"); do { MOZ_CrashSequence(__null, 3536); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3537 placeholderListener->Stop();
3538 return AnonymizeDevices(window, aDevices);
3539 },
3540 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3541 // EnumerateDevicesImpl may fail if a new doc has been set, in which
3542 // case the OnNavigation() method should have removed all previous
3543 // active listeners, or if a platform device access request was not
3544 // granted.
3545 placeholderListener->Stop();
3546 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3547 __func__);
3548 });
3549}
3550
3551RefPtr<LocalDevicePromise> MediaManager::SelectAudioOutput(
3552 nsPIDOMWindowInner* aWindow, const dom::AudioOutputOptions& aOptions,
3553 CallerType aCallerType) {
3554 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
3555 nsCOMPtr<nsIPrincipal> principal =
3556 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3557 if (!PermissionsPolicyUtils::IsFeatureAllowed(aWindow->GetExtantDoc(),
3558 u"speaker-selection"_ns)) {
3559 return LocalDevicePromise::CreateAndReject(
3560 MakeRefPtr<MediaMgrError>(
3561 MediaMgrError::Name::NotAllowedError,
3562 "Document's Permissions Policy does not allow selectAudioOutput()"),
3563 __func__);
3564 }
3565 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "./../../../dom/media/MediaManager.cpp"
, 3565)
) {
3566 return LocalDevicePromise::CreateAndReject(
3567 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3568 __func__);
3569 }
3570 // Disallow access to null principal.
3571 if (principal->GetIsNullPrincipal()) {
3572 return LocalDevicePromise::CreateAndReject(
3573 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3574 __func__);
3575 }
3576 ipc::PrincipalInfo principalInfo;
3577 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3578 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"
, 3578)
) {
3579 return LocalDevicePromise::CreateAndReject(
3580 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3581 __func__);
3582 }
3583 uint64_t windowID = aWindow->WindowID();
3584 const bool resistFingerprinting =
3585 aWindow->AsGlobal()->ShouldResistFingerprinting(aCallerType,
3586 RFPTarget::MediaDevices);
3587 return EnumerateDevicesImpl(
3588 aWindow, CreateEnumerationParams(
3589 MediaSourceEnum::Other, MediaSourceEnum::Other,
3590 {EnumerationFlag::EnumerateAudioOutputs,
3591 EnumerationFlag::AllowPermissionRequest}))
3592 ->Then(
3593 GetCurrentSerialEventTarget(), __func__,
3594 [self = RefPtr<MediaManager>(this), windowID, aOptions, aCallerType,
3595 resistFingerprinting, isHandlingUserInput,
3596 principalInfo](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3597 // Ensure that the window is still good.
3598 RefPtr<nsPIDOMWindowInner> window =
3599 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3600 if (!window) {
3601 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)
3602 "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)
3603 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)
;
3604 return LocalDevicePromise::CreateAndReject(
3605 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3606 __func__);
3607 }
3608 if (aDevices->IsEmpty()) {
3609 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)
;
3610 auto error = resistFingerprinting
3611 ? MediaMgrError::Name::NotAllowedError
3612 : MediaMgrError::Name::NotFoundError;
3613 return LocalDevicePromise::CreateAndReject(
3614 MakeRefPtr<MediaMgrError>(error), __func__);
3615 }
3616 MozPromiseHolder<LocalDevicePromise> holder;
3617 RefPtr<LocalDevicePromise> p = holder.Ensure(__func__);
3618 auto task = MakeRefPtr<SelectAudioOutputTask>(
3619 std::move(holder), windowID, aCallerType, principalInfo);
3620 nsString callID;
3621 nsresult rv = GenerateUUID(callID);
3622 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"
, 3622); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 3622); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3623 size_t taskCount =
3624 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3625 bool askPermission =
3626 !Preferences::GetBool("media.navigator.permission.disabled") ||
3627 Preferences::GetBool("media.navigator.permission.force");
3628 if (!askPermission) {
3629 self->NotifyAllowed(callID, *aDevices);
3630 } else {
3631 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"
, 3631); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window->IsSecureContext()"
")"); do { MOZ_CrashSequence(__null, 3631); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3632 auto req = MakeRefPtr<GetUserMediaRequest>(
3633 window, callID, std::move(aDevices), aOptions, true,
3634 isHandlingUserInput);
3635 if (taskCount > 1) {
3636 // there is at least 1 pending gUM request
3637 self->mPendingGUMRequest.AppendElement(req.forget());
3638 } else {
3639 nsCOMPtr<nsIObserverService> obs =
3640 services::GetObserverService();
3641 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3642 }
3643 }
3644 return p;
3645 },
3646 [](RefPtr<MediaMgrError> aError) {
3647 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)
3648 "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)
;
3649 return LocalDevicePromise::CreateAndReject(std::move(aError),
3650 __func__);
3651 });
3652}
3653
3654MediaEngine* MediaManager::GetBackend() {
3655 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"
, 3655); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3655); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3656 // Plugin backends as appropriate. The default engine also currently
3657 // includes picture support for Android.
3658 // This IS called off main-thread.
3659 if (!mBackend) {
3660#if defined(MOZ_WEBRTC1)
3661 mBackend = new MediaEngineWebRTC();
3662#else
3663 mBackend = new MediaEngineFake();
3664#endif
3665 mDeviceListChangeListener = mBackend->DeviceListChangeEvent().Connect(
3666 AbstractThread::MainThread(), this, &MediaManager::DeviceListChanged);
3667 }
3668 return mBackend;
3669}
3670
3671void MediaManager::OnNavigation(uint64_t aWindowID) {
3672 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", 3672); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3672); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3673 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)
;
3674
3675 // Stop the streams for this window. The runnables check this value before
3676 // making a call to content.
3677
3678 nsTArray<nsString>* callIDs;
3679 if (mCallIds.Get(aWindowID, &callIDs)) {
3680 for (auto& callID : *callIDs) {
3681 mActiveCallbacks.Remove(callID);
3682 for (auto& request : mPendingGUMRequest.Clone()) {
3683 nsString id;
3684 request->GetCallID(id);
3685 if (id == callID) {
3686 mPendingGUMRequest.RemoveElement(request);
3687 }
3688 }
3689 }
3690 mCallIds.Remove(aWindowID);
3691 }
3692
3693 if (RefPtr<GetUserMediaWindowListener> listener =
3694 GetWindowListener(aWindowID)) {
3695 listener->RemoveAll();
3696 }
3697 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"
, 3697); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowListener(aWindowID)"
")"); do { MOZ_CrashSequence(__null, 3697); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3698}
3699
3700void MediaManager::OnCameraMute(bool aMute) {
3701 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", 3701); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3701); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3702 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)
;
3703 mCamerasMuted = aMute;
3704 // This is safe since we're on main-thread, and the windowlist can only
3705 // be added to from the main-thread
3706 for (const auto& window :
3707 ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>(
3708 mActiveWindows.Values())) {
3709 window->MuteOrUnmuteCameras(aMute);
3710 }
3711}
3712
3713void MediaManager::OnMicrophoneMute(bool aMute) {
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 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)
;
3716 mMicrophonesMuted = aMute;
3717 // This is safe since we're on main-thread, and the windowlist can only
3718 // be added to from the main-thread
3719 for (const auto& window :
3720 ToTArray<AutoTArray<RefPtr<GetUserMediaWindowListener>, 2>>(
3721 mActiveWindows.Values())) {
3722 window->MuteOrUnmuteMicrophones(aMute);
3723 }
3724}
3725
3726RefPtr<GetUserMediaWindowListener> MediaManager::GetOrMakeWindowListener(
3727 nsPIDOMWindowInner* aWindow) {
3728 Document* doc = aWindow->GetExtantDoc();
3729 if (!doc) {
3730 // The window has been destroyed. Destroyed windows don't have listeners.
3731 return nullptr;
3732 }
3733 nsIPrincipal* principal = doc->NodePrincipal();
3734 uint64_t windowId = aWindow->WindowID();
3735 RefPtr<GetUserMediaWindowListener> windowListener =
3736 GetWindowListener(windowId);
3737 if (windowListener) {
3738 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", 3739); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { MOZ_CrashSequence(__null, 3739); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3739 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", 3739); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { MOZ_CrashSequence(__null, 3739); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3740 } else {
3741 windowListener = new GetUserMediaWindowListener(
3742 windowId, MakePrincipalHandle(principal));
3743 AddWindowID(windowId, windowListener);
3744 }
3745 return windowListener;
3746}
3747
3748void MediaManager::AddWindowID(uint64_t aWindowId,
3749 RefPtr<GetUserMediaWindowListener> aListener) {
3750 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", 3750); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3750); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3751 // Store the WindowID in a hash table and mark as active. The entry is removed
3752 // when this window is closed or navigated away from.
3753 // This is safe since we're on main-thread, and the windowlist can only
3754 // be invalidated from the main-thread (see OnNavigation)
3755 if (IsWindowStillActive(aWindowId)) {
3756 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", 3756); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "false" ") (" "Window already added" ")"); do
{ MOZ_CrashSequence(__null, 3756); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
3757 return;
3758 }
3759
3760 aListener->MuteOrUnmuteCameras(mCamerasMuted);
3761 aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted);
3762 GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener));
3763
3764 RefPtr<WindowGlobalChild> wgc =
3765 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3766 if (wgc) {
3767 wgc->BlockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3768 }
3769}
3770
3771void MediaManager::RemoveWindowID(uint64_t aWindowId) {
3772 RefPtr<WindowGlobalChild> wgc =
3773 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3774 if (wgc) {
3775 wgc->UnblockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3776 }
3777
3778 mActiveWindows.Remove(aWindowId);
3779
3780 // get outer windowID
3781 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
3782 if (!window) {
3783 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)
;
3784 return;
3785 }
3786
3787 auto* outer = window->GetOuterWindow();
3788 if (!outer) {
3789 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)
;
3790 return;
3791 }
3792
3793 uint64_t outerID = outer->WindowID();
3794
3795 // Notify the UI that this window no longer has gUM active
3796 char windowBuffer[32];
3797 SprintfLiteral(windowBuffer, "%" PRIu64"l" "u", outerID);
3798 nsString data = NS_ConvertUTF8toUTF16(windowBuffer);
3799
3800 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3801 obs->NotifyWhenScriptSafe(nullptr, "recording-window-ended", data.get());
3802 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)
3803 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)
;
3804}
3805
3806bool MediaManager::IsWindowListenerStillActive(
3807 const RefPtr<GetUserMediaWindowListener>& aListener) {
3808 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"
, 3808); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aListener"
")"); do { MOZ_CrashSequence(__null, 3808); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3809 return aListener && aListener == GetWindowListener(aListener->WindowID());
3810}
3811
3812nsresult MediaManager::GetPref(nsIPrefBranch* aBranch, const char* aPref,
3813 const char* aData, int32_t* aVal) {
3814 if (aData && strcmp(aPref, aData) != 0) {
3815 return NS_ERROR_INVALID_ARG;
3816 }
3817
3818 int32_t temp;
3819 nsresult rv = aBranch->GetIntPref(aPref, &temp);
3820 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3821 *aVal = temp;
3822 }
3823
3824 return rv;
3825}
3826
3827nsresult MediaManager::GetPrefBool(nsIPrefBranch* aBranch, const char* aPref,
3828 const char* aData, bool* aVal) {
3829 if (aData && strcmp(aPref, aData) != 0) {
3830 return NS_ERROR_INVALID_ARG;
3831 }
3832
3833 bool temp;
3834 nsresult rv = aBranch->GetBoolPref(aPref, &temp);
3835 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3836 *aVal = temp;
3837 }
3838
3839 return rv;
3840}
3841
3842#ifdef MOZ_WEBRTC1
3843template <class Enum, class Int>
3844constexpr Enum ClampEnum(Int v) {
3845 return std::clamp(
3846 static_cast<Enum>(SaturatingCast<std::underlying_type_t<Enum>>(v)),
3847 ContiguousEnumValues<Enum>::min, ContiguousEnumValues<Enum>::max);
3848}
3849#endif
3850
3851void MediaManager::GetPrefs(nsIPrefBranch* aBranch, const char* aData) {
3852 GetPref(aBranch, "media.navigator.video.default_width", aData,
3853 &mPrefs.mWidth);
3854 GetPref(aBranch, "media.navigator.video.default_height", aData,
3855 &mPrefs.mHeight);
3856 GetPref(aBranch, "media.navigator.video.default_fps", aData, &mPrefs.mFPS);
3857 GetPref(aBranch, "media.navigator.audio.fake_frequency", aData,
3858 &mPrefs.mFreq);
3859#ifdef MOZ_WEBRTC1
3860 GetPrefBool(aBranch, "media.navigator.video.resize_mode.enabled", aData,
3861 &mPrefs.mResizeModeEnabled);
3862 int32_t resizeMode{};
3863 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)))
3864 aData, &resizeMode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetPref(aBranch, "media.navigator.video.default_resize_mode"
, aData, &resizeMode))), 1)))
) {
3865 mPrefs.mResizeMode = ClampEnum<VideoResizeModeEnum>(resizeMode);
3866 }
3867 GetPrefBool(aBranch, "media.getusermedia.audio.processing.platform.enabled",
3868 aData, &mPrefs.mUsePlatformProcessing);
3869 GetPrefBool(aBranch, "media.getusermedia.audio.processing.aec.enabled", aData,
3870 &mPrefs.mAecOn);
3871 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc.enabled", aData,
3872 &mPrefs.mAgcOn);
3873 GetPrefBool(aBranch, "media.getusermedia.audio.processing.hpf.enabled", aData,
3874 &mPrefs.mHPFOn);
3875 GetPrefBool(aBranch, "media.getusermedia.audio.processing.noise.enabled",
3876 aData, &mPrefs.mNoiseOn);
3877 GetPrefBool(aBranch, "media.getusermedia.audio.processing.transient.enabled",
3878 aData, &mPrefs.mTransientOn);
3879 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc2.forced", aData,
3880 &mPrefs.mAgc2Forced);
3881 // Use 0 or 1 to force to false or true
3882 // EchoCanceller3Config::echo_removal_control.has_clock_drift.
3883 // -1 is the default, which means automatically set has_clock_drift as
3884 // deemed appropriate.
3885 GetPref(aBranch, "media.getusermedia.audio.processing.aec.expect_drift",
3886 aData, &mPrefs.mExpectDrift);
3887 GetPref(aBranch, "media.getusermedia.audio.processing.agc", aData,
3888 &mPrefs.mAgc);
3889 GetPref(aBranch, "media.getusermedia.audio.processing.noise", aData,
3890 &mPrefs.mNoise);
3891 GetPref(aBranch, "media.getusermedia.audio.max_channels", aData,
3892 &mPrefs.mChannels);
3893#endif
3894 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)
3895 "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)
3896 "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)
3897 "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)
3898 "{}, 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)
3899 __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)
3900 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)
3901 : "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)
3902 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)
3903 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)
3904 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)
3905 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)
3906 : 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)
3907 : "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)
3908 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)
3909 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)
;
3910}
3911
3912void MediaManager::Shutdown() {
3913 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", 3913); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 3913); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3914 if (sHasMainThreadShutdown) {
3915 return;
3916 }
3917
3918 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3919
3920 obs->RemoveObserver(this, "last-pb-context-exited");
3921 obs->RemoveObserver(this, "getUserMedia:privileged:allow");
3922 obs->RemoveObserver(this, "getUserMedia:response:allow");
3923 obs->RemoveObserver(this, "getUserMedia:response:deny");
3924 obs->RemoveObserver(this, "getUserMedia:response:noOSPermission");
3925 obs->RemoveObserver(this, "getUserMedia:revoke");
3926 obs->RemoveObserver(this, "getUserMedia:muteVideo");
3927 obs->RemoveObserver(this, "getUserMedia:unmuteVideo");
3928 obs->RemoveObserver(this, "getUserMedia:muteAudio");
3929 obs->RemoveObserver(this, "getUserMedia:unmuteAudio");
3930 obs->RemoveObserver(this, "application-background");
3931 obs->RemoveObserver(this, "application-foreground");
3932
3933 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
3934 if (prefs) {
3935 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
3936 prefs->RemoveObserver(aPrefName, this);
3937 });
3938 }
3939
3940 if (mDeviceChangeTimer) {
3941 mDeviceChangeTimer->Cancel();
3942 // Drop ref to MediaTimer early to avoid blocking SharedThreadPool shutdown
3943 mDeviceChangeTimer = nullptr;
3944 }
3945
3946 {
3947 // Close off any remaining active windows.
3948
3949 // Live capture at this point is rare but can happen. Stopping it will make
3950 // the window listeners attempt to remove themselves from the active windows
3951 // table. We cannot touch the table at point so we grab a copy of the window
3952 // listeners first.
3953 const auto listeners = ToArray(GetActiveWindows()->Values());
3954 for (const auto& listener : listeners) {
3955 listener->RemoveAll();
3956 }
3957 }
3958 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"
, 3958); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetActiveWindows()->Count() == 0"
")"); do { MOZ_CrashSequence(__null, 3958); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3959
3960 GetActiveWindows()->Clear();
3961 mActiveCallbacks.Clear();
3962 mCallIds.Clear();
3963 mPendingGUMRequest.Clear();
3964#ifdef MOZ_WEBRTC1
3965 mLogHandle = nullptr;
3966#endif
3967
3968 // From main thread's point of view, shutdown is now done.
3969 // All that remains is shutting down the media thread.
3970 sHasMainThreadShutdown = true;
3971
3972 // Release the backend (and call Shutdown()) from within mMediaThread.
3973 // Don't use MediaManager::Dispatch() because we're
3974 // sHasMainThreadShutdown == true here!
3975 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3976 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3977 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3978 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3979 // 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3980 // 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3981 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3982 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3983 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3984 }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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3985 // 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3986 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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
3987 })))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"
, 3978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 3978); __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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
, "./../../../dom/media/MediaManager.cpp", 3987); 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\", 3978); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { MOZ_CrashSequence(__null, 3978); __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { MOZ_CrashSequence(__null, 3987); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3988
3989 // note that this == sSingleton
3990 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", 3990); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "this == sSingleton" ")"); do { MOZ_CrashSequence
(__null, 3990); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3991
3992 // Explicitly shut down the TaskQueue so that it releases its
3993 // SharedThreadPool when all tasks have completed. SharedThreadPool blocks
3994 // XPCOM shutdown from proceeding beyond "xpcom-shutdown-threads" until all
3995 // SharedThreadPools are released, but the nsComponentManager keeps a
3996 // reference to the MediaManager for the nsIMediaManagerService until much
3997 // later in shutdown. This also provides additional assurance that no
3998 // further tasks will be queued.
3999 mMediaThread->BeginShutdown()->Then(
4000 GetMainThreadSerialEventTarget(), __func__, [] {
4001 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)
4002 "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)
;
4003 // Remove async shutdown blocker
4004 media::MustGetShutdownBarrier()->RemoveBlocker(
4005 sSingleton->mShutdownBlocker);
4006
4007 sSingleton = nullptr;
4008 });
4009}
4010
4011void MediaManager::SendPendingGUMRequest() {
4012 if (mPendingGUMRequest.Length() > 0) {
4013 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
4014 obs->NotifyObservers(mPendingGUMRequest[0], "getUserMedia:request",
4015 nullptr);
4016 mPendingGUMRequest.RemoveElementAt(0);
4017 }
4018}
4019
4020bool IsGUMResponseNoAccess(const char* aTopic,
4021 MediaMgrError::Name& aErrorName) {
4022 if (!strcmp(aTopic, "getUserMedia:response:deny")) {
4023 aErrorName = MediaMgrError::Name::NotAllowedError;
4024 return true;
4025 }
4026
4027 if (!strcmp(aTopic, "getUserMedia:response:noOSPermission")) {
4028 aErrorName = MediaMgrError::Name::NotFoundError;
4029 return true;
4030 }
4031
4032 return false;
4033}
4034
4035static MediaSourceEnum ParseScreenColonWindowID(const char16_t* aData,
4036 uint64_t* aWindowIDOut) {
4037 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"
, 4037); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindowIDOut"
")"); do { MOZ_CrashSequence(__null, 4037); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4038 // may be windowid or screen:windowid
4039 const nsDependentString data(aData);
4040 if (Substring(data, 0, strlen("screen:")).EqualsLiteral("screen:")) {
4041 nsresult rv;
4042 *aWindowIDOut = Substring(data, strlen("screen:")).ToInteger64(&rv);
4043 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"
, 4043); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 4043); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4044 return MediaSourceEnum::Screen;
4045 }
4046 nsresult rv;
4047 *aWindowIDOut = data.ToInteger64(&rv);
4048 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"
, 4048); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 4048); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4049 return MediaSourceEnum::Camera;
4050}
4051
4052nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
4053 const char16_t* aData) {
4054 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", 4054); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4054); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4055
4056 MediaMgrError::Name gumNoAccessError = MediaMgrError::Name::NotAllowedError;
4057
4058 if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
4059 nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(aSubject));
4060 if (branch) {
4061 GetPrefs(branch, NS_ConvertUTF16toUTF8(aData).get());
4062 DeviceListChanged();
4063 }
4064 } else if (!strcmp(aTopic, "last-pb-context-exited")) {
4065 // Clear memory of private-browsing-specific deviceIds. Fire and forget.
4066 media::SanitizeOriginKeys(0, true);
4067 return NS_OK;
4068 } else if (!strcmp(aTopic, "getUserMedia:got-device-permission")) {
4069 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"
, 4069); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSubject" ")"
); do { MOZ_CrashSequence(__null, 4069); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4070 nsCOMPtr<nsIRunnable> task = do_QueryInterface(aSubject);
4071 MediaManager::Dispatch(NewTaskFrom([task] { task->Run(); }));
4072 return NS_OK;
4073 } else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
4074 !strcmp(aTopic, "getUserMedia:response:allow")) {
4075 nsString key(aData);
4076 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
4077 if (!task) {
4078 return NS_OK;
4079 }
4080
4081 if (sHasMainThreadShutdown) {
4082 task->Denied(MediaMgrError::Name::AbortError, "In shutdown"_ns);
4083 return NS_OK;
4084 }
4085 if (NS_WARN_IF(!aSubject)NS_warn_if_impl(!aSubject, "!aSubject", "./../../../dom/media/MediaManager.cpp"
, 4085)
) {
4086 return NS_ERROR_FAILURE; // ignored
4087 }
4088 // Permission has been granted. aSubject contains the particular device
4089 // or devices selected and approved by the user, if any.
4090 nsCOMPtr<nsIArray> array(do_QueryInterface(aSubject));
4091 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"
, 4091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { MOZ_CrashSequence(__null, 4091); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4092 uint32_t len = 0;
4093 array->GetLength(&len);
4094 RefPtr<LocalMediaDevice> audioInput;
4095 RefPtr<LocalMediaDevice> videoInput;
4096 RefPtr<LocalMediaDevice> audioOutput;
4097 for (uint32_t i = 0; i < len; i++) {
4098 nsCOMPtr<nsIMediaDevice> device;
4099 array->QueryElementAt(i, NS_GET_IID(nsIMediaDevice)(nsIMediaDevice::kIID),
4100 getter_AddRefs(device));
4101 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"
, 4101); AnnotateMozCrashReason("MOZ_ASSERT" "(" "device" ")"
); do { MOZ_CrashSequence(__null, 4101); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // shouldn't be returning anything else...
4102 if (!device) {
4103 continue;
4104 }
4105
4106 // Casting here is safe because a LocalMediaDevice is created
4107 // only in Gecko side, JS can only query for an instance.
4108 auto* dev = static_cast<LocalMediaDevice*>(device.get());
4109 switch (dev->Kind()) {
4110 case MediaDeviceKind::Videoinput:
4111 if (!videoInput) {
4112 videoInput = dev;
4113 }
4114 break;
4115 case MediaDeviceKind::Audioinput:
4116 if (!audioInput) {
4117 audioInput = dev;
4118 }
4119 break;
4120 case MediaDeviceKind::Audiooutput:
4121 if (!audioOutput) {
4122 audioOutput = dev;
4123 }
4124 break;
4125 default:
4126 MOZ_CRASH("Unexpected device kind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected device kind"
, "./../../../dom/media/MediaManager.cpp", 4126); AnnotateMozCrashReason
("MOZ_CRASH(" "Unexpected device kind" ")"); do { MOZ_CrashSequence
(__null, 4126); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
;
4127 }
4128 }
4129
4130 if (GetUserMediaStreamTask* streamTask = task->AsGetUserMediaStreamTask()) {
4131 bool needVideo = IsOn(streamTask->GetConstraints().mVideo);
4132 bool needAudio = IsOn(streamTask->GetConstraints().mAudio);
4133 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", 4133); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "needVideo || needAudio" ")"); do { MOZ_CrashSequence
(__null, 4133); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4134
4135 if ((needVideo && !videoInput) || (needAudio && !audioInput)) {
4136 task->Denied(MediaMgrError::Name::NotAllowedError);
4137 return NS_OK;
4138 }
4139 streamTask->Allowed(std::move(audioInput), std::move(videoInput));
4140 return NS_OK;
4141 }
4142 if (SelectAudioOutputTask* outputTask = task->AsSelectAudioOutputTask()) {
4143 if (!audioOutput) {
4144 task->Denied(MediaMgrError::Name::NotAllowedError);
4145 return NS_OK;
4146 }
4147 outputTask->Allowed(std::move(audioOutput));
4148 return NS_OK;
4149 }
4150
4151 NS_WARNING("Unknown task type in getUserMedia")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown task type in getUserMedia"
, nullptr, "./../../../dom/media/MediaManager.cpp", 4151)
;
4152 return NS_ERROR_FAILURE;
4153
4154 } else if (IsGUMResponseNoAccess(aTopic, gumNoAccessError)) {
4155 nsString key(aData);
4156 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
4157 if (task) {
4158 task->Denied(gumNoAccessError);
4159 SendPendingGUMRequest();
4160 }
4161 return NS_OK;
4162
4163 } else if (!strcmp(aTopic, "getUserMedia:revoke")) {
4164 uint64_t windowID;
4165 if (ParseScreenColonWindowID(aData, &windowID) == MediaSourceEnum::Screen) {
4166 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)
;
4167 StopScreensharing(windowID);
4168 } else {
4169 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)
;
4170 OnNavigation(windowID);
4171 }
4172 return NS_OK;
4173 } else if (!strcmp(aTopic, "getUserMedia:muteVideo") ||
4174 !strcmp(aTopic, "getUserMedia:unmuteVideo")) {
4175 OnCameraMute(!strcmp(aTopic, "getUserMedia:muteVideo"));
4176 return NS_OK;
4177 } else if (!strcmp(aTopic, "getUserMedia:muteAudio") ||
4178 !strcmp(aTopic, "getUserMedia:unmuteAudio")) {
4179 OnMicrophoneMute(!strcmp(aTopic, "getUserMedia:muteAudio"));
4180 return NS_OK;
4181 } else if ((!strcmp(aTopic, "application-background") ||
4182 !strcmp(aTopic, "application-foreground")) &&
4183 StaticPrefs::media_getusermedia_camera_background_mute_enabled()) {
4184 // On mobile we turn off any cameras (but not mics) while in the background.
4185 // Keeping things simple for now by duplicating test-covered code above.
4186 //
4187 // NOTE: If a mobile device ever wants to implement "getUserMedia:muteVideo"
4188 // as well, it'd need to update this code to handle & test the combinations.
4189 OnCameraMute(!strcmp(aTopic, "application-background"));
4190 }
4191
4192 return NS_OK;
4193}
4194
4195NS_IMETHODIMPnsresult
4196MediaManager::CollectReports(nsIHandleReportCallback* aHandleReport,
4197 nsISupports* aData, bool aAnonymize) {
4198 size_t amount = 0;
4199 amount += mActiveWindows.ShallowSizeOfExcludingThis(MallocSizeOf);
4200 for (const GetUserMediaWindowListener* listener : mActiveWindows.Values()) {
4201 amount += listener->SizeOfIncludingThis(MallocSizeOf);
4202 }
4203 amount += mActiveCallbacks.ShallowSizeOfExcludingThis(MallocSizeOf);
4204 for (const GetUserMediaTask* task : mActiveCallbacks.Values()) {
4205 // Assume nsString buffers for keys are accounted in mCallIds.
4206 amount += task->SizeOfIncludingThis(MallocSizeOf);
4207 }
4208 amount += mCallIds.ShallowSizeOfExcludingThis(MallocSizeOf);
4209 for (const auto& array : mCallIds.Values()) {
4210 amount += array->ShallowSizeOfExcludingThis(MallocSizeOf);
4211 for (const nsString& callID : *array) {
4212 amount += callID.SizeOfExcludingThisEvenIfShared(MallocSizeOf);
4213 }
4214 }
4215 amount += mPendingGUMRequest.ShallowSizeOfExcludingThis(MallocSizeOf);
4216 // GetUserMediaRequest pointees of mPendingGUMRequest do not have support
4217 // for memory accounting. mPendingGUMRequest logic should probably be moved
4218 // to the front end (bug 1691625).
4219 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)
4220 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)
4221 "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)
;
4222 return NS_OK;
4223}
4224
4225nsresult MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray) {
4226 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"
, 4226); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aArray" ")"
); do { MOZ_CrashSequence(__null, 4226); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4227
4228 nsCOMPtr<nsIMutableArray> array = nsArray::Create();
4229
4230 for (const auto& entry : mActiveWindows) {
4231 const uint64_t& id = entry.GetKey();
4232 RefPtr<GetUserMediaWindowListener> winListener = entry.GetData();
4233 if (!winListener) {
4234 continue;
4235 }
4236
4237 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(id);
4238 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"
, 4238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { MOZ_CrashSequence(__null, 4238); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4239 // XXXkhuey ...
4240 if (!window) {
4241 continue;
4242 }
4243
4244 if (winListener->CapturingVideo() || winListener->CapturingAudio()) {
4245 array->AppendElement(ToSupports(window));
4246 }
4247 }
4248
4249 array.forget(aArray);
4250 return NS_OK;
4251}
4252
4253struct CaptureWindowStateData {
4254 uint16_t* mCamera;
4255 uint16_t* mMicrophone;
4256 uint16_t* mScreenShare;
4257 uint16_t* mWindowShare;
4258 uint16_t* mAppShare;
4259 uint16_t* mBrowserShare;
4260};
4261
4262NS_IMETHODIMPnsresult
4263MediaManager::MediaCaptureWindowState(
4264 nsIDOMWindow* aCapturedWindow, uint16_t* aCamera, uint16_t* aMicrophone,
4265 uint16_t* aScreen, uint16_t* aWindow, uint16_t* aBrowser,
4266 nsTArray<RefPtr<nsIMediaDevice>>& aDevices) {
4267 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", 4267); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4267); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4268
4269 CaptureState camera = CaptureState::Off;
4270 CaptureState microphone = CaptureState::Off;
4271 CaptureState screen = CaptureState::Off;
4272 CaptureState window = CaptureState::Off;
4273 CaptureState browser = CaptureState::Off;
4274 RefPtr<LocalMediaDeviceSetRefCnt> devices;
4275
4276 nsCOMPtr<nsPIDOMWindowInner> piWin = do_QueryInterface(aCapturedWindow);
4277 if (piWin) {
4278 if (RefPtr<GetUserMediaWindowListener> listener =
4279 GetWindowListener(piWin->WindowID())) {
4280 camera = listener->CapturingSource(MediaSourceEnum::Camera);
4281 microphone = listener->CapturingSource(MediaSourceEnum::Microphone);
4282 screen = listener->CapturingSource(MediaSourceEnum::Screen);
4283 window = listener->CapturingSource(MediaSourceEnum::Window);
4284 browser = listener->CapturingSource(MediaSourceEnum::Browser);
4285 devices = listener->GetDevices();
4286 }
4287 }
4288
4289 *aCamera = FromCaptureState(camera);
4290 *aMicrophone = FromCaptureState(microphone);
4291 *aScreen = FromCaptureState(screen);
4292 *aWindow = FromCaptureState(window);
4293 *aBrowser = FromCaptureState(browser);
4294 if (devices) {
4295 for (auto& device : *devices) {
4296 aDevices.AppendElement(device);
4297 }
4298 }
4299
4300 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)
4301 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)
4302 *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)
4303 ? "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)
4304 : (*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)
4305 ? "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)
4306 : ""),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)
4307 *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)
4308 ? "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)
4309 : (*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)
4310 ? "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)
4311 : ""),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)
4312 *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)
4313 *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)
;
4314
4315 return NS_OK;
4316}
4317
4318NS_IMETHODIMPnsresult
4319MediaManager::SanitizeDeviceIds(int64_t aSinceWhen) {
4320 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", 4320); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4320); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4321 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)
;
4322
4323 media::SanitizeOriginKeys(aSinceWhen, false); // we fire and forget
4324 return NS_OK;
4325}
4326
4327void MediaManager::StopScreensharing(uint64_t aWindowID) {
4328 // We need to stop window/screensharing for all streams in this innerwindow.
4329
4330 if (RefPtr<GetUserMediaWindowListener> listener =
4331 GetWindowListener(aWindowID)) {
4332 listener->StopSharing();
4333 }
4334}
4335
4336bool MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId) {
4337 // Does page currently have a gUM stream active?
4338
4339 nsCOMPtr<nsIArray> array;
4340 GetActiveMediaCaptureWindows(getter_AddRefs(array));
4341 uint32_t len;
4342 array->GetLength(&len);
4343 for (uint32_t i = 0; i < len; i++) {
4344 nsCOMPtr<nsPIDOMWindowInner> win;
4345 array->QueryElementAt(i, NS_GET_IID(nsPIDOMWindowInner)(nsPIDOMWindowInner::kIID),
4346 getter_AddRefs(win));
4347 if (win && win->WindowID() == aWindowId) {
4348 return true;
4349 }
4350 }
4351
4352 // Or are persistent permissions (audio or video) granted?
4353
4354 return GetPersistentPermissions(aWindowId)
4355 .map([](auto&& aState) {
4356 return aState.mMicrophonePermission ==
4357 PersistentPermissionState::Allow ||
4358 aState.mCameraPermission == PersistentPermissionState::Allow;
4359 })
4360 .unwrapOr(false);
4361}
4362
4363DeviceListener::DeviceListener()
4364 : mStopped(false),
4365 mMainThreadCheck(nullptr),
4366 mPrincipalHandle(PRINCIPAL_HANDLE_NONEnullptr),
4367 mWindowListener(nullptr) {}
4368
4369void DeviceListener::Register(GetUserMediaWindowListener* aListener) {
4370 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)
4371 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)
;
4372
4373 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", 4373); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "aListener" ") (" "No listener" ")"); do { MOZ_CrashSequence
(__null, 4373); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4374 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"
, 4374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mWindowListener"
") (" "Already registered" ")"); do { MOZ_CrashSequence(__null
, 4374); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4375 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"
, 4375); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 4375); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4376
4377 mPrincipalHandle = aListener->GetPrincipalHandle();
4378 mWindowListener = aListener;
4379}
4380
4381void DeviceListener::Activate(RefPtr<LocalMediaDevice> aDevice,
4382 RefPtr<LocalTrackSource> aTrackSource,
4383 bool aStartMuted, bool aIsAllocated) {
4384 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"
, 4384); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4384); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4385
4386 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)
4387 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)
;
4388
4389 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", 4389); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "!mStopped" ") (" "Cannot activate stopped device listener"
")"); do { MOZ_CrashSequence(__null, 4389); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4390 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"
, 4390); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { MOZ_CrashSequence(__null
, 4390); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
4391
4392 mMainThreadCheck = PR_GetCurrentThread();
4393 bool offWhileDisabled =
4394 (aDevice->GetMediaSource() == MediaSourceEnum::Microphone &&
4395 Preferences::GetBool(
4396 "media.getusermedia.microphone.off_while_disabled.enabled", true)) ||
4397 (aDevice->GetMediaSource() == MediaSourceEnum::Camera &&
4398 Preferences::GetBool(
4399 "media.getusermedia.camera.off_while_disabled.enabled", true));
4400
4401 if (MediaEventSource<void>* event = aDevice->Source()->CaptureEndedEvent()) {
4402 mCaptureEndedListener = event->Connect(AbstractThread::MainThread(), this,
4403 &DeviceListener::Stop);
4404 }
4405
4406 mDeviceState = std::make_unique<DeviceState>(
4407 std::move(aDevice), std::move(aTrackSource), offWhileDisabled);
4408 mDeviceState->mDeviceMuted = aStartMuted;
4409 mDeviceState->mAllocated = aIsAllocated;
4410 if (aStartMuted) {
4411 mDeviceState->mTrackSource->Mute();
4412 }
4413}
4414
4415RefPtr<DeviceListener::DeviceListenerPromise>
4416DeviceListener::InitializeAsync() {
4417 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"
, 4417); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4417); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4418 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"
, 4418); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mStopped"
")"); do { MOZ_CrashSequence(__null, 4418); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4419
4420 return InvokeAsync(
4421 MediaManager::Get()->mMediaThread, __func__,
4422 [this, self = RefPtr(this), principal = GetPrincipalHandle(),
4423 device = mDeviceState->mDevice,
4424 track = mDeviceState->mTrackSource->mTrack] {
4425 // Start the device if not muted, or if mOffWhileDisabled is
4426 // false (the device should remain on even when muted).
4427 bool startDevice = !mDeviceState->mDeviceMuted ||
4428 !mDeviceState->mOffWhileDisabled;
4429 nsresult rv = Initialize(principal, device, track, startDevice);
4430 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4431 return GenericPromise::CreateAndResolve(
4432 true, "DeviceListener::InitializeAsync success");
4433 }
4434 return GenericPromise::CreateAndReject(
4435 rv, "DeviceListener::InitializeAsync failure");
4436 })
4437 ->Then(
4438 GetMainThreadSerialEventTarget(), __func__,
4439 [self = RefPtr<DeviceListener>(this), this](bool) {
4440 if (mStopped) {
4441 // We were shut down during the async init
4442 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4443 }
4444
4445 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"
, 4445); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { MOZ_CrashSequence(__null, 4445); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4446 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"
, 4446); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { MOZ_CrashSequence(__null, 4446); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4447 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", 4447); AnnotateMozCrashReason
("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped" ")"
); do { MOZ_CrashSequence(__null, 4447); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4448
4449 mDeviceState->mDeviceEnabled = true;
4450 mDeviceState->mTrackEnabled = true;
4451 mDeviceState->mTrackEnabledTime = TimeStamp::Now();
4452 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4453 },
4454 [self = RefPtr<DeviceListener>(this), this](nsresult aRv) {
4455 auto kind = mDeviceState->mDevice->Kind();
4456 RefPtr<MediaMgrError> err;
4457 if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) {
4458 auto name =
4459 (aRv == NS_ERROR_FAILURE || aRv == NS_ERROR_NOT_AVAILABLE)
4460 ? MediaMgrError::Name::NotReadableError
4461 : MediaMgrError::Name::AbortError;
4462 nsCString log;
4463 log.AppendPrintf("Starting %s failed",
4464 dom::GetEnumString(kind).get());
4465 err = MakeRefPtr<MediaMgrError>(name, std::move(log));
4466 }
4467
4468 if (mStopped) {
4469 return DeviceListenerPromise::CreateAndReject(err, __func__);
4470 }
4471
4472 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"
, 4472); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { MOZ_CrashSequence(__null, 4472); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4473 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"
, 4473); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { MOZ_CrashSequence(__null, 4473); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4474 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", 4474); AnnotateMozCrashReason
("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped" ")"
); do { MOZ_CrashSequence(__null, 4474); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4475
4476 Stop();
4477
4478 return DeviceListenerPromise::CreateAndReject(err, __func__);
4479 });
4480}
4481
4482nsresult DeviceListener::Initialize(PrincipalHandle aPrincipal,
4483 LocalMediaDevice* aDevice,
4484 MediaTrack* aTrack, bool aStartDevice) {
4485 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"
, 4485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 4485); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4486
4487 auto kind = aDevice->Kind();
4488 aDevice->SetTrack(aTrack, aPrincipal);
4489 nsresult rv = aStartDevice ? aDevice->Start() : NS_OK;
4490 if (kind == MediaDeviceKind::Audioinput ||
4491 kind == MediaDeviceKind::Videoinput) {
4492 if ((rv == NS_ERROR_NOT_AVAILABLE && kind == MediaDeviceKind::Audioinput) ||
4493 (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && kind == MediaDeviceKind::Videoinput)) {
4494 PR_Sleep(200);
4495 rv = aDevice->Start();
4496 }
4497 }
4498 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)
4499 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)
;
4500 return rv;
4501}
4502
4503already_AddRefed<DeviceListener> DeviceListener::Clone() const {
4504 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", 4504); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4504); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4505 MediaManager* mgr = MediaManager::GetIfExists();
4506 if (!mgr) {
4507 return nullptr;
4508 }
4509 if (!mWindowListener) {
4510 return nullptr;
4511 }
4512 auto* thisDevice = GetDevice();
4513 if (!thisDevice) {
4514 return nullptr;
4515 }
4516
4517 auto* thisTrackSource = GetTrackSource();
4518 if (!thisTrackSource) {
4519 return nullptr;
4520 }
4521
4522 // See PrepareDOMStream for how a gUM/gDM track is created.
4523 RefPtr<MediaTrack> track;
4524 MediaTrackGraph* mtg = thisTrackSource->mTrack->Graph();
4525 if (const auto source = thisDevice->GetMediaSource();
4526 source == dom::MediaSourceEnum::Microphone) {
4527#ifdef MOZ_WEBRTC1
4528 if (thisDevice->IsFake()) {
4529 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
4530 } else {
4531 track = AudioProcessingTrack::Create(mtg);
4532 track->Suspend(); // Microphone source resumes in SetTrack
4533 }
4534#else
4535 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
4536#endif
4537 } else if (source == dom::MediaSourceEnum::Camera ||
4538 source == dom::MediaSourceEnum::Screen ||
4539 source == dom::MediaSourceEnum::Window ||
4540 source == dom::MediaSourceEnum::Browser) {
4541 track = mtg->CreateSourceTrack(MediaSegment::VIDEO);
4542 }
4543
4544 if (!track) {
4545 return nullptr;
4546 }
4547
4548 RefPtr device = thisDevice->Clone();
4549 auto listener = MakeRefPtr<DeviceListener>();
4550 auto trackSource = MakeRefPtr<LocalTrackSource>(
4551 thisTrackSource->GetPrincipal(), thisTrackSource->mLabel, listener,
4552 thisTrackSource->mSource, track, thisTrackSource->mPeerIdentity,
4553 thisTrackSource->mTrackingId);
4554
4555 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)
;
4556 mWindowListener->Register(listener);
4557 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)
;
4558 mWindowListener->Activate(listener, device, trackSource,
4559 /*aIsAllocated=*/false);
4560
4561 listener->mDeviceState->mDeviceEnabled = mDeviceState->mDeviceEnabled;
4562 listener->mDeviceState->mDeviceMuted = mDeviceState->mDeviceMuted;
4563 listener->mDeviceState->mTrackEnabled = mDeviceState->mTrackEnabled;
4564 listener->mDeviceState->mTrackEnabledTime = TimeStamp::Now();
4565
4566 // We have to do an async operation here, even though Clone() is sync.
4567 // This is fine because JS will not be able to trigger any operation to run
4568 // async on the media thread.
4569 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)
4570 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)
;
4571 InvokeAsync(
4572 mgr->mMediaThread, __func__,
4573 [thisDevice = RefPtr(thisDevice), device, prefs = mgr->mPrefs,
4574 windowId = mWindowListener->WindowID(), listener,
4575 principal = GetPrincipalHandle(), track,
4576 startDevice = !listener->mDeviceState->mOffWhileDisabled ||
4577 (!listener->mDeviceState->mDeviceMuted &&
4578 listener->mDeviceState->mDeviceEnabled)] {
4579 const char* outBadConstraint{};
4580 nsresult rv = device->Source()->Allocate(
4581 thisDevice->Constraints(), prefs, windowId, &outBadConstraint);
4582 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)
4583 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)
;
4584 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4585 return GenericPromise::CreateAndReject(
4586 rv, "DeviceListener::Clone failure #1");
4587 }
4588 rv = listener->Initialize(principal, device, track, startDevice);
4589 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4590 return GenericPromise::CreateAndResolve(
4591 true, "DeviceListener::Clone success");
4592 }
4593 return GenericPromise::CreateAndReject(
4594 rv, "DeviceListener::Clone failure #2");
4595 })
4596 ->Then(
4597 GetMainThreadSerialEventTarget(), __func__,
4598 [listener, device,
4599 trackSource](GenericPromise::ResolveOrRejectValue&& aValue) {
4600 if (aValue.IsReject()) {
4601 // Allocating/initializing failed. Stopping the device listener
4602 // will destroy the MediaStreamTrackSource's MediaTrack, which
4603 // will make the MediaStreamTrack's mTrack MediaTrack auto-end
4604 // due to lack of inputs. This makes the MediaStreamTrack's
4605 // readyState transition to "ended" as expected.
4606 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)
4607 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)
;
4608 listener->Stop();
4609 return;
4610 }
4611 listener->mDeviceState->mAllocated = true;
4612 if (listener->mDeviceState->mStopped && !sHasMainThreadShutdown) {
4613 MediaManager::Dispatch(NS_NewRunnableFunction(
4614 "DeviceListener::Clone::Stop",
4615 [device = listener->mDeviceState->mDevice]() {
4616 device->Stop();
4617 device->Deallocate();
4618 }));
4619 }
4620 });
4621
4622 return listener.forget();
4623}
4624
4625void DeviceListener::Stop() {
4626 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"
, 4626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4626); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4627
4628 if (mStopped) {
4629 return;
4630 }
4631 mStopped = true;
4632
4633 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)
;
4634
4635 if (mDeviceState) {
4636 mDeviceState->mDisableTimer->Cancel();
4637
4638 if (mDeviceState->mStopped) {
4639 // device already stopped.
4640 return;
4641 }
4642 mDeviceState->mStopped = true;
4643
4644 mDeviceState->mTrackSource->Stop();
4645
4646 if (mDeviceState->mAllocated) {
4647 MediaManager::Dispatch(NewTaskFrom([device = mDeviceState->mDevice]() {
4648 device->Stop();
4649 device->Deallocate();
4650 }));
4651 }
4652
4653 mWindowListener->ChromeAffectingStateChanged();
4654 }
4655
4656 mCaptureEndedListener.DisconnectIfExists();
4657
4658 // Keep a strong ref to the removed window listener.
4659 RefPtr<GetUserMediaWindowListener> windowListener = mWindowListener;
4660 mWindowListener = nullptr;
4661 windowListener->Remove(this);
4662}
4663
4664void DeviceListener::GetSettings(MediaTrackSettings& aOutSettings) const {
4665 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"
, 4665); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4665); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4666 LocalMediaDevice* device = GetDevice();
4667 device->GetSettings(aOutSettings);
4668
4669 MediaSourceEnum mediaSource = device->GetMediaSource();
4670 if (mediaSource == MediaSourceEnum::Camera ||
4671 mediaSource == MediaSourceEnum::Microphone) {
4672 aOutSettings.mDeviceId.Construct(device->mID);
4673 aOutSettings.mGroupId.Construct(device->mGroupID);
4674 }
4675}
4676
4677void DeviceListener::GetCapabilities(
4678 MediaTrackCapabilities& aOutCapabilities) const {
4679 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"
, 4679); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4679); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4680 LocalMediaDevice* device = GetDevice();
4681 device->GetCapabilities(aOutCapabilities);
4682
4683 MediaSourceEnum mediaSource = device->GetMediaSource();
4684 if (mediaSource == MediaSourceEnum::Camera ||
4685 mediaSource == MediaSourceEnum::Microphone) {
4686 aOutCapabilities.mDeviceId.Construct(device->mID);
4687 aOutCapabilities.mGroupId.Construct(device->mGroupID);
4688 }
4689}
4690
4691auto DeviceListener::UpdateDevice(bool aOn) -> RefPtr<DeviceOperationPromise> {
4692 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", 4692); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4692); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4693 RefPtr<DeviceListener> self = this;
4694 DeviceState& state = *mDeviceState;
4695 return MediaManager::Dispatch<DeviceOperationPromise>(
4696 __func__,
4697 [self, device = state.mDevice,
4698 aOn](MozPromiseHolder<DeviceOperationPromise>& h) {
4699 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)
4700 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)
;
4701 h.Resolve(aOn ? device->Start() : device->Stop(), __func__);
4702 })
4703 ->Then(
4704 GetMainThreadSerialEventTarget(), __func__,
4705 [self, this, &state, aOn](nsresult aResult) {
4706 if (state.mStopped) {
4707 // Device was stopped on main thread during the operation. Done.
4708 return DeviceOperationPromise::CreateAndResolve(aResult,
4709 __func__);
4710 }
4711 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)
4712 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)
4713 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)
4714 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)
;
4715
4716 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT) {
4717 // This path handles errors from starting or stopping the
4718 // device. NS_ERROR_ABORT are for cases where *we* aborted. They
4719 // need graceful handling.
4720 if (aOn) {
4721 // Starting the device failed. Stopping the track here will
4722 // make the MediaStreamTrack end after a pass through the
4723 // MediaTrackGraph.
4724 Stop();
4725 } else {
4726 // Stopping the device failed. This is odd, but not fatal.
4727 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"
, 4727); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "The device should be stoppable" ")"
); do { MOZ_CrashSequence(__null, 4727); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4728 }
4729 }
4730 return DeviceOperationPromise::CreateAndResolve(aResult, __func__);
4731 },
4732 []() {
4733 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"
, 4733); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { MOZ_CrashSequence(__null, 4733); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4734 return DeviceOperationPromise::CreateAndReject(false, __func__);
4735 });
4736}
4737
4738void DeviceListener::SetDeviceEnabled(bool aEnable) {
4739 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"
, 4739); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4739); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4740 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"
, 4740); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set enabled state for" ")"); do { MOZ_CrashSequence
(__null, 4740); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4741
4742 DeviceState& state = *mDeviceState;
4743
4744 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)
4745 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)
4746 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)
;
4747
4748 state.mTrackEnabled = aEnable;
4749
4750 if (state.mStopped) {
4751 // Device terminally stopped. Updating device state is pointless.
4752 return;
4753 }
4754
4755 if (state.mOperationInProgress) {
4756 // If a timer is in progress, it needs to be canceled now so the next
4757 // DisableTrack() gets a fresh start. Canceling will trigger another
4758 // operation.
4759 state.mDisableTimer->Cancel();
4760 return;
4761 }
4762
4763 if (state.mDeviceEnabled == aEnable) {
4764 // Device is already in the desired state.
4765 return;
4766 }
4767
4768 // All paths from here on must end in setting
4769 // `state.mOperationInProgress` to false.
4770 state.mOperationInProgress = true;
4771
4772 RefPtr<MediaTimerPromise> timerPromise;
4773 if (aEnable) {
4774 timerPromise = MediaTimerPromise::CreateAndResolve(true, __func__);
4775 state.mTrackEnabledTime = TimeStamp::Now();
4776 } else {
4777 const TimeDuration maxDelay =
4778 TimeDuration::FromMilliseconds(Preferences::GetUint(
4779 GetDevice()->Kind() == MediaDeviceKind::Audioinput
4780 ? "media.getusermedia.microphone.off_while_disabled.delay_ms"
4781 : "media.getusermedia.camera.off_while_disabled.delay_ms",
4782 3000));
4783 const TimeDuration durationEnabled =
4784 TimeStamp::Now() - state.mTrackEnabledTime;
4785 const TimeDuration delay = TimeDuration::Max(
4786 TimeDuration::FromMilliseconds(0), maxDelay - durationEnabled);
4787 timerPromise = state.mDisableTimer->WaitFor(delay, __func__);
4788 }
4789
4790 RefPtr<DeviceListener> self = this;
4791 timerPromise
4792 ->Then(
4793 GetMainThreadSerialEventTarget(), __func__,
4794 [self, this, &state, aEnable]() mutable {
4795 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", 4796); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable" ") (" "Device operation hasn't started"
")"); do { MOZ_CrashSequence(__null, 4796); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4796 "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", 4796); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable" ") (" "Device operation hasn't started"
")"); do { MOZ_CrashSequence(__null, 4796); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4797 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", 4798); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ") (" "It's our responsibility to reset the inProgress state"
")"); do { MOZ_CrashSequence(__null, 4798); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4798 "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", 4798); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ") (" "It's our responsibility to reset the inProgress state"
")"); do { MOZ_CrashSequence(__null, 4798); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4799
4800 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)
4801 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)
4802 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)
;
4803
4804 if (state.mStopped) {
4805 // Source was stopped between timer resolving and this runnable.
4806 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4807 __func__);
4808 }
4809
4810 state.mDeviceEnabled = aEnable;
4811
4812 if (mWindowListener) {
4813 mWindowListener->ChromeAffectingStateChanged();
4814 }
4815 if (!state.mOffWhileDisabled || state.mDeviceMuted) {
4816 // If the feature to turn a device off while disabled is itself
4817 // disabled, or the device is currently user agent muted, then
4818 // we shortcut the device operation and tell the
4819 // ux-updating code that everything went fine.
4820 return DeviceOperationPromise::CreateAndResolve(NS_OK, __func__);
4821 }
4822 return UpdateDevice(aEnable);
4823 },
4824 []() {
4825 // Timer was canceled by us. We signal this with NS_ERROR_ABORT.
4826 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4827 __func__);
4828 })
4829 ->Then(
4830 GetMainThreadSerialEventTarget(), __func__,
4831 [self, this, &state, aEnable](nsresult aResult) mutable {
4832 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", 4833); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable" ")"); do {
MOZ_CrashSequence(__null, 4833); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (false
)
4833 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", 4833); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable" ")"); do {
MOZ_CrashSequence(__null, 4833); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (false
)
;
4834 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", 4834); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "state.mOperationInProgress" ")"); do { MOZ_CrashSequence
(__null, 4834); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4835 state.mOperationInProgress = false;
4836
4837 if (state.mStopped) {
4838 // Device was stopped on main thread during the operation.
4839 // Nothing to do.
4840 return;
4841 }
4842
4843 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT && !aEnable) {
4844 // To keep our internal state sane in this case, we disallow
4845 // future stops due to disable.
4846 state.mOffWhileDisabled = false;
4847 return;
4848 }
4849
4850 // This path is for a device operation aResult that was success or
4851 // NS_ERROR_ABORT (*we* canceled the operation).
4852 // At this point we have to follow up on the intended state, i.e.,
4853 // update the device state if the track state changed in the
4854 // meantime.
4855
4856 if (state.mTrackEnabled != state.mDeviceEnabled) {
4857 // Track state changed during this operation. We'll start over.
4858 SetDeviceEnabled(state.mTrackEnabled);
4859 }
4860 },
4861 []() { 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"
, 4861); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { MOZ_CrashSequence(__null, 4861); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; });
4862}
4863
4864void DeviceListener::SetDeviceMuted(bool aMute) {
4865 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"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 4865); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4866 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"
, 4866); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set muted state for" ")"); do { MOZ_CrashSequence
(__null, 4866); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4867
4868 DeviceState& state = *mDeviceState;
4869
4870 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)
4871 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)
4872 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)
;
4873
4874 if (state.mStopped) {
4875 // Device terminally stopped. Updating device state is pointless.
4876 return;
4877 }
4878
4879 if (state.mDeviceMuted == aMute) {
4880 // Device is already in the desired state.
4881 return;
4882 }
4883
4884 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)
4885 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)
4886 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)
;
4887
4888 state.mDeviceMuted = aMute;
4889
4890 if (mWindowListener) {
4891 mWindowListener->ChromeAffectingStateChanged();
4892 }
4893 // Update trackSource to fire mute/unmute events on all its tracks
4894 if (aMute) {
4895 state.mTrackSource->Mute();
4896 } else {
4897 state.mTrackSource->Unmute();
4898 }
4899 if (!state.mOffWhileDisabled || !state.mDeviceEnabled) {
4900 // If the pref to turn the underlying device is itself off, or the device
4901 // is already off, it's unecessary to do anything else.
4902 return;
4903 }
4904 UpdateDevice(!aMute);
4905}
4906
4907void DeviceListener::MuteOrUnmuteCamera(bool aMute) {
4908 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", 4908); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4908); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4909
4910 if (mStopped) {
4911 return;
4912 }
4913
4914 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", 4914); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "mWindowListener" ")"); do { MOZ_CrashSequence
(__null, 4914); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4915 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)
4916 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)
;
4917
4918 if (GetDevice() &&
4919 (GetDevice()->GetMediaSource() == MediaSourceEnum::Camera)) {
4920 SetDeviceMuted(aMute);
4921 }
4922}
4923
4924void DeviceListener::MuteOrUnmuteMicrophone(bool aMute) {
4925 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", 4925); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4925); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4926
4927 if (mStopped) {
4928 return;
4929 }
4930
4931 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", 4931); AnnotateMozCrashReason
("MOZ_RELEASE_ASSERT" "(" "mWindowListener" ")"); do { MOZ_CrashSequence
(__null, 4931); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4932 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)
4933 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)
;
4934
4935 if (GetDevice() &&
4936 (GetDevice()->GetMediaSource() == MediaSourceEnum::Microphone)) {
4937 SetDeviceMuted(aMute);
4938 }
4939}
4940
4941bool DeviceListener::CapturingVideo() const {
4942 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", 4942); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4942); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4943 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4944 MediaEngineSource::IsVideo(GetDevice()->GetMediaSource()) &&
4945 (!GetDevice()->IsFake() ||
4946 Preferences::GetBool("media.navigator.permission.fake"));
4947}
4948
4949bool DeviceListener::CapturingAudio() const {
4950 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", 4950); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4950); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4951 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4952 MediaEngineSource::IsAudio(GetDevice()->GetMediaSource()) &&
4953 (!GetDevice()->IsFake() ||
4954 Preferences::GetBool("media.navigator.permission.fake"));
4955}
4956
4957CaptureState DeviceListener::CapturingSource(MediaSourceEnum aSource) const {
4958 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", 4958); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4958); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4959 if (GetDevice()->GetMediaSource() != aSource) {
4960 // This DeviceListener doesn't capture a matching source
4961 return CaptureState::Off;
4962 }
4963
4964 if (mDeviceState->mStopped) {
4965 // The source is a match but has been permanently stopped
4966 return CaptureState::Off;
4967 }
4968
4969 if ((aSource == MediaSourceEnum::Camera ||
4970 aSource == MediaSourceEnum::Microphone) &&
4971 GetDevice()->IsFake() &&
4972 !Preferences::GetBool("media.navigator.permission.fake")) {
4973 // Fake Camera and Microphone only count if there is no fake permission
4974 return CaptureState::Off;
4975 }
4976
4977 // Source is a match and is active and unmuted
4978
4979 if (mDeviceState->mDeviceEnabled && !mDeviceState->mDeviceMuted) {
4980 return CaptureState::Enabled;
4981 }
4982
4983 return CaptureState::Disabled;
4984}
4985
4986RefPtr<DeviceListener::DeviceListenerPromise> DeviceListener::ApplyConstraints(
4987 const MediaTrackConstraints& aConstraints, CallerType aCallerType) {
4988 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", 4988); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 4988); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4989
4990 if (mStopped || mDeviceState->mStopped) {
4991 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)
4992 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)
;
4993 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4994 }
4995
4996 MediaManager* mgr = MediaManager::GetIfExists();
4997 if (!mgr) {
4998 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4999 }
5000
5001 return InvokeAsync(
5002 mgr->mMediaThread, __func__,
5003 [device = mDeviceState->mDevice, aConstraints, prefs = mgr->mPrefs,
5004 aCallerType]() mutable -> RefPtr<DeviceListenerPromise> {
5005 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"
, 5005); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { MOZ_CrashSequence(__null, 5005); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5006 MediaManager* mgr = MediaManager::GetIfExists();
5007 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"
, 5007); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mgr"
")"); do { MOZ_CrashSequence(__null, 5007); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // Must exist while media thread is alive
5008 const char* badConstraint = nullptr;
5009 nsresult rv =
5010 device->Reconfigure(aConstraints, mgr->mPrefs, &badConstraint);
5011 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5012 if (rv == NS_ERROR_INVALID_ARG) {
5013 // Reconfigure failed due to constraints
5014 if (!badConstraint) {
5015 nsTArray<RefPtr<LocalMediaDevice>> devices;
5016 devices.AppendElement(device);
5017 badConstraint = MediaConstraintsHelper::SelectSettings(
5018 NormalizedConstraints(aConstraints), prefs, devices,
5019 aCallerType);
5020 }
5021 } else {
5022 // Unexpected. ApplyConstraints* cannot fail with any other error.
5023 badConstraint = "";
5024 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)
5025 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)
;
5026 }
5027
5028 return DeviceListenerPromise::CreateAndReject(
5029 MakeRefPtr<MediaMgrError>(
5030 MediaMgrError::Name::OverconstrainedError, "",
5031 NS_ConvertASCIItoUTF16(badConstraint)),
5032 __func__);
5033 }
5034 // Reconfigure was successful
5035 return DeviceListenerPromise::CreateAndResolve(false, __func__);
5036 });
5037}
5038
5039PrincipalHandle DeviceListener::GetPrincipalHandle() const {
5040 return mPrincipalHandle;
5041}
5042
5043void GetUserMediaWindowListener::StopSharing() {
5044 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"
, 5044); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5044); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5045
5046 for (auto& l : mActiveListeners.Clone()) {
5047 MediaSourceEnum source = l->GetDevice()->GetMediaSource();
5048 if (source == MediaSourceEnum::Screen ||
5049 source == MediaSourceEnum::Window ||
5050 source == MediaSourceEnum::AudioCapture ||
5051 source == MediaSourceEnum::Browser) {
5052 l->Stop();
5053 }
5054 }
5055}
5056
5057void GetUserMediaWindowListener::StopRawID(const nsString& removedDeviceID) {
5058 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"
, 5058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5058); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5059
5060 for (auto& l : mActiveListeners.Clone()) {
5061 if (removedDeviceID.Equals(l->GetDevice()->RawID())) {
5062 l->Stop();
5063 }
5064 }
5065}
5066
5067void GetUserMediaWindowListener::MuteOrUnmuteCameras(bool aMute) {
5068 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"
, 5068); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5068); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5069
5070 if (mCamerasAreMuted == aMute) {
5071 return;
5072 }
5073 mCamerasAreMuted = aMute;
5074
5075 for (auto& l : mActiveListeners.Clone()) {
5076 if (l->GetDevice()->Kind() == MediaDeviceKind::Videoinput) {
5077 l->MuteOrUnmuteCamera(aMute);
5078 }
5079 }
5080}
5081
5082void GetUserMediaWindowListener::MuteOrUnmuteMicrophones(bool aMute) {
5083 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"
, 5083); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { MOZ_CrashSequence
(__null, 5083); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5084
5085 if (mMicrophonesAreMuted == aMute) {
5086 return;
5087 }
5088 mMicrophonesAreMuted = aMute;
5089
5090 for (auto& l : mActiveListeners.Clone()) {
5091 if (l->GetDevice()->Kind() == MediaDeviceKind::Audioinput) {
5092 l->MuteOrUnmuteMicrophone(aMute);
5093 }
5094 }
5095}
5096
5097void GetUserMediaWindowListener::ChromeAffectingStateChanged() {
5098 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", 5098); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "NS_IsMainThread()" ")"); do { MOZ_CrashSequence
(__null, 5098); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5099
5100 // We wait until stable state before notifying chrome so chrome only does
5101 // one update if more updates happen in this event loop.
5102
5103 if (mChromeNotificationTaskPosted) {
5104 return;
5105 }
5106
5107 nsCOMPtr<nsIRunnable> runnable =
5108 NewRunnableMethod("GetUserMediaWindowListener::NotifyChrome", this,
5109 &GetUserMediaWindowListener::NotifyChrome);
5110 nsContentUtils::RunInStableState(runnable.forget());
5111 mChromeNotificationTaskPosted = true;
5112}
5113
5114void GetUserMediaWindowListener::NotifyChrome() {
5115 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"
, 5115); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mChromeNotificationTaskPosted"
")"); do { MOZ_CrashSequence(__null, 5115); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5116 mChromeNotificationTaskPosted = false;
5117
5118 NS_DispatchToMainThread(NS_NewRunnableFunction(
5119 "MediaManager::NotifyChrome", [windowID = mWindowID]() {
5120 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowID);
5121 if (!window) {
5122 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"
, 5122); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should have window" ")"); do { MOZ_CrashSequence
(__null, 5122); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
5123 return;
5124 }
5125
5126 nsresult rv = MediaManager::NotifyRecordingStatusChange(window);
5127 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5128 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"
, 5128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should be able to notify chrome"
")"); do { MOZ_CrashSequence(__null, 5128); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5129 return;
5130 }
5131 }));
5132}
5133
5134#undef LOG
5135
5136} // namespace mozilla