Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp
Warning:line 2873, 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 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_media2.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=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/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 /var/lib/jenkins/workspace/firefox-scan-build/dom/media -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/media/libsoundtouch/src -I /var/lib/jenkins/workspace/firefox-scan-build/caps -I /var/lib/jenkins/workspace/firefox-scan-build/docshell/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc -I /var/lib/jenkins/workspace/firefox-scan-build/layout/generic -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul -I /var/lib/jenkins/workspace/firefox-scan-build/media/libyuv/libyuv/include -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/content/tests/browser -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/common -I /var/lib/jenkins/workspace/firefox-scan-build/third_party/libwebrtc -I /var/lib/jenkins/workspace/firefox-scan-build/third_party/libwebrtc/third_party/abseil-cpp -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia/skia -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -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-deprecated-this-capture -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-error=attributes -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 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-09-22-115206-3586786-1 -x c++ Unified_cpp_dom_media2.cpp
1/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2/* vim: set ts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "MediaManager.h"
8
9#include "AudioCaptureTrack.h"
10#include "AudioDeviceInfo.h"
11#include "AudioStreamTrack.h"
12#include "CubebDeviceEnumerator.h"
13#include "CubebInputStream.h"
14#include "MediaTimer.h"
15#include "MediaTrackConstraints.h"
16#include "MediaTrackGraph.h"
17#include "MediaTrackListener.h"
18#include "VideoStreamTrack.h"
19#include "Tracing.h"
20#include "VideoUtils.h"
21#include "mozilla/Base64.h"
22#include "mozilla/EventTargetCapability.h"
23#include "mozilla/MozPromise.h"
24#include "mozilla/NullPrincipal.h"
25#include "mozilla/PeerIdentity.h"
26#include "mozilla/PermissionDelegateHandler.h"
27#include "mozilla/Sprintf.h"
28#include "mozilla/StaticPrefs_media.h"
29#include "mozilla/Telemetry.h"
30#include "mozilla/Types.h"
31#include "mozilla/dom/BindingDeclarations.h"
32#include "mozilla/dom/Document.h"
33#include "mozilla/dom/Element.h"
34#include "mozilla/dom/FeaturePolicyUtils.h"
35#include "mozilla/dom/File.h"
36#include "mozilla/dom/GetUserMediaRequestBinding.h"
37#include "mozilla/dom/MediaDeviceInfo.h"
38#include "mozilla/dom/MediaDevices.h"
39#include "mozilla/dom/MediaDevicesBinding.h"
40#include "mozilla/dom/MediaStreamBinding.h"
41#include "mozilla/dom/MediaStreamTrackBinding.h"
42#include "mozilla/dom/Promise.h"
43#include "mozilla/dom/UserActivation.h"
44#include "mozilla/dom/WindowContext.h"
45#include "mozilla/dom/WindowGlobalChild.h"
46#include "mozilla/ipc/BackgroundChild.h"
47#include "mozilla/ipc/PBackgroundChild.h"
48#include "mozilla/media/CamerasTypes.h"
49#include "mozilla/media/MediaChild.h"
50#include "mozilla/media/MediaTaskUtils.h"
51#include "nsAppDirectoryServiceDefs.h"
52#include "nsArray.h"
53#include "nsContentUtils.h"
54#include "nsGlobalWindowInner.h"
55#include "nsHashPropertyBag.h"
56#include "nsIEventTarget.h"
57#include "nsIPermissionManager.h"
58#include "nsIUUIDGenerator.h"
59#include "nsJSUtils.h"
60#include "nsNetCID.h"
61#include "nsNetUtil.h"
62#include "nsProxyRelease.h"
63#include "nspr.h"
64#include "nss.h"
65#include "pk11pub.h"
66
67/* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
68#include "MediaEngineFake.h"
69#include "MediaEngineSource.h"
70#if defined(MOZ_WEBRTC1)
71# include "MediaEngineWebRTC.h"
72# include "MediaEngineWebRTCAudio.h"
73# include "browser_logging/WebRtcLog.h"
74# include "modules/audio_processing/include/audio_processing.h"
75#endif
76
77#if defined(XP_WIN)
78# include <objbase.h>
79#endif
80
81// A specialization of nsMainThreadPtrHolder for
82// mozilla::dom::CallbackObjectHolder. See documentation for
83// nsMainThreadPtrHolder in nsProxyRelease.h. This specialization lets us avoid
84// wrapping the CallbackObjectHolder into a separate refcounted object.
85template <class WebIDLCallbackT, class XPCOMCallbackT>
86class nsMainThreadPtrHolder<
87 mozilla::dom::CallbackObjectHolder<WebIDLCallbackT, XPCOMCallbackT>>
88 final {
89 typedef mozilla::dom::CallbackObjectHolder<WebIDLCallbackT, XPCOMCallbackT>
90 Holder;
91
92 public:
93 nsMainThreadPtrHolder(const char* aName, Holder&& aHolder)
94 : mHolder(std::move(aHolder))
95#ifndef RELEASE_OR_BETA
96 ,
97 mName(aName)
98#endif
99 {
100 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 100); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 100; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
101 }
102
103 private:
104 // We can be released on any thread.
105 ~nsMainThreadPtrHolder() {
106 if (NS_IsMainThread()) {
107 mHolder.Reset();
108 } else if (mHolder.GetISupports()) {
109 nsCOMPtr<nsIEventTarget> target = do_GetMainThread();
110 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 110); AnnotateMozCrashReason("MOZ_ASSERT" "(" "target" ")")
; do { *((volatile int*)__null) = 110; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
111 NS_ProxyRelease(
112#ifdef RELEASE_OR_BETA
113 nullptr,
114#else
115 mName,
116#endif
117 target, mHolder.Forget());
118 }
119 }
120
121 public:
122 Holder* get() {
123 // Nobody should be touching the raw pointer off-main-thread.
124 if (MOZ_UNLIKELY(!NS_IsMainThread())(__builtin_expect(!!(!NS_IsMainThread()), 0))) {
125 NS_ERROR("Can't dereference nsMainThreadPtrHolder off main thread")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Can't dereference nsMainThreadPtrHolder off main thread"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 125); MOZ_PretendNoReturn(); } while (0)
;
126 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 126); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 126; __attribute__((nomerge)) ::abort(); } while
(false); } while (false)
;
127 }
128 return &mHolder;
129 }
130
131 bool operator!() const { return !mHolder; }
132
133 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
133; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 133
; __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:
134
135 private:
136 // Our holder.
137 Holder mHolder;
138
139#ifndef RELEASE_OR_BETA
140 const char* mName = nullptr;
141#endif
142
143 // Copy constructor and operator= not implemented. Once constructed, the
144 // holder is immutable.
145 Holder& operator=(const nsMainThreadPtrHolder& aOther) = delete;
146 nsMainThreadPtrHolder(const nsMainThreadPtrHolder& aOther) = delete;
147};
148
149namespace mozilla {
150
151LazyLogModule gMediaManagerLog("MediaManager");
152#define LOG(...) MOZ_LOG(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(moz_real_module
, LogLevel::Debug, __VA_ARGS__); } } while (0)
153
154class GetUserMediaStreamTask;
155class LocalTrackSource;
156class SelectAudioOutputTask;
157
158using camera::CamerasAccessStatus;
159using dom::BFCacheStatus;
160using dom::CallerType;
161using dom::ConstrainDOMStringParameters;
162using dom::ConstrainDoubleRange;
163using dom::ConstrainLongRange;
164using dom::DisplayMediaStreamConstraints;
165using dom::Document;
166using dom::Element;
167using dom::FeaturePolicyUtils;
168using dom::File;
169using dom::GetUserMediaRequest;
170using dom::MediaDeviceKind;
171using dom::MediaDevices;
172using dom::MediaSourceEnum;
173using dom::MediaStreamConstraints;
174using dom::MediaStreamError;
175using dom::MediaStreamTrack;
176using dom::MediaStreamTrackSource;
177using dom::MediaTrackCapabilities;
178using dom::MediaTrackConstraints;
179using dom::MediaTrackConstraintSet;
180using dom::MediaTrackSettings;
181using dom::OwningBooleanOrMediaTrackConstraints;
182using dom::OwningStringOrStringSequence;
183using dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters;
184using dom::Promise;
185using dom::Sequence;
186using dom::UserActivation;
187using dom::WindowGlobalChild;
188using ConstDeviceSetPromise = MediaManager::ConstDeviceSetPromise;
189using DeviceSetPromise = MediaManager::DeviceSetPromise;
190using LocalDevicePromise = MediaManager::LocalDevicePromise;
191using LocalDeviceSetPromise = MediaManager::LocalDeviceSetPromise;
192using LocalMediaDeviceSetRefCnt = MediaManager::LocalMediaDeviceSetRefCnt;
193using MediaDeviceSetRefCnt = MediaManager::MediaDeviceSetRefCnt;
194using media::NewRunnableFrom;
195using media::NewTaskFrom;
196using media::Refcountable;
197
198// Whether main thread actions of MediaManager shutdown (except for clearing
199// of sSingleton) have completed.
200static bool sHasMainThreadShutdown;
201
202struct DeviceState {
203 DeviceState(RefPtr<LocalMediaDevice> aDevice,
204 RefPtr<LocalTrackSource> aTrackSource, bool aOffWhileDisabled)
205 : mOffWhileDisabled(aOffWhileDisabled),
206 mDevice(std::move(aDevice)),
207 mTrackSource(std::move(aTrackSource)) {
208 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 208); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDevice" ")"
); do { *((volatile int*)__null) = 208; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
209 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 209); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTrackSource"
")"); do { *((volatile int*)__null) = 209; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
210 }
211
212 // true if we have stopped mDevice, this is a terminal state.
213 // MainThread only.
214 bool mStopped = false;
215
216 // true if mDevice is currently enabled.
217 // A device must be both enabled and unmuted to be turned on and capturing.
218 // MainThread only.
219 bool mDeviceEnabled = false;
220
221 // true if mDevice is currently muted.
222 // A device that is either muted or disabled is turned off and not capturing.
223 // MainThread only.
224 bool mDeviceMuted;
225
226 // true if the application has currently enabled mDevice.
227 // MainThread only.
228 bool mTrackEnabled = false;
229
230 // Time when the application last enabled mDevice.
231 // MainThread only.
232 TimeStamp mTrackEnabledTime;
233
234 // true if an operation to Start() or Stop() mDevice has been dispatched to
235 // the media thread and is not finished yet.
236 // MainThread only.
237 bool mOperationInProgress = false;
238
239 // true if we are allowed to turn off the underlying source while all tracks
240 // are disabled. Only affects disabling; always turns off on user-agent mute.
241 // MainThread only.
242 bool mOffWhileDisabled = false;
243
244 // Timer triggered by a MediaStreamTrackSource signaling that all tracks got
245 // disabled. When the timer fires we initiate Stop()ing mDevice.
246 // If set we allow dynamically stopping and starting mDevice.
247 // Any thread.
248 const RefPtr<MediaTimer> mDisableTimer = new MediaTimer();
249
250 // The underlying device we keep state for. Always non-null.
251 // Threadsafe access, but see method declarations for individual constraints.
252 const RefPtr<LocalMediaDevice> mDevice;
253
254 // The MediaStreamTrackSource for any tracks (original and clones) originating
255 // from this device. Always non-null. Threadsafe access, but see method
256 // declarations for individual constraints.
257 const RefPtr<LocalTrackSource> mTrackSource;
258};
259
260/**
261 * This mimics the capture state from nsIMediaManagerService.
262 */
263enum class CaptureState : uint16_t {
264 Off = nsIMediaManagerService::STATE_NOCAPTURE,
265 Enabled = nsIMediaManagerService::STATE_CAPTURE_ENABLED,
266 Disabled = nsIMediaManagerService::STATE_CAPTURE_DISABLED,
267};
268
269static CaptureState CombineCaptureState(CaptureState aFirst,
270 CaptureState aSecond) {
271 if (aFirst == CaptureState::Enabled || aSecond == CaptureState::Enabled) {
272 return CaptureState::Enabled;
273 }
274 if (aFirst == CaptureState::Disabled || aSecond == CaptureState::Disabled) {
275 return CaptureState::Disabled;
276 }
277 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aFirst == CaptureState::Off"
")"); do { *((volatile int*)__null) = 277; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
278 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSecond == CaptureState::Off"
")"); do { *((volatile int*)__null) = 278; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
279 return CaptureState::Off;
280}
281
282static uint16_t FromCaptureState(CaptureState aState) {
283 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 284); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
")"); do { *((volatile int*)__null) = 284; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
284 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 284); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aState == CaptureState::Off || aState == CaptureState::Enabled || aState == CaptureState::Disabled"
")"); do { *((volatile int*)__null) = 284; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
285 return static_cast<uint16_t>(aState);
286}
287
288void MediaManager::CallOnError(GetUserMediaErrorCallback& aCallback,
289 MediaStreamError& aError) {
290 aCallback.Call(aError);
291}
292
293void MediaManager::CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
294 DOMMediaStream& aStream) {
295 aCallback.Call(aStream);
296}
297
298enum class PersistentPermissionState : uint32_t {
299 Unknown = nsIPermissionManager::UNKNOWN_ACTION,
300 Allow = nsIPermissionManager::ALLOW_ACTION,
301 Deny = nsIPermissionManager::DENY_ACTION,
302 Prompt = nsIPermissionManager::PROMPT_ACTION,
303};
304
305static PersistentPermissionState CheckPermission(
306 PersistentPermissionState aPermission) {
307 switch (aPermission) {
308 case PersistentPermissionState::Unknown:
309 case PersistentPermissionState::Allow:
310 case PersistentPermissionState::Deny:
311 case PersistentPermissionState::Prompt:
312 return aPermission;
313 }
314 MOZ_CRASH("Unexpected permission value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected permission value"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 314); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected permission value"
")"); do { *((volatile int*)__null) = 314; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
315}
316
317struct WindowPersistentPermissionState {
318 PersistentPermissionState mCameraPermission;
319 PersistentPermissionState mMicrophonePermission;
320};
321
322static Result<WindowPersistentPermissionState, nsresult>
323GetPersistentPermissions(uint64_t aWindowId) {
324 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
325 if (NS_WARN_IF(!window)NS_warn_if_impl(!window, "!window", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 325)
|| NS_WARN_IF(!window->GetPrincipal())NS_warn_if_impl(!window->GetPrincipal(), "!window->GetPrincipal()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 325)
) {
326 return Err(NS_ERROR_INVALID_ARG);
327 }
328
329 Document* doc = window->GetExtantDoc();
330 if (NS_WARN_IF(!doc)NS_warn_if_impl(!doc, "!doc", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 330)
) {
331 return Err(NS_ERROR_INVALID_ARG);
332 }
333
334 nsIPrincipal* principal = window->GetPrincipal();
335 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 335)
) {
336 return Err(NS_ERROR_INVALID_ARG);
337 }
338
339 nsresult rv;
340 RefPtr<PermissionDelegateHandler> permDelegate =
341 doc->GetPermissionDelegateHandler();
342 if (NS_WARN_IF(!permDelegate)NS_warn_if_impl(!permDelegate, "!permDelegate", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 342)
) {
343 return Err(NS_ERROR_INVALID_ARG);
344 }
345
346 uint32_t audio = nsIPermissionManager::UNKNOWN_ACTION;
347 uint32_t video = nsIPermissionManager::UNKNOWN_ACTION;
348 {
349 rv = permDelegate->GetPermission("microphone"_ns, &audio, true);
350 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 350)
) {
351 return Err(rv);
352 }
353 rv = permDelegate->GetPermission("camera"_ns, &video, true);
354 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 354)
) {
355 return Err(rv);
356 }
357 }
358
359 return WindowPersistentPermissionState{
360 CheckPermission(static_cast<PersistentPermissionState>(video)),
361 CheckPermission(static_cast<PersistentPermissionState>(audio))};
362}
363
364/**
365 * DeviceListener has threadsafe refcounting for use across the main, media and
366 * MTG threads. But it has a non-threadsafe SupportsWeakPtr for WeakPtr usage
367 * only from main thread, to ensure that garbage- and cycle-collected objects
368 * don't hold a reference to it during late shutdown.
369 */
370class DeviceListener : public SupportsWeakPtr {
371 public:
372 typedef MozPromise<bool /* aIgnored */, RefPtr<MediaMgrError>, true>
373 DeviceListenerPromise;
374
375 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
376; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 376
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("DeviceListener")); if (count == 0) { ::mozilla::detail
::ProxyDeleteVoid( "ProxyDelete " "DeviceListener", ::mozilla
::GetMainThreadSerialEventTarget(), this, [](void* self) { delete
static_cast<DeviceListener*>(self); }); return 0; } return
count; } using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; public:
376 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
376; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 376
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("DeviceListener")); if (count == 0) { ::mozilla::detail
::ProxyDeleteVoid( "ProxyDelete " "DeviceListener", ::mozilla
::GetMainThreadSerialEventTarget(), this, [](void* self) { delete
static_cast<DeviceListener*>(self); }); return 0; } return
count; } using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; public:
377
378 DeviceListener();
379
380 /**
381 * Registers this device listener as belonging to the given window listener.
382 * Stop() must be called on registered DeviceListeners before destruction.
383 */
384 void Register(GetUserMediaWindowListener* aListener);
385
386 /**
387 * Marks this listener as active and creates the internal device state.
388 */
389 void Activate(RefPtr<LocalMediaDevice> aDevice,
390 RefPtr<LocalTrackSource> aTrackSource, bool aStartMuted);
391
392 /**
393 * Posts a task to initialize and start the associated device.
394 */
395 RefPtr<DeviceListenerPromise> InitializeAsync();
396
397 /**
398 * Posts a task to stop the device associated with this DeviceListener and
399 * notifies the associated window listener that a track was stopped.
400 *
401 * This will also clean up the weak reference to the associated window
402 * listener, and tell the window listener to remove its hard reference to this
403 * DeviceListener, so any caller will need to keep its own hard ref.
404 */
405 void Stop();
406
407 /**
408 * Gets the main thread MediaTrackSettings from the MediaEngineSource
409 * associated with aTrack.
410 */
411 void GetSettings(MediaTrackSettings& aOutSettings) const;
412
413 /**
414 * Gets the main thread MediaTrackCapabilities from the MediaEngineSource
415 * associated with aTrack.
416 */
417 void GetCapabilities(MediaTrackCapabilities& aOutCapabilities) const;
418
419 /**
420 * Posts a task to set the enabled state of the device associated with this
421 * DeviceListener to aEnabled and notifies the associated window listener that
422 * a track's state has changed.
423 *
424 * Turning the hardware off while the device is disabled is supported for:
425 * - Camera (enabled by default, controlled by pref
426 * "media.getusermedia.camera.off_while_disabled.enabled")
427 * - Microphone (disabled by default, controlled by pref
428 * "media.getusermedia.microphone.off_while_disabled.enabled")
429 * Screen-, app-, or windowsharing is not supported at this time.
430 *
431 * The behavior is also different between disabling and enabling a device.
432 * While enabling is immediate, disabling only happens after a delay.
433 * This is now defaulting to 3 seconds but can be overriden by prefs:
434 * - "media.getusermedia.camera.off_while_disabled.delay_ms" and
435 * - "media.getusermedia.microphone.off_while_disabled.delay_ms".
436 *
437 * The delay is in place to prevent misuse by malicious sites. If a track is
438 * re-enabled before the delay has passed, the device will not be touched
439 * until another disable followed by the full delay happens.
440 */
441 void SetDeviceEnabled(bool aEnabled);
442
443 /**
444 * Posts a task to set the muted state of the device associated with this
445 * DeviceListener to aMuted and notifies the associated window listener that a
446 * track's state has changed.
447 *
448 * Turning the hardware off while the device is muted is supported for:
449 * - Camera (enabled by default, controlled by pref
450 * "media.getusermedia.camera.off_while_disabled.enabled")
451 * - Microphone (disabled by default, controlled by pref
452 * "media.getusermedia.microphone.off_while_disabled.enabled")
453 * Screen-, app-, or windowsharing is not supported at this time.
454 */
455 void SetDeviceMuted(bool aMuted);
456
457 /**
458 * Mutes or unmutes the associated video device if it is a camera.
459 */
460 void MuteOrUnmuteCamera(bool aMute);
461 void MuteOrUnmuteMicrophone(bool aMute);
462
463 LocalMediaDevice* GetDevice() const {
464 return mDeviceState ? mDeviceState->mDevice.get() : nullptr;
465 }
466
467 bool Activated() const { return static_cast<bool>(mDeviceState); }
468
469 bool Stopped() const { return mStopped; }
470
471 bool CapturingVideo() const;
472
473 bool CapturingAudio() const;
474
475 CaptureState CapturingSource(MediaSourceEnum aSource) const;
476
477 RefPtr<DeviceListenerPromise> ApplyConstraints(
478 const MediaTrackConstraints& aConstraints, CallerType aCallerType);
479
480 PrincipalHandle GetPrincipalHandle() const;
481
482 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
483 size_t amount = aMallocSizeOf(this);
484 // Assume mPrincipalHandle refers to a principal owned elsewhere.
485 // DeviceState does not have support for memory accounting.
486 return amount;
487 }
488
489 private:
490 virtual ~DeviceListener() {
491 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStopped" ")"
); do { *((volatile int*)__null) = 491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
492 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mWindowListener"
")"); do { *((volatile int*)__null) = 492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
493 }
494
495 using DeviceOperationPromise =
496 MozPromise<nsresult, bool, /* IsExclusive = */ true>;
497
498 /**
499 * Posts a task to start or stop the device associated with aTrack, based on
500 * a passed-in boolean. Private method used by SetDeviceEnabled and
501 * SetDeviceMuted.
502 */
503 RefPtr<DeviceOperationPromise> UpdateDevice(bool aOn);
504
505 // true after this listener has had all devices stopped. MainThread only.
506 bool mStopped;
507
508 // never ever indirect off this; just for assertions
509 PRThread* mMainThreadCheck;
510
511 // Set in Register() on main thread, then read from any thread.
512 PrincipalHandle mPrincipalHandle;
513
514 // Weak pointer to the window listener that owns us. MainThread only.
515 GetUserMediaWindowListener* mWindowListener;
516
517 // Accessed from MediaTrackGraph thread, MediaManager thread, and MainThread
518 // No locking needed as it's set on Activate() and never assigned to again.
519 UniquePtr<DeviceState> mDeviceState;
520
521 MediaEventListener mCaptureEndedListener;
522};
523
524/**
525 * This class represents a WindowID and handles all MediaTrackListeners
526 * (here subclassed as DeviceListeners) used to feed GetUserMedia tracks.
527 * It proxies feedback from them into messages for browser chrome.
528 * The DeviceListeners are used to Start() and Stop() the underlying
529 * MediaEngineSource when MediaStreams are assigned and deassigned in content.
530 */
531class GetUserMediaWindowListener {
532 friend MediaManager;
533
534 public:
535 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
535; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 535
; __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:
536
537 // Create in an inactive state
538 GetUserMediaWindowListener(uint64_t aWindowID,
539 const PrincipalHandle& aPrincipalHandle)
540 : mWindowID(aWindowID),
541 mPrincipalHandle(aPrincipalHandle),
542 mChromeNotificationTaskPosted(false) {}
543
544 /**
545 * Registers an inactive gUM device listener for this WindowListener.
546 */
547 void Register(RefPtr<DeviceListener> aListener) {
548 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
549 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 549); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aListener" ")"
); do { *((volatile int*)__null) = 549; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
550 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 550); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aListener->Activated()"
")"); do { *((volatile int*)__null) = 550; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
551 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 551); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)"
") (" "Already registered" ")"); do { *((volatile int*)__null
) = 551; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
552 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 552); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "Already activated" ")"); do { *((volatile int*)__null
) = 552; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
553
554 aListener->Register(this);
555 mInactiveListeners.AppendElement(std::move(aListener));
556 }
557
558 /**
559 * Activates an already registered and inactive gUM device listener for this
560 * WindowListener.
561 */
562 void Activate(RefPtr<DeviceListener> aListener,
563 RefPtr<LocalMediaDevice> aDevice,
564 RefPtr<LocalTrackSource> aTrackSource) {
565 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 565; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
566 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 566); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aListener" ")"
); do { *((volatile int*)__null) = 566; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
567 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 567); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aListener->Activated()"
")"); do { *((volatile int*)__null) = 567; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
568 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Contains(aListener)"
") (" "Must be registered to activate" ")"); do { *((volatile
int*)__null) = 569; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
569 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Contains(aListener)"
") (" "Must be registered to activate" ")"); do { *((volatile
int*)__null) = 569; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
570 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "Already activated" ")"); do { *((volatile int*)__null
) = 570; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
571
572 bool muted = false;
573 if (aDevice->Kind() == MediaDeviceKind::Videoinput) {
574 muted = mCamerasAreMuted;
575 } else if (aDevice->Kind() == MediaDeviceKind::Audioinput) {
576 muted = mMicrophonesAreMuted;
577 } else {
578 MOZ_CRASH("Unexpected device kind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected device kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 578); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected device kind"
")"); do { *((volatile int*)__null) = 578; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
579 }
580
581 mInactiveListeners.RemoveElement(aListener);
582 aListener->Activate(std::move(aDevice), std::move(aTrackSource), muted);
583 mActiveListeners.AppendElement(std::move(aListener));
584 }
585
586 /**
587 * Removes all DeviceListeners from this window listener.
588 * Removes this window listener from the list of active windows, so callers
589 * need to make sure to hold a strong reference.
590 */
591 void RemoveAll() {
592 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 592); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 592; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
593
594 for (auto& l : mInactiveListeners.Clone()) {
595 Remove(l);
596 }
597 for (auto& l : mActiveListeners.Clone()) {
598 Remove(l);
599 }
600 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 600); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0"
")"); do { *((volatile int*)__null) = 600; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
601 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 601); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0"
")"); do { *((volatile int*)__null) = 601; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
602
603 MediaManager* mgr = MediaManager::GetIfExists();
604 if (!mgr) {
605 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 605); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MediaManager should stay until everything is removed" ")");
do { *((volatile int*)__null) = 605; __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
;
606 return;
607 }
608 GetUserMediaWindowListener* windowListener =
609 mgr->GetWindowListener(mWindowID);
610
611 if (!windowListener) {
612 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
613 auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
614 if (globalWindow) {
615 auto req = MakeRefPtr<GetUserMediaRequest>(
616 globalWindow, VoidString(), VoidString(),
617 UserActivation::IsHandlingUserInput());
618 obs->NotifyWhenScriptSafe(req, "recording-device-stopped", nullptr);
619 }
620 return;
621 }
622
623 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "windowListener == this"
") (" "There should only be one window listener per window ID"
")"); do { *((volatile int*)__null) = 624; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
624 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "windowListener == this"
") (" "There should only be one window listener per window ID"
")"); do { *((volatile int*)__null) = 624; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
625
626 LOG("GUMWindowListener %p removing windowID %" PRIu64"l" "u", this, mWindowID);
627 mgr->RemoveWindowID(mWindowID);
628 }
629
630 /**
631 * Removes a listener from our lists. Safe to call without holding a hard
632 * reference. That said, you'll still want to iterate on a copy of said lists,
633 * if you end up calling this method (or methods that may call this method) in
634 * the loop, to avoid inadvertently skipping members.
635 *
636 * For use only from GetUserMediaWindowListener and DeviceListener.
637 */
638 bool Remove(RefPtr<DeviceListener> aListener) {
639 // We refcount aListener on entry since we're going to proxy-release it
640 // below to prevent the refcount going to zero on callers who might be
641 // inside the listener, but operating without a hard reference to self.
642 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 642); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 642; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
643
644 if (!mInactiveListeners.RemoveElement(aListener) &&
645 !mActiveListeners.RemoveElement(aListener)) {
646 return false;
647 }
648 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 650; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
649 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 650; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
650 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInactiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 650; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
651 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 653); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 653; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
652 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 653); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 653; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
653 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 653); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mActiveListeners.Contains(aListener)"
") (" "A DeviceListener should only be once in one of " "mInactiveListeners and mActiveListeners"
")"); do { *((volatile int*)__null) = 653; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
654
655 LOG("GUMWindowListener %p stopping DeviceListener %p.", this,
656 aListener.get());
657 aListener->Stop();
658
659 if (LocalMediaDevice* removedDevice = aListener->GetDevice()) {
660 bool revokePermission = true;
661 nsString removedRawId;
662 nsString removedSourceType;
663 removedDevice->GetRawId(removedRawId);
664 removedDevice->GetMediaSource(removedSourceType);
665
666 for (const auto& l : mActiveListeners) {
667 if (LocalMediaDevice* device = l->GetDevice()) {
668 nsString rawId;
669 device->GetRawId(rawId);
670 if (removedRawId.Equals(rawId)) {
671 revokePermission = false;
672 break;
673 }
674 }
675 }
676
677 if (revokePermission) {
678 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
679 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
680 auto req = MakeRefPtr<GetUserMediaRequest>(
681 window, removedRawId, removedSourceType,
682 UserActivation::IsHandlingUserInput());
683 obs->NotifyWhenScriptSafe(req, "recording-device-stopped", nullptr);
684 }
685 }
686
687 if (mInactiveListeners.Length() == 0 && mActiveListeners.Length() == 0) {
688 LOG("GUMWindowListener %p Removed last DeviceListener. Cleaning up.",
689 this);
690 RemoveAll();
691 }
692
693 nsCOMPtr<nsIEventTarget> mainTarget = do_GetMainThread();
694 // To allow being invoked by callers not holding a strong reference to self,
695 // hold the listener alive until the stack has unwound, by always
696 // dispatching a runnable (aAlwaysProxy = true)
697 NS_ProxyRelease(__func__, mainTarget, aListener.forget(), true);
698 return true;
699 }
700
701 /**
702 * Stops all screen/window/audioCapture sharing, but not camera or microphone.
703 */
704 void StopSharing();
705
706 void StopRawID(const nsString& removedDeviceID);
707
708 void MuteOrUnmuteCameras(bool aMute);
709 void MuteOrUnmuteMicrophones(bool aMute);
710
711 /**
712 * Called by one of our DeviceListeners when one of its tracks has changed so
713 * that chrome state is affected.
714 * Schedules an event for the next stable state to update chrome.
715 */
716 void ChromeAffectingStateChanged();
717
718 /**
719 * Called in stable state to send a notification to update chrome.
720 */
721 void NotifyChrome();
722
723 bool CapturingVideo() const {
724 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 724; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
725 for (auto& l : mActiveListeners) {
726 if (l->CapturingVideo()) {
727 return true;
728 }
729 }
730 return false;
731 }
732
733 bool CapturingAudio() const {
734 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 734); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 734; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
735 for (auto& l : mActiveListeners) {
736 if (l->CapturingAudio()) {
737 return true;
738 }
739 }
740 return false;
741 }
742
743 CaptureState CapturingSource(MediaSourceEnum aSource) const {
744 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 744); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 744; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
745 CaptureState result = CaptureState::Off;
746 for (auto& l : mActiveListeners) {
747 result = CombineCaptureState(result, l->CapturingSource(aSource));
748 }
749 return result;
750 }
751
752 RefPtr<LocalMediaDeviceSetRefCnt> GetDevices() {
753 RefPtr devices = new LocalMediaDeviceSetRefCnt();
754 for (auto& l : mActiveListeners) {
755 devices->AppendElement(l->GetDevice());
756 }
757 return devices;
758 }
759
760 uint64_t WindowID() const { return mWindowID; }
761
762 PrincipalHandle GetPrincipalHandle() const { return mPrincipalHandle; }
763
764 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
765 size_t amount = aMallocSizeOf(this);
766 // Assume mPrincipalHandle refers to a principal owned elsewhere.
767 amount += mInactiveListeners.ShallowSizeOfExcludingThis(aMallocSizeOf);
768 for (const RefPtr<DeviceListener>& listener : mInactiveListeners) {
769 amount += listener->SizeOfIncludingThis(aMallocSizeOf);
770 }
771 amount += mActiveListeners.ShallowSizeOfExcludingThis(aMallocSizeOf);
772 for (const RefPtr<DeviceListener>& listener : mActiveListeners) {
773 amount += listener->SizeOfIncludingThis(aMallocSizeOf);
774 }
775 return amount;
776 }
777
778 private:
779 ~GetUserMediaWindowListener() {
780 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0"
") (" "Inactive listeners should already be removed" ")"); do
{ *((volatile int*)__null) = 781; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
781 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInactiveListeners.Length() == 0"
") (" "Inactive listeners should already be removed" ")"); do
{ *((volatile int*)__null) = 781; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
782 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 783); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0"
") (" "Active listeners should already be removed" ")"); do {
*((volatile int*)__null) = 783; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
783 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 783); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActiveListeners.Length() == 0"
") (" "Active listeners should already be removed" ")"); do {
*((volatile int*)__null) = 783; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
784 }
785
786 uint64_t mWindowID;
787 const PrincipalHandle mPrincipalHandle;
788
789 // true if we have scheduled a task to notify chrome in the next stable state.
790 // The task will reset this to false. MainThread only.
791 bool mChromeNotificationTaskPosted;
792
793 nsTArray<RefPtr<DeviceListener>> mInactiveListeners;
794 nsTArray<RefPtr<DeviceListener>> mActiveListeners;
795
796 // Whether camera and microphone access in this window are currently
797 // User Agent (UA) muted. When true, new and cloned tracks must start
798 // out muted, to avoid JS circumventing UA mute. Per-camera and
799 // per-microphone UA muting is not supported.
800 bool mCamerasAreMuted = false;
801 bool mMicrophonesAreMuted = false;
802};
803
804class LocalTrackSource : public MediaStreamTrackSource {
805 public:
806 LocalTrackSource(nsIPrincipal* aPrincipal, const nsString& aLabel,
807 const RefPtr<DeviceListener>& aListener,
808 MediaSourceEnum aSource, MediaTrack* aTrack,
809 RefPtr<PeerIdentity> aPeerIdentity,
810 TrackingId aTrackingId = TrackingId())
811 : MediaStreamTrackSource(aPrincipal, aLabel, std::move(aTrackingId)),
812 mSource(aSource),
813 mTrack(aTrack),
814 mPeerIdentity(std::move(aPeerIdentity)),
815 mListener(aListener.get()) {}
816
817 MediaSourceEnum GetMediaSource() const override { return mSource; }
818
819 const PeerIdentity* GetPeerIdentity() const override { return mPeerIdentity; }
820
821 RefPtr<MediaStreamTrackSource::ApplyConstraintsPromise> ApplyConstraints(
822 const MediaTrackConstraints& aConstraints,
823 CallerType aCallerType) override {
824 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 824; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
825 if (sHasMainThreadShutdown || !mListener) {
826 // Track has been stopped, or we are in shutdown. In either case
827 // there's no observable outcome, so pretend we succeeded.
828 return MediaStreamTrackSource::ApplyConstraintsPromise::CreateAndResolve(
829 false, __func__);
830 }
831 return mListener->ApplyConstraints(aConstraints, aCallerType);
832 }
833
834 void GetSettings(MediaTrackSettings& aOutSettings) override {
835 if (mListener) {
836 mListener->GetSettings(aOutSettings);
837 }
838 }
839
840 void GetCapabilities(MediaTrackCapabilities& aOutCapabilities) override {
841 if (mListener) {
842 mListener->GetCapabilities(aOutCapabilities);
843 }
844 }
845
846 void Stop() override {
847 if (mListener) {
848 mListener->Stop();
849 mListener = nullptr;
850 }
851 if (!mTrack->IsDestroyed()) {
852 mTrack->Destroy();
853 }
854 }
855
856 void Disable() override {
857 if (mListener) {
858 mListener->SetDeviceEnabled(false);
859 }
860 }
861
862 void Enable() override {
863 if (mListener) {
864 mListener->SetDeviceEnabled(true);
865 }
866 }
867
868 void Mute() {
869 MutedChanged(true);
870 mTrack->SetDisabledTrackMode(DisabledTrackMode::SILENCE_BLACK);
871 }
872
873 void Unmute() {
874 MutedChanged(false);
875 mTrack->SetDisabledTrackMode(DisabledTrackMode::ENABLED);
876 }
877
878 const MediaSourceEnum mSource;
879 const RefPtr<MediaTrack> mTrack;
880 const RefPtr<const PeerIdentity> mPeerIdentity;
881
882 protected:
883 ~LocalTrackSource() {
884 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 884); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 884; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
885 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 885); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTrack->IsDestroyed()"
")"); do { *((volatile int*)__null) = 885; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
886 }
887
888 // This is a weak pointer to avoid having the DeviceListener (which may
889 // have references to threads and threadpools) kept alive by DOM-objects
890 // that may have ref-cycles and thus are released very late during
891 // shutdown, even after xpcom-shutdown-threads. See bug 1351655 for what
892 // can happen.
893 WeakPtr<DeviceListener> mListener;
894};
895
896class AudioCaptureTrackSource : public LocalTrackSource {
897 public:
898 AudioCaptureTrackSource(nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow,
899 const nsString& aLabel,
900 AudioCaptureTrack* aAudioCaptureTrack,
901 RefPtr<PeerIdentity> aPeerIdentity)
902 : LocalTrackSource(aPrincipal, aLabel, nullptr,
903 MediaSourceEnum::AudioCapture, aAudioCaptureTrack,
904 std::move(aPeerIdentity)),
905 mWindow(aWindow),
906 mAudioCaptureTrack(aAudioCaptureTrack) {
907 mAudioCaptureTrack->Start();
908 mAudioCaptureTrack->Graph()->RegisterCaptureTrackForWindow(
909 mWindow->WindowID(), mAudioCaptureTrack);
910 mWindow->SetAudioCapture(true);
911 }
912
913 void Stop() override {
914 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 914); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 914; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
915 if (!mAudioCaptureTrack->IsDestroyed()) {
916 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 916); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { *((volatile int*)__null) = 916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
917 mWindow->SetAudioCapture(false);
918 mAudioCaptureTrack->Graph()->UnregisterCaptureTrackForWindow(
919 mWindow->WindowID());
920 mWindow = nullptr;
921 }
922 // LocalTrackSource destroys the track.
923 LocalTrackSource::Stop();
924 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 924); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudioCaptureTrack->IsDestroyed()"
")"); do { *((volatile int*)__null) = 924; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
925 }
926
927 ProcessedMediaTrack* InputTrack() const { return mAudioCaptureTrack.get(); }
928
929 protected:
930 ~AudioCaptureTrackSource() {
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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 931; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
932 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 932); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudioCaptureTrack->IsDestroyed()"
")"); do { *((volatile int*)__null) = 932; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
933 }
934
935 RefPtr<nsPIDOMWindowInner> mWindow;
936 const RefPtr<AudioCaptureTrack> mAudioCaptureTrack;
937};
938
939/**
940 * nsIMediaDevice implementation.
941 */
942NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
942; __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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"LocalMediaDevice\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 942; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 942
; __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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"LocalMediaDevice\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 942; __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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 942); 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((sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
943
944MediaDevice::MediaDevice(MediaEngine* aEngine, MediaSourceEnum aMediaSource,
945 const nsString& aRawName, const nsString& aRawID,
946 const nsString& aRawGroupID, IsScary aIsScary,
947 const OsPromptable canRequestOsLevelPrompt,
948 const IsPlaceholder aIsPlaceholder)
949 : mEngine(aEngine),
950 mAudioDeviceInfo(nullptr),
951 mMediaSource(aMediaSource),
952 mKind(MediaEngineSource::IsVideo(aMediaSource)
953 ? MediaDeviceKind::Videoinput
954 : MediaDeviceKind::Audioinput),
955 mScary(aIsScary == IsScary::Yes),
956 mCanRequestOsLevelPrompt(canRequestOsLevelPrompt == OsPromptable::Yes),
957 mIsFake(mEngine->IsFake()),
958 mIsPlaceholder(aIsPlaceholder == IsPlaceholder::Yes),
959 mType(NS_ConvertASCIItoUTF16(dom::GetEnumString(mKind))),
960 mRawID(aRawID),
961 mRawGroupID(aRawGroupID),
962 mRawName(aRawName) {
963 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mEngine" ")"
); do { *((volatile int*)__null) = 963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
964}
965
966MediaDevice::MediaDevice(MediaEngine* aEngine,
967 const RefPtr<AudioDeviceInfo>& aAudioDeviceInfo,
968 const nsString& aRawID)
969 : mEngine(aEngine),
970 mAudioDeviceInfo(aAudioDeviceInfo),
971 mMediaSource(mAudioDeviceInfo->Type() == AudioDeviceInfo::TYPE_INPUT
972 ? MediaSourceEnum::Microphone
973 : MediaSourceEnum::Other),
974 mKind(mMediaSource == MediaSourceEnum::Microphone
975 ? MediaDeviceKind::Audioinput
976 : MediaDeviceKind::Audiooutput),
977 mScary(false),
978 mCanRequestOsLevelPrompt(false),
979 mIsFake(false),
980 mIsPlaceholder(false),
981 mType(NS_ConvertASCIItoUTF16(dom::GetEnumString(mKind))),
982 mRawID(aRawID),
983 mRawGroupID(mAudioDeviceInfo->GroupID()),
984 mRawName(mAudioDeviceInfo->Name()) {}
985
986/* static */
987RefPtr<MediaDevice> MediaDevice::CopyWithNewRawGroupId(
988 const RefPtr<MediaDevice>& aOther, const nsString& aRawGroupID) {
989 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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 989); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aOther->mAudioDeviceInfo"
") (" "device not supported" ")"); do { *((volatile int*)__null
) = 989; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
990 return new MediaDevice(aOther->mEngine, aOther->mMediaSource,
991 aOther->mRawName, aOther->mRawID, aRawGroupID,
992 IsScary(aOther->mScary),
993 OsPromptable(aOther->mCanRequestOsLevelPrompt),
994 IsPlaceholder(aOther->mIsPlaceholder));
995}
996
997MediaDevice::~MediaDevice() = default;
998
999LocalMediaDevice::LocalMediaDevice(RefPtr<const MediaDevice> aRawDevice,
1000 const nsString& aID,
1001 const nsString& aGroupID,
1002 const nsString& aName)
1003 : mRawDevice(std::move(aRawDevice)),
1004 mName(aName),
1005 mID(aID),
1006 mGroupID(aGroupID) {
1007 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRawDevice"
")"); do { *((volatile int*)__null) = 1007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1008}
1009
1010/**
1011 * Helper functions that implement the constraints algorithm from
1012 * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
1013 */
1014
1015/* static */
1016bool LocalMediaDevice::StringsContain(
1017 const OwningStringOrStringSequence& aStrings, nsString aN) {
1018 return aStrings.IsString() ? aStrings.GetAsString() == aN
1019 : aStrings.GetAsStringSequence().Contains(aN);
1020}
1021
1022/* static */
1023uint32_t LocalMediaDevice::FitnessDistance(
1024 nsString aN, const ConstrainDOMStringParameters& aParams) {
1025 if (aParams.mExact.WasPassed() &&
1026 !StringsContain(aParams.mExact.Value(), aN)) {
1027 return UINT32_MAX(4294967295U);
1028 }
1029 if (aParams.mIdeal.WasPassed() &&
1030 !StringsContain(aParams.mIdeal.Value(), aN)) {
1031 return 1;
1032 }
1033 return 0;
1034}
1035
1036// Binding code doesn't templatize well...
1037
1038/* static */
1039uint32_t LocalMediaDevice::FitnessDistance(
1040 nsString aN,
1041 const OwningStringOrStringSequenceOrConstrainDOMStringParameters&
1042 aConstraint) {
1043 if (aConstraint.IsString()) {
1044 ConstrainDOMStringParameters params;
1045 params.mIdeal.Construct();
1046 params.mIdeal.Value().SetAsString() = aConstraint.GetAsString();
1047 return FitnessDistance(aN, params);
1048 } else if (aConstraint.IsStringSequence()) {
1049 ConstrainDOMStringParameters params;
1050 params.mIdeal.Construct();
1051 params.mIdeal.Value().SetAsStringSequence() =
1052 aConstraint.GetAsStringSequence();
1053 return FitnessDistance(aN, params);
1054 } else {
1055 return FitnessDistance(aN, aConstraint.GetAsConstrainDOMStringParameters());
1056 }
1057}
1058
1059uint32_t LocalMediaDevice::GetBestFitnessDistance(
1060 const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
1061 CallerType aCallerType) {
1062 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1062); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1062; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1063 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1063); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetMediaSource() != MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 1063; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1064
1065 bool isChrome = aCallerType == CallerType::System;
1066 const nsString& id = isChrome ? RawID() : mID;
1067 auto type = GetMediaSource();
1068 uint64_t distance = 0;
1069 if (!aConstraintSets.IsEmpty()) {
1070 if (isChrome /* For the screen/window sharing preview */ ||
1071 type == MediaSourceEnum::Camera ||
1072 type == MediaSourceEnum::Microphone) {
1073 distance += uint64_t(MediaConstraintsHelper::FitnessDistance(
1074 Some(id), aConstraintSets[0]->mDeviceId)) +
1075 uint64_t(MediaConstraintsHelper::FitnessDistance(
1076 Some(mGroupID), aConstraintSets[0]->mGroupId));
1077 }
1078 }
1079 if (distance < UINT32_MAX(4294967295U)) {
1080 // Forward request to underlying object to interrogate per-mode
1081 // capabilities.
1082 distance += Source()->GetBestFitnessDistance(aConstraintSets);
1083 }
1084 return std::min<uint64_t>(distance, UINT32_MAX(4294967295U));
1085}
1086
1087NS_IMETHODIMPnsresult
1088LocalMediaDevice::GetRawName(nsAString& aName) {
1089 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1090 aName.Assign(mRawDevice->mRawName);
1091 return NS_OK;
1092}
1093
1094NS_IMETHODIMPnsresult
1095LocalMediaDevice::GetType(nsAString& aType) {
1096 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1096); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1096; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1097 aType.Assign(mRawDevice->mType);
1098 return NS_OK;
1099}
1100
1101NS_IMETHODIMPnsresult
1102LocalMediaDevice::GetRawId(nsAString& aID) {
1103 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1103); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1103; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1104 aID.Assign(RawID());
1105 return NS_OK;
1106}
1107
1108NS_IMETHODIMPnsresult
1109LocalMediaDevice::GetId(nsAString& aID) {
1110 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1110); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1110; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1111 aID.Assign(mID);
1112 return NS_OK;
1113}
1114
1115NS_IMETHODIMPnsresult
1116LocalMediaDevice::GetScary(bool* aScary) {
1117 *aScary = mRawDevice->mScary;
1118 return NS_OK;
1119}
1120
1121NS_IMETHODIMPnsresult
1122LocalMediaDevice::GetCanRequestOsLevelPrompt(bool* aCanRequestOsLevelPrompt) {
1123 *aCanRequestOsLevelPrompt = mRawDevice->mCanRequestOsLevelPrompt;
1124 return NS_OK;
1125}
1126
1127void LocalMediaDevice::GetSettings(MediaTrackSettings& aOutSettings) {
1128 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1128; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1129 Source()->GetSettings(aOutSettings);
1130}
1131
1132void LocalMediaDevice::GetCapabilities(
1133 MediaTrackCapabilities& aOutCapabilities) {
1134 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1134; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1135 Source()->GetCapabilities(aOutCapabilities);
1136}
1137
1138MediaEngineSource* LocalMediaDevice::Source() {
1139 if (!mSource) {
1140 mSource = mRawDevice->mEngine->CreateSource(mRawDevice);
1141 }
1142 return mSource;
1143}
1144
1145const TrackingId& LocalMediaDevice::GetTrackingId() const {
1146 return mSource->GetTrackingId();
1147}
1148
1149// Threadsafe since mKind and mSource are const.
1150NS_IMETHODIMPnsresult
1151LocalMediaDevice::GetMediaSource(nsAString& aMediaSource) {
1152 if (Kind() == MediaDeviceKind::Audiooutput) {
1153 aMediaSource.Truncate();
1154 } else {
1155 aMediaSource.AssignASCII(dom::GetEnumString(GetMediaSource()));
1156 }
1157 return NS_OK;
1158}
1159
1160nsresult LocalMediaDevice::Allocate(const MediaTrackConstraints& aConstraints,
1161 const MediaEnginePrefs& aPrefs,
1162 uint64_t aWindowID,
1163 const char** aOutBadConstraint) {
1164 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1164); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1164; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1165
1166 // Mock failure for automated tests.
1167 if (IsFake() && aConstraints.mDeviceId.WasPassed() &&
1168 aConstraints.mDeviceId.Value().IsString() &&
1169 aConstraints.mDeviceId.Value().GetAsString().EqualsASCII("bad device")) {
1170 return NS_ERROR_FAILURE;
1171 }
1172
1173 return Source()->Allocate(aConstraints, aPrefs, aWindowID, aOutBadConstraint);
1174}
1175
1176void LocalMediaDevice::SetTrack(const RefPtr<MediaTrack>& aTrack,
1177 const PrincipalHandle& aPrincipalHandle) {
1178 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1178); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1178; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1179 Source()->SetTrack(aTrack, aPrincipalHandle);
1180}
1181
1182nsresult LocalMediaDevice::Start() {
1183 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1183); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1183; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1184 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Source()" ")"
); do { *((volatile int*)__null) = 1184; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1185 return Source()->Start();
1186}
1187
1188nsresult LocalMediaDevice::Reconfigure(
1189 const MediaTrackConstraints& aConstraints, const MediaEnginePrefs& aPrefs,
1190 const char** aOutBadConstraint) {
1191 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1191); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1191; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1192 auto type = GetMediaSource();
1193 if (type == MediaSourceEnum::Camera || type == MediaSourceEnum::Microphone) {
1194 NormalizedConstraints c(aConstraints);
1195 if (MediaConstraintsHelper::FitnessDistance(Some(mID), c.mDeviceId) ==
1196 UINT32_MAX(4294967295U)) {
1197 *aOutBadConstraint = "deviceId";
1198 return NS_ERROR_INVALID_ARG;
1199 }
1200 if (MediaConstraintsHelper::FitnessDistance(Some(mGroupID), c.mGroupId) ==
1201 UINT32_MAX(4294967295U)) {
1202 *aOutBadConstraint = "groupId";
1203 return NS_ERROR_INVALID_ARG;
1204 }
1205 }
1206 return Source()->Reconfigure(aConstraints, aPrefs, aOutBadConstraint);
1207}
1208
1209nsresult LocalMediaDevice::FocusOnSelectedSource() {
1210 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1210); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1210; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1211 return Source()->FocusOnSelectedSource();
1212}
1213
1214nsresult LocalMediaDevice::Stop() {
1215 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1215); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1215; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1216 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1216); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSource" ")"
); do { *((volatile int*)__null) = 1216; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1217 return mSource->Stop();
1218}
1219
1220nsresult LocalMediaDevice::Deallocate() {
1221 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1221); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1221; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1222 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1222); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSource" ")"
); do { *((volatile int*)__null) = 1222; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1223 return mSource->Deallocate();
1224}
1225
1226MediaSourceEnum MediaDevice::GetMediaSource() const { return mMediaSource; }
1227
1228static const MediaTrackConstraints& GetInvariant(
1229 const OwningBooleanOrMediaTrackConstraints& aUnion) {
1230 static const MediaTrackConstraints empty;
1231 return aUnion.IsMediaTrackConstraints() ? aUnion.GetAsMediaTrackConstraints()
1232 : empty;
1233}
1234
1235// Source getter returning full list
1236
1237static void GetMediaDevices(MediaEngine* aEngine, MediaSourceEnum aSrcType,
1238 MediaManager::MediaDeviceSet& aResult,
1239 const char* aMediaDeviceName = nullptr) {
1240 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 1240; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1241
1242 LOG("%s: aEngine=%p, aSrcType=%" PRIu8"u" ", aMediaDeviceName=%s", __func__,
1243 aEngine, static_cast<uint8_t>(aSrcType),
1244 aMediaDeviceName ? aMediaDeviceName : "null");
1245 nsTArray<RefPtr<MediaDevice>> devices;
1246 aEngine->EnumerateDevices(aSrcType, MediaSinkEnum::Other, &devices);
1247
1248 /*
1249 * We're allowing multiple tabs to access the same camera for parity
1250 * with Chrome. See bug 811757 for some of the issues surrounding
1251 * this decision. To disallow, we'd filter by IsAvailable() as we used
1252 * to.
1253 */
1254 if (aMediaDeviceName && *aMediaDeviceName) {
1255 for (auto& device : devices) {
1256 if (device->mRawName.EqualsASCII(aMediaDeviceName)) {
1257 aResult.AppendElement(device);
1258 LOG("%s: found aMediaDeviceName=%s", __func__, aMediaDeviceName);
1259 break;
1260 }
1261 }
1262 } else {
1263 aResult = std::move(devices);
1264 if (MOZ_LOG_TEST(gMediaManagerLog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gMediaManagerLog
, mozilla::LogLevel::Debug)), 0))
) {
1265 for (auto& device : aResult) {
1266 LOG("%s: appending device=%s", __func__,
1267 NS_ConvertUTF16toUTF8(device->mRawName).get());
1268 }
1269 }
1270 }
1271}
1272
1273RefPtr<LocalDeviceSetPromise> MediaManager::SelectSettings(
1274 const MediaStreamConstraints& aConstraints, CallerType aCallerType,
1275 RefPtr<LocalMediaDeviceSetRefCnt> aDevices) {
1276 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1276; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1277
1278 // Algorithm accesses device capabilities code and must run on media thread.
1279 // Modifies passed-in aDevices.
1280
1281 return MediaManager::Dispatch<LocalDeviceSetPromise>(
1282 __func__, [aConstraints, devices = std::move(aDevices),
1283 aCallerType](MozPromiseHolder<LocalDeviceSetPromise>& holder) {
1284 auto& devicesRef = *devices;
1285
1286 // Since the advanced part of the constraints algorithm needs to know
1287 // when a candidate set is overconstrained (zero members), we must split
1288 // up the list into videos and audios, and put it back together again at
1289 // the end.
1290
1291 nsTArray<RefPtr<LocalMediaDevice>> videos;
1292 nsTArray<RefPtr<LocalMediaDevice>> audios;
1293
1294 for (const auto& device : devicesRef) {
1295 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
")"); do { *((volatile int*)__null) = 1296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1296 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "device->Kind() == MediaDeviceKind::Videoinput || device->Kind() == MediaDeviceKind::Audioinput"
")"); do { *((volatile int*)__null) = 1296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1297 if (device->Kind() == MediaDeviceKind::Videoinput) {
1298 videos.AppendElement(device);
1299 } else if (device->Kind() == MediaDeviceKind::Audioinput) {
1300 audios.AppendElement(device);
1301 }
1302 }
1303 devicesRef.Clear();
1304 const char* badConstraint = nullptr;
1305 bool needVideo = IsOn(aConstraints.mVideo);
1306 bool needAudio = IsOn(aConstraints.mAudio);
1307
1308 if (needVideo && videos.Length()) {
1309 badConstraint = MediaConstraintsHelper::SelectSettings(
1310 NormalizedConstraints(GetInvariant(aConstraints.mVideo)), videos,
1311 aCallerType);
1312 }
1313 if (!badConstraint && needAudio && audios.Length()) {
1314 badConstraint = MediaConstraintsHelper::SelectSettings(
1315 NormalizedConstraints(GetInvariant(aConstraints.mAudio)), audios,
1316 aCallerType);
1317 }
1318 if (badConstraint) {
1319 LOG("SelectSettings: bad constraint found! Calling error handler!");
1320 nsString constraint;
1321 constraint.AssignASCII(badConstraint);
1322 holder.Reject(
1323 new MediaMgrError(MediaMgrError::Name::OverconstrainedError, "",
1324 constraint),
1325 __func__);
1326 return;
1327 }
1328 if (!needVideo == !videos.Length() && !needAudio == !audios.Length()) {
1329 for (auto& video : videos) {
1330 devicesRef.AppendElement(video);
1331 }
1332 for (auto& audio : audios) {
1333 devicesRef.AppendElement(audio);
1334 }
1335 }
1336 holder.Resolve(devices, __func__);
1337 });
1338}
1339
1340/**
1341 * Describes a requested task that handles response from the UI and sends
1342 * results back to the DOM.
1343 */
1344class GetUserMediaTask {
1345 public:
1346 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1346; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1346
; __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:
1347 GetUserMediaTask(uint64_t aWindowID, const ipc::PrincipalInfo& aPrincipalInfo,
1348 CallerType aCallerType)
1349 : mPrincipalInfo(aPrincipalInfo),
1350 mWindowID(aWindowID),
1351 mCallerType(aCallerType) {}
1352
1353 virtual void Denied(MediaMgrError::Name aName,
1354 const nsCString& aMessage = ""_ns) = 0;
1355
1356 virtual GetUserMediaStreamTask* AsGetUserMediaStreamTask() { return nullptr; }
1357 virtual SelectAudioOutputTask* AsSelectAudioOutputTask() { return nullptr; }
1358
1359 uint64_t GetWindowID() const { return mWindowID; }
1360 enum CallerType CallerType() const { return mCallerType; }
1361
1362 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
1363 size_t amount = aMallocSizeOf(this);
1364 // Assume mWindowListener is owned by MediaManager.
1365 // Assume mAudioDeviceListener and mVideoDeviceListener are owned by
1366 // mWindowListener.
1367 // Assume PrincipalInfo string buffers are shared.
1368 // Member types without support for accounting of pointees:
1369 // MozPromiseHolder, RefPtr<LocalMediaDevice>.
1370 // We don't have a good way to account for lambda captures for MozPromise
1371 // callbacks.
1372 return amount;
1373 }
1374
1375 protected:
1376 virtual ~GetUserMediaTask() = default;
1377
1378 // Call GetPrincipalKey again, if not private browing, this time with
1379 // persist = true, to promote deviceIds to persistent, in case they're not
1380 // already. Fire'n'forget.
1381 void PersistPrincipalKey() {
1382 if (IsPrincipalInfoPrivate(mPrincipalInfo)) {
1383 return;
1384 }
1385 media::GetPrincipalKey(mPrincipalInfo, true)
1386 ->Then(
1387 GetCurrentSerialEventTarget(), __func__,
1388 [](const media::PrincipalKeyPromise::ResolveOrRejectValue& aValue) {
1389 if (aValue.IsReject()) {
1390 LOG("Failed get Principal key. Persisting of deviceIds "
1391 "will be broken");
1392 }
1393 });
1394 }
1395
1396 private:
1397 // Thread-safe (object) principal of Window with ID mWindowID
1398 const ipc::PrincipalInfo mPrincipalInfo;
1399
1400 protected:
1401 // The ID of the not-necessarily-toplevel inner Window relevant global
1402 // object of the MediaDevices on which getUserMedia() was called
1403 const uint64_t mWindowID;
1404 // Whether the JS caller of getUserMedia() has system (subject) principal
1405 const enum CallerType mCallerType;
1406};
1407
1408/**
1409 * Describes a requested task that handles response from the UI to a
1410 * getUserMedia() request and sends results back to content. If the request
1411 * is allowed and device initialization succeeds, then the MozPromise is
1412 * resolved with a DOMMediaStream having a track or tracks for the approved
1413 * device or devices.
1414 */
1415class GetUserMediaStreamTask final : public GetUserMediaTask {
1416 public:
1417 GetUserMediaStreamTask(
1418 const MediaStreamConstraints& aConstraints,
1419 MozPromiseHolder<MediaManager::StreamPromise>&& aHolder,
1420 uint64_t aWindowID, RefPtr<GetUserMediaWindowListener> aWindowListener,
1421 RefPtr<DeviceListener> aAudioDeviceListener,
1422 RefPtr<DeviceListener> aVideoDeviceListener,
1423 const MediaEnginePrefs& aPrefs, const ipc::PrincipalInfo& aPrincipalInfo,
1424 enum CallerType aCallerType, bool aShouldFocusSource)
1425 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1426 mConstraints(aConstraints),
1427 mHolder(std::move(aHolder)),
1428 mWindowListener(std::move(aWindowListener)),
1429 mAudioDeviceListener(std::move(aAudioDeviceListener)),
1430 mVideoDeviceListener(std::move(aVideoDeviceListener)),
1431 mPrefs(aPrefs),
1432 mShouldFocusSource(aShouldFocusSource),
1433 mManager(MediaManager::GetInstance()) {}
1434
1435 void Allowed(RefPtr<LocalMediaDevice> aAudioDevice,
1436 RefPtr<LocalMediaDevice> aVideoDevice) {
1437 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1437); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioDevice || aVideoDevice"
")"); do { *((volatile int*)__null) = 1437; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1438 mAudioDevice = std::move(aAudioDevice);
1439 mVideoDevice = std::move(aVideoDevice);
1440 // Reuse the same thread to save memory.
1441 MediaManager::Dispatch(
1442 NewRunnableMethod("GetUserMediaStreamTask::AllocateDevices", this,
1443 &GetUserMediaStreamTask::AllocateDevices));
1444 }
1445
1446 GetUserMediaStreamTask* AsGetUserMediaStreamTask() override { return this; }
1447
1448 private:
1449 ~GetUserMediaStreamTask() override {
1450 if (!mHolder.IsEmpty()) {
1451 Fail(MediaMgrError::Name::NotAllowedError);
1452 }
1453 }
1454
1455 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns,
1456 const nsString& aConstraint = u""_ns) {
1457 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage, aConstraint),
1458 __func__);
1459 // We add a disabled listener to the StreamListeners array until accepted
1460 // If this was the only active MediaStream, remove the window from the list.
1461 NS_DispatchToMainThread(NS_NewRunnableFunction(
1462 "DeviceListener::Stop",
1463 [audio = mAudioDeviceListener, video = mVideoDeviceListener] {
1464 if (audio) {
1465 audio->Stop();
1466 }
1467 if (video) {
1468 video->Stop();
1469 }
1470 }));
1471 }
1472
1473 /**
1474 * Runs on a separate thread and is responsible for allocating devices.
1475 *
1476 * Do not run this on the main thread.
1477 */
1478 void AllocateDevices() {
1479 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1479); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1479; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1480 LOG("GetUserMediaStreamTask::AllocateDevices()");
1481
1482 // Allocate a video or audio device and return a MediaStream via
1483 // PrepareDOMStream().
1484
1485 nsresult rv;
1486 const char* errorMsg = nullptr;
1487 const char* badConstraint = nullptr;
1488
1489 if (mAudioDevice) {
1490 auto& constraints = GetInvariant(mConstraints.mAudio);
1491 rv = mAudioDevice->Allocate(constraints, mPrefs, mWindowID,
1492 &badConstraint);
1493 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1494 errorMsg = "Failed to allocate audiosource";
1495 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1496 nsTArray<RefPtr<LocalMediaDevice>> devices;
1497 devices.AppendElement(mAudioDevice);
1498 badConstraint = MediaConstraintsHelper::SelectSettings(
1499 NormalizedConstraints(constraints), devices, mCallerType);
1500 }
1501 }
1502 }
1503 if (!errorMsg && mVideoDevice) {
1504 auto& constraints = GetInvariant(mConstraints.mVideo);
1505 rv = mVideoDevice->Allocate(constraints, mPrefs, mWindowID,
1506 &badConstraint);
1507 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1508 errorMsg = "Failed to allocate videosource";
1509 if (rv == NS_ERROR_NOT_AVAILABLE && !badConstraint) {
1510 nsTArray<RefPtr<LocalMediaDevice>> devices;
1511 devices.AppendElement(mVideoDevice);
1512 badConstraint = MediaConstraintsHelper::SelectSettings(
1513 NormalizedConstraints(constraints), devices, mCallerType);
1514 }
1515 if (mAudioDevice) {
1516 mAudioDevice->Deallocate();
1517 }
1518 } else {
1519 mVideoTrackingId.emplace(mVideoDevice->GetTrackingId());
1520 }
1521 }
1522 if (errorMsg) {
1523 LOG("%s %" PRIu32"u", errorMsg, static_cast<uint32_t>(rv));
1524 if (badConstraint) {
1525 Fail(MediaMgrError::Name::OverconstrainedError, ""_ns,
1526 NS_ConvertUTF8toUTF16(badConstraint));
1527 } else {
1528 Fail(MediaMgrError::Name::NotReadableError, nsCString(errorMsg));
1529 }
1530 NS_DispatchToMainThread(
1531 NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest", []() {
1532 if (MediaManager* manager = MediaManager::GetIfExists()) {
1533 manager->SendPendingGUMRequest();
1534 }
1535 }));
1536 return;
1537 }
1538 NS_DispatchToMainThread(
1539 NewRunnableMethod("GetUserMediaStreamTask::PrepareDOMStream", this,
1540 &GetUserMediaStreamTask::PrepareDOMStream));
1541 }
1542
1543 public:
1544 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1545 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1545); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1545; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1546 Fail(aName, aMessage);
1547 }
1548
1549 const MediaStreamConstraints& GetConstraints() { return mConstraints; }
1550
1551 void PrimeVoiceProcessing() {
1552 mPrimingStream = MakeAndAddRef<PrimingCubebVoiceInputStream>();
1553 mPrimingStream->Init();
1554 }
1555
1556 private:
1557 void PrepareDOMStream();
1558
1559 class PrimingCubebVoiceInputStream {
1560 class Listener final : public CubebInputStream::Listener {
1561 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1561); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1561; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1561); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1561
; __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:
;
1562
1563 private:
1564 ~Listener() = default;
1565
1566 long DataCallback(const void*, long) override {
1567 MOZ_CRASH("Unexpected data callback")do { do { } while (false); MOZ_ReportCrash("" "Unexpected data callback"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1567); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected data callback"
")"); do { *((volatile int*)__null) = 1567; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1568 }
1569 void StateCallback(cubeb_state) override {}
1570 void DeviceChangedCallback() override {}
1571 };
1572
1573 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1574; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1574
; __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:
1574 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1574; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1574
; __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:
1575
1576 public:
1577 void Init() {
1578 mCubebThread.GetEventTarget()->Dispatch(
1579 NS_NewRunnableFunction(__func__, [this, self = RefPtr(this)] {
1580 mCubebThread.AssertOnCurrentThread();
1581 LOG("Priming voice processing with stream %p", this);
1582 TRACE("PrimingCubebVoiceInputStream::Init")AutoTracer trace(gAudioCallbackTraceLogger, "PrimingCubebVoiceInputStream::Init"
);
;
1583 const cubeb_devid default_device = nullptr;
1584 const uint32_t mono = 1;
1585 const uint32_t rate = CubebUtils::PreferredSampleRate(false);
1586 const bool isVoice = true;
1587 mCubebStream =
1588 CubebInputStream::Create(default_device, mono, rate, isVoice,
1589 MakeRefPtr<Listener>().get());
1590 }));
1591 }
1592
1593 private:
1594 ~PrimingCubebVoiceInputStream() {
1595 mCubebThread.AssertOnCurrentThread();
1596 LOG("Releasing primed voice processing stream %p", this);
1597 mCubebStream = nullptr;
1598 }
1599
1600 const EventTargetCapability<nsISerialEventTarget> mCubebThread =
1601 EventTargetCapability<nsISerialEventTarget>(
1602 TaskQueue::Create(CubebUtils::GetCubebOperationThread(),
1603 "PrimingCubebInputStream::mCubebThread")
1604 .get());
1605 UniquePtr<CubebInputStream> mCubebStream MOZ_GUARDED_BY(mCubebThread)__attribute__((guarded_by(mCubebThread)));
1606 };
1607
1608 // Constraints derived from those passed to getUserMedia() but adjusted for
1609 // preferences, defaults, and security
1610 const MediaStreamConstraints mConstraints;
1611
1612 MozPromiseHolder<MediaManager::StreamPromise> mHolder;
1613 // GetUserMediaWindowListener with which DeviceListeners are registered
1614 const RefPtr<GetUserMediaWindowListener> mWindowListener;
1615 const RefPtr<DeviceListener> mAudioDeviceListener;
1616 const RefPtr<DeviceListener> mVideoDeviceListener;
1617 // MediaDevices are set when selected and Allowed() by the UI.
1618 RefPtr<LocalMediaDevice> mAudioDevice;
1619 RefPtr<LocalMediaDevice> mVideoDevice;
1620 RefPtr<PrimingCubebVoiceInputStream> mPrimingStream;
1621 // Tracking id unique for a video frame source. Set when the corresponding
1622 // device has been allocated.
1623 Maybe<TrackingId> mVideoTrackingId;
1624 // Copy of MediaManager::mPrefs
1625 const MediaEnginePrefs mPrefs;
1626 // media.getusermedia.window.focus_source.enabled
1627 const bool mShouldFocusSource;
1628 // The MediaManager is referenced at construction so that it won't be
1629 // created after its ShutdownBlocker would run.
1630 const RefPtr<MediaManager> mManager;
1631};
1632
1633/**
1634 * Creates a MediaTrack, attaches a listener and resolves a MozPromise to
1635 * provide the stream to the DOM.
1636 *
1637 * All of this must be done on the main thread!
1638 */
1639void GetUserMediaStreamTask::PrepareDOMStream() {
1640 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1640); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1640; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1641 LOG("GetUserMediaStreamTask::PrepareDOMStream()");
1642 nsGlobalWindowInner* window =
1643 nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
1644
1645 // We're on main-thread, and the windowlist can only
1646 // be invalidated from the main-thread (see OnNavigation)
1647 if (!mManager->IsWindowListenerStillActive(mWindowListener)) {
1648 // This window is no longer live. mListener has already been removed.
1649 return;
1650 }
1651
1652 MediaTrackGraph::GraphDriverType graphDriverType =
1653 mAudioDevice ? MediaTrackGraph::AUDIO_THREAD_DRIVER
1654 : MediaTrackGraph::SYSTEM_THREAD_DRIVER;
1655 MediaTrackGraph* mtg = MediaTrackGraph::GetInstance(
1656 graphDriverType, window, MediaTrackGraph::REQUEST_DEFAULT_SAMPLE_RATE,
1657 MediaTrackGraph::DEFAULT_OUTPUT_DEVICE);
1658
1659 auto domStream = MakeRefPtr<DOMMediaStream>(window);
1660 RefPtr<LocalTrackSource> audioTrackSource;
1661 RefPtr<LocalTrackSource> videoTrackSource;
1662 nsCOMPtr<nsIPrincipal> principal;
1663 RefPtr<PeerIdentity> peerIdentity = nullptr;
1664 if (!mConstraints.mPeerIdentity.IsEmpty()) {
1665 peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
1666 principal = NullPrincipal::CreateWithInheritedAttributes(
1667 window->GetExtantDoc()->NodePrincipal());
1668 } else {
1669 principal = window->GetExtantDoc()->NodePrincipal();
1670 }
1671 RefPtr<GenericNonExclusivePromise> firstFramePromise;
1672 if (mAudioDevice) {
1673 if (mAudioDevice->GetMediaSource() == MediaSourceEnum::AudioCapture) {
1674 // AudioCapture is a special case, here, in the sense that we're not
1675 // really using the audio source and the SourceMediaTrack, which acts
1676 // as placeholders. We re-route a number of tracks internally in the
1677 // MTG and mix them down instead.
1678 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1681)
1679 "MediaCaptureWindowState doesn't handle "NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1681)
1680 "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, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1681)
1681 "before shipping.")NS_DebugBreak(NS_DEBUG_WARNING, "MediaCaptureWindowState doesn't handle "
"MediaSourceEnum::AudioCapture. This must be fixed with UX "
"before shipping.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1681)
;
1682 auto audioCaptureSource = MakeRefPtr<AudioCaptureTrackSource>(
1683 principal, window, u"Window audio capture"_ns,
1684 mtg->CreateAudioCaptureTrack(), peerIdentity);
1685 audioTrackSource = audioCaptureSource;
1686 RefPtr<MediaStreamTrack> track = new dom::AudioStreamTrack(
1687 window, audioCaptureSource->InputTrack(), audioCaptureSource);
1688 domStream->AddTrackInternal(track);
1689 } else {
1690 const nsString& audioDeviceName = mAudioDevice->mName;
1691 RefPtr<MediaTrack> track;
1692#ifdef MOZ_WEBRTC1
1693 if (mAudioDevice->IsFake()) {
1694 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1695 } else {
1696 track = AudioProcessingTrack::Create(mtg);
1697 track->Suspend(); // Microphone source resumes in SetTrack
1698 }
1699#else
1700 track = mtg->CreateSourceTrack(MediaSegment::AUDIO);
1701#endif
1702 audioTrackSource = new LocalTrackSource(
1703 principal, audioDeviceName, mAudioDeviceListener,
1704 mAudioDevice->GetMediaSource(), track, peerIdentity);
1705 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mAudio)"
")"); do { *((volatile int*)__null) = 1705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1706 RefPtr<MediaStreamTrack> domTrack = new dom::AudioStreamTrack(
1707 window, track, audioTrackSource, dom::MediaStreamTrackState::Live,
1708 false, GetInvariant(mConstraints.mAudio));
1709 domStream->AddTrackInternal(domTrack);
1710 }
1711 }
1712 if (mVideoDevice) {
1713 const nsString& videoDeviceName = mVideoDevice->mName;
1714 RefPtr<MediaTrack> track = mtg->CreateSourceTrack(MediaSegment::VIDEO);
1715 videoTrackSource = new LocalTrackSource(
1716 principal, videoDeviceName, mVideoDeviceListener,
1717 mVideoDevice->GetMediaSource(), track, peerIdentity, *mVideoTrackingId);
1718 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1718); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsOn(mConstraints.mVideo)"
")"); do { *((volatile int*)__null) = 1718; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1719 RefPtr<MediaStreamTrack> domTrack = new dom::VideoStreamTrack(
1720 window, track, videoTrackSource, dom::MediaStreamTrackState::Live,
1721 false, GetInvariant(mConstraints.mVideo));
1722 domStream->AddTrackInternal(domTrack);
1723 switch (mVideoDevice->GetMediaSource()) {
1724 case MediaSourceEnum::Browser:
1725 case MediaSourceEnum::Screen:
1726 case MediaSourceEnum::Window:
1727 // Wait for first frame for screen-sharing devices, to ensure
1728 // with and height settings are available immediately, to pass wpt.
1729 firstFramePromise = mVideoDevice->Source()->GetFirstFramePromise();
1730 break;
1731 default:
1732 break;
1733 }
1734 }
1735
1736 if (!domStream || (!audioTrackSource && !videoTrackSource) ||
1737 sHasMainThreadShutdown) {
1738 LOG("Returning error for getUserMedia() - no stream");
1739
1740 mHolder.Reject(
1741 MakeRefPtr<MediaMgrError>(
1742 MediaMgrError::Name::AbortError,
1743 sHasMainThreadShutdown ? "In shutdown"_ns : "No stream."_ns),
1744 __func__);
1745 return;
1746 }
1747
1748 // Activate our device listeners. We'll call Start() on the source when we
1749 // get a callback that the MediaStream has started consuming. The listener
1750 // is freed when the page is invalidated (on navigation or close).
1751 if (mAudioDeviceListener) {
1752 mWindowListener->Activate(mAudioDeviceListener, mAudioDevice,
1753 std::move(audioTrackSource));
1754 }
1755 if (mVideoDeviceListener) {
1756 mWindowListener->Activate(mVideoDeviceListener, mVideoDevice,
1757 std::move(videoTrackSource));
1758 }
1759
1760 // Dispatch to the media thread to ask it to start the sources, because that
1761 // can take a while.
1762 typedef DeviceListener::DeviceListenerPromise PromiseType;
1763 AutoTArray<RefPtr<PromiseType>, 2> promises;
1764 if (mAudioDeviceListener) {
1765 promises.AppendElement(mAudioDeviceListener->InitializeAsync());
1766 }
1767 if (mVideoDeviceListener) {
1768 promises.AppendElement(mVideoDeviceListener->InitializeAsync());
1769 }
1770 PromiseType::All(GetMainThreadSerialEventTarget(), promises)
1771 ->Then(
1772 GetMainThreadSerialEventTarget(), __func__,
1773 [manager = mManager, windowListener = mWindowListener,
1774 firstFramePromise] {
1775 LOG("GetUserMediaStreamTask::PrepareDOMStream: starting success "
1776 "callback following InitializeAsync()");
1777 // Initiating and starting devices succeeded.
1778 windowListener->ChromeAffectingStateChanged();
1779 manager->SendPendingGUMRequest();
1780 if (!firstFramePromise) {
1781 return DeviceListener::DeviceListenerPromise::CreateAndResolve(
1782 true, __func__);
1783 }
1784 RefPtr<DeviceListener::DeviceListenerPromise> resolvePromise =
1785 firstFramePromise->Then(
1786 GetMainThreadSerialEventTarget(), __func__,
1787 [] {
1788 return DeviceListener::DeviceListenerPromise::
1789 CreateAndResolve(true, __func__);
1790 },
1791 [](nsresult aError) {
1792 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)))",
"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1792); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(aError)), 0)))"
")"); do { *((volatile int*)__null) = 1792; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1793 if (aError == NS_ERROR_UNEXPECTED) {
1794 return DeviceListener::DeviceListenerPromise::
1795 CreateAndReject(
1796 MakeRefPtr<MediaMgrError>(
1797 MediaMgrError::Name::NotAllowedError),
1798 __func__);
1799 }
1800 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aError == NS_ERROR_ABORT"
")"); do { *((volatile int*)__null) = 1800; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1801 return DeviceListener::DeviceListenerPromise::
1802 CreateAndReject(MakeRefPtr<MediaMgrError>(
1803 MediaMgrError::Name::AbortError,
1804 "In shutdown"),
1805 __func__);
1806 });
1807 return resolvePromise;
1808 },
1809 [audio = mAudioDeviceListener,
1810 video = mVideoDeviceListener](RefPtr<MediaMgrError>&& aError) {
1811 LOG("GetUserMediaStreamTask::PrepareDOMStream: starting failure "
1812 "callback following InitializeAsync()");
1813 if (audio) {
1814 audio->Stop();
1815 }
1816 if (video) {
1817 video->Stop();
1818 }
1819 return DeviceListener::DeviceListenerPromise::CreateAndReject(
1820 aError, __func__);
1821 })
1822 ->Then(
1823 GetMainThreadSerialEventTarget(), __func__,
1824 [holder = std::move(mHolder), domStream, callerType = mCallerType,
1825 shouldFocus = mShouldFocusSource, videoDevice = mVideoDevice](
1826 const DeviceListener::DeviceListenerPromise::ResolveOrRejectValue&
1827 aValue) mutable {
1828 if (aValue.IsResolve()) {
1829 if (auto* mgr = MediaManager::GetIfExists();
1830 mgr && !sHasMainThreadShutdown && videoDevice &&
1831 callerType == CallerType::NonSystem && shouldFocus) {
1832 // Device was successfully started. Attempt to focus the
1833 // source.
1834 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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1835 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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1836 "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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1837 [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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1838 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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1839 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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1840 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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1841 }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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1842 })))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)))) { LOG("FocusOnSelectedSource failed"
); } })))), 1)))), 1))) { } else { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1842); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "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)))) { LOG(\"FocusOnSelectedSource failed\"); } })))"
")"); do { *((volatile int*)__null) = 1842; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1843 }
1844
1845 holder.Resolve(domStream, __func__);
1846 } else {
1847 holder.Reject(aValue.RejectValue(), __func__);
1848 }
1849 });
1850
1851 PersistPrincipalKey();
1852}
1853
1854/**
1855 * Describes a requested task that handles response from the UI to a
1856 * selectAudioOutput() request and sends results back to content. If the
1857 * request is allowed, then the MozPromise is resolved with a MediaDevice
1858 * for the approved device.
1859 */
1860class SelectAudioOutputTask final : public GetUserMediaTask {
1861 public:
1862 SelectAudioOutputTask(MozPromiseHolder<LocalDevicePromise>&& aHolder,
1863 uint64_t aWindowID, enum CallerType aCallerType,
1864 const ipc::PrincipalInfo& aPrincipalInfo)
1865 : GetUserMediaTask(aWindowID, aPrincipalInfo, aCallerType),
1866 mHolder(std::move(aHolder)) {}
1867
1868 void Allowed(RefPtr<LocalMediaDevice> aAudioOutput) {
1869 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioOutput"
")"); do { *((volatile int*)__null) = 1869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1870 mHolder.Resolve(std::move(aAudioOutput), __func__);
1871 PersistPrincipalKey();
1872 }
1873
1874 void Denied(MediaMgrError::Name aName, const nsCString& aMessage) override {
1875 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1875); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1875; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1876 Fail(aName, aMessage);
1877 }
1878
1879 SelectAudioOutputTask* AsSelectAudioOutputTask() override { return this; }
1880
1881 private:
1882 ~SelectAudioOutputTask() override {
1883 if (!mHolder.IsEmpty()) {
1884 Fail(MediaMgrError::Name::NotAllowedError);
1885 }
1886 }
1887
1888 void Fail(MediaMgrError::Name aName, const nsCString& aMessage = ""_ns) {
1889 mHolder.Reject(MakeRefPtr<MediaMgrError>(aName, aMessage), __func__);
1890 }
1891
1892 private:
1893 MozPromiseHolder<LocalDevicePromise> mHolder;
1894};
1895
1896/* static */
1897void MediaManager::GuessVideoDeviceGroupIDs(MediaDeviceSet& aDevices,
1898 const MediaDeviceSet& aAudios) {
1899 // Run the logic in a lambda to avoid duplication.
1900 auto updateGroupIdIfNeeded = [&](RefPtr<MediaDevice>& aVideo,
1901 const MediaDeviceKind aKind) -> bool {
1902 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1902); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVideo->mKind == MediaDeviceKind::Videoinput"
")"); do { *((volatile int*)__null) = 1902; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1903 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1904); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { *((volatile int*)__null) = 1904; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1904 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1904); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKind == MediaDeviceKind::Audioinput || aKind == MediaDeviceKind::Audiooutput"
")"); do { *((volatile int*)__null) = 1904; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1905 // This will store the new group id if a match is found.
1906 nsString newVideoGroupID;
1907 // If the group id needs to be updated this will become true. It is
1908 // necessary when the new group id is an empty string. Without this extra
1909 // variable to signal the update, we would resort to test if
1910 // `newVideoGroupId` is empty. However,
1911 // that check does not work when the new group id is an empty string.
1912 bool updateGroupId = false;
1913 for (const RefPtr<MediaDevice>& dev : aAudios) {
1914 if (dev->mKind != aKind) {
1915 continue;
1916 }
1917 if (!FindInReadable(aVideo->mRawName, dev->mRawName)) {
1918 continue;
1919 }
1920 if (newVideoGroupID.IsEmpty()) {
1921 // This is only expected on first match. If that's the only match group
1922 // id will be updated to this one at the end of the loop.
1923 updateGroupId = true;
1924 newVideoGroupID = dev->mRawGroupID;
1925 } else {
1926 // More than one device found, it is impossible to know which group id
1927 // is the correct one.
1928 updateGroupId = false;
1929 newVideoGroupID = u""_ns;
1930 break;
1931 }
1932 }
1933 if (updateGroupId) {
1934 aVideo = MediaDevice::CopyWithNewRawGroupId(aVideo, newVideoGroupID);
1935 return true;
1936 }
1937 return false;
1938 };
1939
1940 for (RefPtr<MediaDevice>& video : aDevices) {
1941 if (video->mKind != MediaDeviceKind::Videoinput) {
1942 continue;
1943 }
1944 if (updateGroupIdIfNeeded(video, MediaDeviceKind::Audioinput)) {
1945 // GroupId has been updated, continue to the next video device
1946 continue;
1947 }
1948 // GroupId has not been updated, check among the outputs
1949 updateGroupIdIfNeeded(video, MediaDeviceKind::Audiooutput);
1950 }
1951}
1952
1953namespace {
1954
1955// Class to hold the promise used to request device access and to resolve
1956// even if |task| does not run, either because GeckoViewPermissionProcessChild
1957// gets destroyed before ask-device-permission receives its
1958// got-device-permission reply, or because the media thread is no longer
1959// available. In either case, the process is shutting down so the result is
1960// not important. Reject with a dummy error so the following Then-handler can
1961// resolve with an empty set, so that callers do not need to handle rejection.
1962class DeviceAccessRequestPromiseHolderWithFallback
1963 : public MozPromiseHolder<MozPromise<
1964 CamerasAccessStatus, mozilla::ipc::ResponseRejectReason, true>> {
1965 public:
1966 DeviceAccessRequestPromiseHolderWithFallback() = default;
1967 DeviceAccessRequestPromiseHolderWithFallback(
1968 DeviceAccessRequestPromiseHolderWithFallback&&) = default;
1969 ~DeviceAccessRequestPromiseHolderWithFallback() {
1970 if (!IsEmpty()) {
1971 Reject(ipc::ResponseRejectReason::ChannelClosed, __func__);
1972 }
1973 }
1974};
1975
1976} // anonymous namespace
1977
1978MediaManager::DeviceEnumerationParams::DeviceEnumerationParams(
1979 dom::MediaSourceEnum aInputType, DeviceType aType,
1980 nsAutoCString aForcedDeviceName)
1981 : mInputType(aInputType),
1982 mType(aType),
1983 mForcedDeviceName(std::move(aForcedDeviceName)) {
1984 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1984); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1984; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1985 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1985); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType != dom::MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 1985; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1986 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1986); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mType == DeviceType::Real"
")"); do { *((volatile int*)__null) = 1986; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1987}
1988
1989MediaManager::VideoDeviceEnumerationParams::VideoDeviceEnumerationParams(
1990 dom::MediaSourceEnum aInputType, DeviceType aType,
1991 nsAutoCString aForcedDeviceName, nsAutoCString aForcedMicrophoneName)
1992 : DeviceEnumerationParams(aInputType, aType, std::move(aForcedDeviceName)),
1993 mForcedMicrophoneName(std::move(aForcedMicrophoneName)) {
1994 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1994; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1995 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 1996; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1996 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 1996; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1997 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 1997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mType == DeviceType::Real"
")"); do { *((volatile int*)__null) = 1997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1998}
1999
2000MediaManager::EnumerationParams::EnumerationParams(
2001 EnumerationFlags aFlags, Maybe<VideoDeviceEnumerationParams> aVideo,
2002 Maybe<DeviceEnumerationParams> aAudio)
2003 : mFlags(aFlags), mVideo(std::move(aVideo)), mAudio(std::move(aAudio)) {
2004 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2005 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2005); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaEngineSource::IsVideo(mVideo->mInputType)"
")"); do { *((volatile int*)__null) = 2005; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2006 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 2007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2007 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 2007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2008 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2009); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 2009; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2009 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2009); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mVideo->mInputType == dom::MediaSourceEnum::Camera"
")"); do { *((volatile int*)__null) = 2009; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2010 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2010); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaEngineSource::IsAudio(mAudio->mInputType)"
")"); do { *((volatile int*)__null) = 2010; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2011 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2012); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { *((volatile int*)__null) = 2012; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2012 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2012); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { *((volatile int*)__null) = 2012; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2013 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2014); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { *((volatile int*)__null) = 2014; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2014 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2014); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAudio->mInputType == dom::MediaSourceEnum::Microphone"
")"); do { *((volatile int*)__null) = 2014; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2015}
2016
2017bool MediaManager::EnumerationParams::HasFakeCams() const {
2018 return mVideo
2019 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2020 .valueOr(false);
2021}
2022
2023bool MediaManager::EnumerationParams::HasFakeMics() const {
2024 return mAudio
2025 .map([](const auto& aDev) { return aDev.mType == DeviceType::Fake; })
2026 .valueOr(false);
2027}
2028
2029bool MediaManager::EnumerationParams::RealDeviceRequested() const {
2030 auto isReal = [](const auto& aDev) { return aDev.mType == DeviceType::Real; };
2031 return mVideo.map(isReal).valueOr(false) ||
2032 mAudio.map(isReal).valueOr(false) ||
2033 mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2034}
2035
2036MediaSourceEnum MediaManager::EnumerationParams::VideoInputType() const {
2037 return mVideo.map([](const auto& aDev) { return aDev.mInputType; })
2038 .valueOr(MediaSourceEnum::Other);
2039}
2040
2041MediaSourceEnum MediaManager::EnumerationParams::AudioInputType() const {
2042 return mAudio.map([](const auto& aDev) { return aDev.mInputType; })
2043 .valueOr(MediaSourceEnum::Other);
2044}
2045
2046/* static */ MediaManager::EnumerationParams
2047MediaManager::CreateEnumerationParams(dom::MediaSourceEnum aVideoInputType,
2048 dom::MediaSourceEnum aAudioInputType,
2049 EnumerationFlags aFlags) {
2050 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2050); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2050; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2051 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2052); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 2052; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2052 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2052); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVideoInputType == dom::MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 2052; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2053 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2054); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 2054; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2054 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2054); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aAudioInputType == dom::MediaSourceEnum::Other"
")"); do { *((volatile int*)__null) = 2054; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2055 const bool forceFakes = aFlags.contains(EnumerationFlag::ForceFakes);
2056 const bool fakeByPref = Preferences::GetBool("media.navigator.streams.fake");
2057 Maybe<VideoDeviceEnumerationParams> videoParams;
2058 Maybe<DeviceEnumerationParams> audioParams;
2059 nsAutoCString audioDev;
2060 bool audioDevRead = false;
2061 constexpr const char* VIDEO_DEV_NAME = "media.video_loopback_dev";
2062 constexpr const char* AUDIO_DEV_NAME = "media.audio_loopback_dev";
2063 const auto ensureDev = [](const char* aPref, nsAutoCString* aLoopDev,
2064 bool* aPrefRead) {
2065 if (aPrefRead) {
2066 if (*aPrefRead) {
2067 return;
2068 }
2069 *aPrefRead = true;
2070 }
2071
2072 if (NS_FAILED(Preferences::GetCString(aPref, *aLoopDev))((bool)(__builtin_expect(!!(NS_FAILED_impl(Preferences::GetCString
(aPref, *aLoopDev))), 0)))
) {
2073 // Ensure we fall back to an empty string if reading the pref failed.
2074 aLoopDev->SetIsVoid(true);
2075 }
2076 };
2077 if (MediaEngineSource::IsVideo(aVideoInputType)) {
2078 nsAutoCString videoDev;
2079 DeviceType type = DeviceType::Real;
2080 if (aVideoInputType == MediaSourceEnum::Camera) {
2081 // Fake and loopback devices are supported for only Camera.
2082 if (forceFakes) {
2083 type = DeviceType::Fake;
2084 } else {
2085 ensureDev(VIDEO_DEV_NAME, &videoDev, nullptr);
2086 // Loopback prefs take precedence over fake prefs
2087 if (fakeByPref && videoDev.IsEmpty()) {
2088 type = DeviceType::Fake;
2089 } else {
2090 // For groupId correlation we need the audio device name.
2091 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2092 }
2093 }
2094 }
2095 videoParams = Some(VideoDeviceEnumerationParams(aVideoInputType, type,
2096 videoDev, audioDev));
2097 }
2098 if (MediaEngineSource::IsAudio(aAudioInputType)) {
2099 nsAutoCString realAudioDev;
2100 DeviceType type = DeviceType::Real;
2101 if (aAudioInputType == MediaSourceEnum::Microphone) {
2102 // Fake and loopback devices are supported for only Microphone.
2103 if (forceFakes) {
2104 type = DeviceType::Fake;
2105 } else {
2106 ensureDev(AUDIO_DEV_NAME, &audioDev, &audioDevRead);
2107 // Loopback prefs take precedence over fake prefs
2108 if (fakeByPref && audioDev.IsEmpty()) {
2109 type = DeviceType::Fake;
2110 } else {
2111 realAudioDev = audioDev;
2112 }
2113 }
2114 }
2115 audioParams =
2116 Some(DeviceEnumerationParams(aAudioInputType, type, realAudioDev));
2117 }
2118 return EnumerationParams(aFlags, videoParams, audioParams);
2119}
2120
2121RefPtr<DeviceSetPromise>
2122MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
2123 EnumerationParams aParams) {
2124 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2124); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2124; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2125 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2126); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { *((volatile int*)__null) = 2126; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2126 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2126); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParams.mVideo.isSome() || aParams.mAudio.isSome() || aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)"
")"); do { *((volatile int*)__null) = 2126; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2127
2128 LOG("%s: aVideoInputType=%" PRIu8"u" ", aAudioInputType=%" PRIu8"u", __func__,
2129 static_cast<uint8_t>(aParams.VideoInputType()),
2130 static_cast<uint8_t>(aParams.AudioInputType()));
2131
2132 if (sHasMainThreadShutdown) {
2133 // The media thread is no longer available but the result will not be
2134 // observable.
2135 return DeviceSetPromise::CreateAndResolve(
2136 new MediaDeviceSetRefCnt(),
2137 "MaybeRequestPermissionAndEnumerateRawDevices: sync shutdown");
2138 }
2139
2140 const bool hasVideo = aParams.mVideo.isSome();
2141 const bool hasAudio = aParams.mAudio.isSome();
2142 const bool hasAudioOutput =
2143 aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs);
2144 const bool hasFakeCams = aParams.HasFakeCams();
2145 const bool hasFakeMics = aParams.HasFakeMics();
2146 // True if at least one of video input or audio input is a real device
2147 // or there is audio output.
2148 const bool realDeviceRequested = (!hasFakeCams && hasVideo) ||
2149 (!hasFakeMics && hasAudio) || hasAudioOutput;
2150
2151 using NativePromise =
2152 MozPromise<CamerasAccessStatus, mozilla::ipc::ResponseRejectReason,
2153 /* IsExclusive = */ true>;
2154 RefPtr<NativePromise> deviceAccessPromise;
2155 if (realDeviceRequested &&
2156 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
2157 Preferences::GetBool("media.navigator.permission.device", false)) {
2158 // Need to ask permission to retrieve list of all devices;
2159 // notify frontend observer and wait for callback notification to post
2160 // task.
2161 const char16_t* const type =
2162 (aParams.VideoInputType() != MediaSourceEnum::Camera) ? u"audio"
2163 : (aParams.AudioInputType() != MediaSourceEnum::Microphone) ? u"video"
2164 : u"all";
2165 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2166 DeviceAccessRequestPromiseHolderWithFallback deviceAccessPromiseHolder;
2167 deviceAccessPromise = deviceAccessPromiseHolder.Ensure(__func__);
2168 RefPtr task = NS_NewRunnableFunction(
2169 __func__, [holder = std::move(deviceAccessPromiseHolder)]() mutable {
2170 holder.Resolve(CamerasAccessStatus::Granted,
2171 "getUserMedia:got-device-permission");
2172 });
2173 obs->NotifyObservers(static_cast<nsIRunnable*>(task),
2174 "getUserMedia:ask-device-permission", type);
2175 } else if (realDeviceRequested && hasVideo &&
2176 aParams.VideoInputType() == MediaSourceEnum::Camera) {
2177 ipc::PBackgroundChild* backgroundChild =
2178 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2179 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(
2180 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest));
2181 }
2182
2183 if (!deviceAccessPromise) {
2184 // No device access request needed. We can proceed directly, but we still
2185 // need to update camera availability, because the camera engine is always
2186 // created together with the WebRTC backend, which is done because
2187 // devicechange events must work before prompting in cases where persistent
2188 // permission has already been given. Making a request to camera access not
2189 // allowing a permission request does exactly what we need in this case.
2190 ipc::PBackgroundChild* backgroundChild =
2191 ipc::BackgroundChild::GetOrCreateForCurrentThread();
2192 deviceAccessPromise = backgroundChild->SendRequestCameraAccess(false);
2193 }
2194
2195 return deviceAccessPromise->Then(
2196 GetCurrentSerialEventTarget(), __func__,
2197 [this, self = RefPtr(this), aParams = std::move(aParams)](
2198 NativePromise::ResolveOrRejectValue&& aValue) mutable {
2199 if (sHasMainThreadShutdown) {
2200 return DeviceSetPromise::CreateAndResolve(
2201 new MediaDeviceSetRefCnt(),
2202 "MaybeRequestPermissionAndEnumerateRawDevices: async shutdown");
2203 }
2204
2205 if (aValue.IsReject()) {
2206 // IPC failure probably means we're in shutdown. Resolve with
2207 // an empty set, so that callers do not need to handle rejection.
2208 return DeviceSetPromise::CreateAndResolve(
2209 new MediaDeviceSetRefCnt(),
2210 "MaybeRequestPermissionAndEnumerateRawDevices: ipc failure");
2211 }
2212
2213 if (auto v = aValue.ResolveValue();
2214 v == CamerasAccessStatus::Error ||
2215 v == CamerasAccessStatus::Rejected) {
2216 LOG("Request to camera access %s",
2217 v == CamerasAccessStatus::Rejected ? "was rejected" : "failed");
2218 if (v == CamerasAccessStatus::Error) {
2219 NS_WARNING("Failed to request camera access")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to request camera access"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2219)
;
2220 }
2221 return DeviceSetPromise::CreateAndReject(
2222 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2223 "MaybeRequestPermissionAndEnumerateRawDevices: camera access "
2224 "rejected");
2225 }
2226
2227 if (aParams.VideoInputType() == MediaSourceEnum::Camera &&
2228 aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
2229 aValue.ResolveValue() == CamerasAccessStatus::Granted) {
2230 EnsureNoPlaceholdersInDeviceCache();
2231 }
2232
2233 // We have to nest this, unfortunately, since we have no guarantees that
2234 // mMediaThread is alive. If we'd reject due to shutdown above, and have
2235 // the below async operation in a Then handler on the media thread the
2236 // Then handler would fail to dispatch and trip an assert on
2237 // destruction, for instance.
2238 return InvokeAsync(
2239 mMediaThread, __func__, [aParams = std::move(aParams)]() mutable {
2240 return DeviceSetPromise::CreateAndResolve(
2241 EnumerateRawDevices(std::move(aParams)),
2242 "MaybeRequestPermissionAndEnumerateRawDevices: success");
2243 });
2244 });
2245}
2246
2247/**
2248 * EnumerateRawDevices - Enumerate a list of audio & video devices that
2249 * satisfy passed-in constraints. List contains raw id's.
2250 */
2251
2252/* static */ RefPtr<MediaManager::MediaDeviceSetRefCnt>
2253MediaManager::EnumerateRawDevices(EnumerationParams aParams) {
2254 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2254); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 2254; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2255 // Only enumerate what's asked for, and only fake cams and mics.
2256 RefPtr<MediaEngine> fakeBackend, realBackend;
2257 if (aParams.HasFakeCams() || aParams.HasFakeMics()) {
2258 fakeBackend = new MediaEngineFake();
2259 }
2260 if (aParams.RealDeviceRequested()) {
2261 MediaManager* manager = MediaManager::GetIfExists();
2262 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2262); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "manager"
") (" "Must exist while media thread is alive" ")"); do { *(
(volatile int*)__null) = 2262; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
2263 realBackend = manager->GetBackend();
2264 }
2265
2266 RefPtr<MediaEngine> videoBackend;
2267 RefPtr<MediaEngine> audioBackend;
2268 Maybe<MediaDeviceSet> micsOfVideoBackend;
2269 Maybe<MediaDeviceSet> speakers;
2270 RefPtr devices = new MediaDeviceSetRefCnt();
2271
2272 // Enumerate microphones first, then cameras, then speakers, since
2273 // the enumerateDevices() algorithm expects them listed in that order.
2274 if (const auto& audio = aParams.mAudio; audio.isSome()) {
2275 audioBackend = aParams.HasFakeMics() ? fakeBackend : realBackend;
2276 MediaDeviceSet audios;
2277 LOG("EnumerateRawDevices: Getting audio sources with %s backend",
2278 audioBackend == fakeBackend ? "fake" : "real");
2279 GetMediaDevices(audioBackend, audio->mInputType, audios,
2280 audio->mForcedDeviceName.get());
2281 if (audio->mInputType == MediaSourceEnum::Microphone &&
2282 audioBackend == videoBackend) {
2283 micsOfVideoBackend.emplace();
2284 micsOfVideoBackend->AppendElements(audios);
2285 }
2286 devices->AppendElements(std::move(audios));
2287 }
2288 if (const auto& video = aParams.mVideo; video.isSome()) {
2289 videoBackend = aParams.HasFakeCams() ? fakeBackend : realBackend;
2290 MediaDeviceSet videos;
2291 LOG("EnumerateRawDevices: Getting video sources with %s backend",
2292 videoBackend == fakeBackend ? "fake" : "real");
2293 GetMediaDevices(videoBackend, video->mInputType, videos,
2294 video->mForcedDeviceName.get());
2295 devices->AppendElements(std::move(videos));
2296 }
2297 if (aParams.mFlags.contains(EnumerationFlag::EnumerateAudioOutputs)) {
2298 MediaDeviceSet outputs;
2299 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2299); AnnotateMozCrashReason("MOZ_ASSERT" "(" "realBackend"
")"); do { *((volatile int*)__null) = 2299; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2300 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2301 MediaSinkEnum::Speaker, &outputs);
2302 speakers = Some(MediaDeviceSet());
2303 speakers->AppendElements(outputs);
2304 devices->AppendElements(std::move(outputs));
2305 }
2306 if (aParams.VideoInputType() == MediaSourceEnum::Camera) {
2307 MediaDeviceSet audios;
2308 LOG("EnumerateRawDevices: Getting audio sources with %s backend for "
2309 "groupId correlation",
2310 videoBackend == fakeBackend ? "fake" : "real");
2311 // We need to correlate cameras with audio groupIds. We use the backend of
2312 // the camera to always do correlation on devices in the same scope. If we
2313 // don't do this, video-only getUserMedia will not apply groupId constraints
2314 // to the same set of groupIds as gets returned by enumerateDevices.
2315 if (micsOfVideoBackend.isSome()) {
2316 // Microphones from the same backend used for the cameras have
2317 // already been enumerated. Avoid doing it again.
2318 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2319); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { *((volatile int*)__null) = 2319; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2319 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2319); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParams.mVideo->mForcedMicrophoneName == aParams.mAudio->mForcedDeviceName"
")"); do { *((volatile int*)__null) = 2319; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2320 audios.AppendElements(micsOfVideoBackend.extract());
2321 } else {
2322 GetMediaDevices(videoBackend, MediaSourceEnum::Microphone, audios,
2323 aParams.mVideo->mForcedMicrophoneName.get());
2324 }
2325 if (videoBackend == realBackend) {
2326 // When using the real backend for video, there could also be
2327 // speakers to correlate with. There are no fake speakers.
2328 if (speakers.isSome()) {
2329 // Speakers have already been enumerated. Avoid doing it again.
2330 audios.AppendElements(speakers.extract());
2331 } else {
2332 realBackend->EnumerateDevices(MediaSourceEnum::Other,
2333 MediaSinkEnum::Speaker, &audios);
2334 }
2335 }
2336 GuessVideoDeviceGroupIDs(*devices, audios);
2337 }
2338
2339 return devices;
2340}
2341
2342RefPtr<ConstDeviceSetPromise> MediaManager::GetPhysicalDevices() {
2343 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2343; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2344 if (mPhysicalDevices) {
2345 return ConstDeviceSetPromise::CreateAndResolve(mPhysicalDevices, __func__);
2346 }
2347 if (mPendingDevicesPromises) {
2348 // Enumeration is already in progress.
2349 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2350 }
2351 mPendingDevicesPromises =
2352 new Refcountable<nsTArray<MozPromiseHolder<ConstDeviceSetPromise>>>;
2353 MaybeRequestPermissionAndEnumerateRawDevices(
2354 CreateEnumerationParams(MediaSourceEnum::Camera,
2355 MediaSourceEnum::Microphone,
2356 EnumerationFlag::EnumerateAudioOutputs))
2357 ->Then(
2358 GetCurrentSerialEventTarget(), __func__,
2359 [self = RefPtr(this), this, promises = mPendingDevicesPromises](
2360 RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
2361 for (auto& promiseHolder : *promises) {
2362 promiseHolder.Resolve(aDevices, __func__);
2363 }
2364 // mPendingDevicesPromises may have changed if devices have changed.
2365 if (promises == mPendingDevicesPromises) {
2366 mPendingDevicesPromises = nullptr;
2367 mPhysicalDevices = std::move(aDevices);
2368 }
2369 },
2370 [](RefPtr<MediaMgrError>&& reason) {
2371 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { *((volatile int*)__null) = 2372; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2372 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "MaybeRequestPermissionAndEnumerateRawDevices does not reject"
")"); do { *((volatile int*)__null) = 2372; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2373 });
2374
2375 return mPendingDevicesPromises->AppendElement()->Ensure(__func__);
2376}
2377
2378MediaManager::MediaManager(already_AddRefed<TaskQueue> aMediaThread)
2379 : mMediaThread(aMediaThread), mBackend(nullptr) {
2380 mPrefs.mFreq = 1000; // 1KHz test tone
2381 mPrefs.mWidth = 0; // adaptive default
2382 mPrefs.mHeight = 0; // adaptive default
2383 mPrefs.mFPS = MediaEnginePrefs::DEFAULT_VIDEO_FPS;
2384 mPrefs.mUsePlatformProcessing = false;
2385 mPrefs.mAecOn = false;
2386 mPrefs.mUseAecMobile = false;
2387 mPrefs.mAgcOn = false;
2388 mPrefs.mHPFOn = false;
2389 mPrefs.mNoiseOn = false;
2390 mPrefs.mTransientOn = false;
2391 mPrefs.mAgc2Forced = false;
2392 mPrefs.mExpectDrift = -1; // auto
2393#ifdef MOZ_WEBRTC1
2394 mPrefs.mAgc =
2395 webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveDigital;
2396 mPrefs.mNoise =
2397 webrtc::AudioProcessing::Config::NoiseSuppression::Level::kModerate;
2398#else
2399 mPrefs.mAgc = 0;
2400 mPrefs.mNoise = 0;
2401#endif
2402 mPrefs.mChannels = 0; // max channels default
2403 nsresult rv;
2404 nsCOMPtr<nsIPrefService> prefs =
2405 do_GetService("@mozilla.org/preferences-service;1", &rv);
2406 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2407 nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
2408 if (branch) {
2409 GetPrefs(branch, nullptr);
2410 }
2411 }
2412}
2413
2414NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2415; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2415; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2415
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2415; __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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); 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((
sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
2415 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2415; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2415; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2415
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MediaManager\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2415; __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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2415); 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((
sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
2416
2417/* static */
2418StaticRefPtr<MediaManager> MediaManager::sSingleton;
2419
2420#ifdef DEBUG1
2421/* static */
2422bool MediaManager::IsInMediaThread() {
2423 return sSingleton && sSingleton->mMediaThread->IsOnCurrentThread();
2424}
2425#endif
2426
2427template <typename Function>
2428static void ForeachObservedPref(const Function& aFunction) {
2429 aFunction("media.navigator.video.default_width"_ns);
2430 aFunction("media.navigator.video.default_height"_ns);
2431 aFunction("media.navigator.video.default_fps"_ns);
2432 aFunction("media.navigator.audio.fake_frequency"_ns);
2433 aFunction("media.audio_loopback_dev"_ns);
2434 aFunction("media.video_loopback_dev"_ns);
2435 aFunction("media.getusermedia.fake-camera-name"_ns);
2436#ifdef MOZ_WEBRTC1
2437 aFunction("media.getusermedia.audio.processing.aec.enabled"_ns);
2438 aFunction("media.getusermedia.audio.processing.aec"_ns);
2439 aFunction("media.getusermedia.audio.processing.agc.enabled"_ns);
2440 aFunction("media.getusermedia.audio.processing.agc"_ns);
2441 aFunction("media.getusermedia.audio.processing.hpf.enabled"_ns);
2442 aFunction("media.getusermedia.audio.processing.noise.enabled"_ns);
2443 aFunction("media.getusermedia.audio.processing.noise"_ns);
2444 aFunction("media.getusermedia.audio.max_channels"_ns);
2445 aFunction("media.navigator.streams.fake"_ns);
2446#endif
2447}
2448
2449// NOTE: never NS_DispatchAndSpinEventLoopUntilComplete to the MediaManager
2450// thread from the MainThread, as we NS_DispatchAndSpinEventLoopUntilComplete to
2451// MainThread from MediaManager thread.
2452
2453// Guaranteed never to return nullptr.
2454/* static */
2455MediaManager* MediaManager::Get() {
2456 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2456); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2456; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2457
2458 if (!sSingleton) {
2459 static int timesCreated = 0;
2460 timesCreated++;
2461 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2461); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "timesCreated == 1"
")"); do { *((volatile int*)__null) = 2461; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2462
2463 RefPtr<TaskQueue> mediaThread = TaskQueue::Create(
2464 GetMediaThreadPool(MediaThreadType::SUPERVISOR), "MediaManager");
2465 LOG("New Media thread for gum");
2466
2467 sSingleton = new MediaManager(mediaThread.forget());
2468
2469 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2470 if (obs) {
2471 obs->AddObserver(sSingleton, "last-pb-context-exited", false);
2472 obs->AddObserver(sSingleton, "getUserMedia:got-device-permission", false);
2473 obs->AddObserver(sSingleton, "getUserMedia:privileged:allow", false);
2474 obs->AddObserver(sSingleton, "getUserMedia:response:allow", false);
2475 obs->AddObserver(sSingleton, "getUserMedia:response:deny", false);
2476 obs->AddObserver(sSingleton, "getUserMedia:response:noOSPermission",
2477 false);
2478 obs->AddObserver(sSingleton, "getUserMedia:revoke", false);
2479 obs->AddObserver(sSingleton, "getUserMedia:muteVideo", false);
2480 obs->AddObserver(sSingleton, "getUserMedia:unmuteVideo", false);
2481 obs->AddObserver(sSingleton, "getUserMedia:muteAudio", false);
2482 obs->AddObserver(sSingleton, "getUserMedia:unmuteAudio", false);
2483 obs->AddObserver(sSingleton, "application-background", false);
2484 obs->AddObserver(sSingleton, "application-foreground", false);
2485 }
2486 // else MediaManager won't work properly and will leak (see bug 837874)
2487 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
2488 if (prefs) {
2489 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
2490 prefs->AddObserver(aPrefName, sSingleton, false);
2491 });
2492 }
2493 RegisterStrongMemoryReporter(sSingleton);
2494
2495 // Prepare async shutdown
2496
2497 class Blocker : public media::ShutdownBlocker {
2498 public:
2499 Blocker()
2500 : media::ShutdownBlocker(
2501 u"Media shutdown: blocking on media thread"_ns) {}
2502
2503 NS_IMETHODvirtual nsresult BlockShutdown(nsIAsyncShutdownClient*) override {
2504 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2504); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "MediaManager::GetIfExists()"
")"); do { *((volatile int*)__null) = 2504; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2505 MediaManager::GetIfExists()->Shutdown();
2506 return NS_OK;
2507 }
2508 };
2509
2510 sSingleton->mShutdownBlocker = new Blocker();
2511 nsresult rv = media::MustGetShutdownBarrier()->AddBlocker(
2512 sSingleton->mShutdownBlocker, NS_LITERAL_STRING_FROM_CSTRING(__FILE__)static_cast<const nsLiteralString&>( nsLiteralString
(u"" "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
))
,
2513 __LINE__2513, u""_ns);
2514 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2514); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 2514; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2515 }
2516 return sSingleton;
2517}
2518
2519/* static */
2520MediaManager* MediaManager::GetIfExists() {
2521 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread() || IsInMediaThread()"
")"); do { *((volatile int*)__null) = 2521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2522 return sSingleton;
2523}
2524
2525/* static */
2526already_AddRefed<MediaManager> MediaManager::GetInstance() {
2527 // so we can have non-refcounted getters
2528 RefPtr<MediaManager> service = MediaManager::Get();
2529 return service.forget();
2530}
2531
2532media::Parent<media::NonE10s>* MediaManager::GetNonE10sParent() {
2533 if (!mNonE10sParent) {
2534 mNonE10sParent = new media::Parent<media::NonE10s>();
2535 }
2536 return mNonE10sParent;
2537}
2538
2539/* static */
2540void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
2541 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2541); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2541; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2542 if (sHasMainThreadShutdown) {
2543 // Can't safely delete task here since it may have items with specific
2544 // thread-release requirements.
2545 // XXXkhuey well then who is supposed to delete it?! We don't signal
2546 // that we failed ...
2547 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2547); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 2547; __attribute__((nomerge)) ::abort(); } while
(false); } while (false)
;
2548 return;
2549 }
2550 NS_ASSERTION(Get(), "MediaManager singleton?")do { if (!(Get())) { NS_DebugBreak(NS_DEBUG_ASSERTION, "MediaManager singleton?"
, "Get()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2550); MOZ_PretendNoReturn(); } } while (0)
;
2551 NS_ASSERTION(Get()->mMediaThread, "No thread yet")do { if (!(Get()->mMediaThread)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "No thread yet", "Get()->mMediaThread", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2551); MOZ_PretendNoReturn(); } } while (0)
;
2552 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 { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(Get()->mMediaThread->Dispatch(std::move(task)))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2552); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(Get()->mMediaThread->Dispatch(std::move(task)))"
")"); do { *((volatile int*)__null) = 2552; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2553}
2554
2555template <typename MozPromiseType, typename FunctionType>
2556/* static */
2557RefPtr<MozPromiseType> MediaManager::Dispatch(StaticString aName,
2558 FunctionType&& aFunction) {
2559 MozPromiseHolder<MozPromiseType> holder;
2560 RefPtr<MozPromiseType> promise = holder.Ensure(aName);
2561 MediaManager::Dispatch(NS_NewRunnableFunction(
2562 aName, [h = std::move(holder), func = std::forward<FunctionType>(
2563 aFunction)]() mutable { func(h); }));
2564 return promise;
2565}
2566
2567/* static */
2568nsresult MediaManager::NotifyRecordingStatusChange(
2569 nsPIDOMWindowInner* aWindow) {
2570 NS_ENSURE_ARG(aWindow)do { if ((__builtin_expect(!!(!(aWindow)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aWindow" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2570); return NS_ERROR_INVALID_ARG; } } while (false)
;
2571
2572 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2573 if (!obs) {
2574 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2576)
2575 "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, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2576)
2576 "notification.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the Observer service for GetUserMedia recording "
"notification.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2576)
;
2577 return NS_ERROR_FAILURE;
2578 }
2579
2580 auto props = MakeRefPtr<nsHashPropertyBag>();
2581
2582 nsCString pageURL;
2583 nsCOMPtr<nsIURI> docURI = aWindow->GetDocumentURI();
2584 NS_ENSURE_TRUE(docURI, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(docURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "docURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2584); return NS_ERROR_FAILURE; } } while (false)
;
2585
2586 nsresult rv = docURI->GetSpec(pageURL);
2587 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, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2587); return rv; } } while (false)
;
2588
2589 NS_ConvertUTF8toUTF16 requestURL(pageURL);
2590
2591 props->SetPropertyAsAString(u"requestURL"_ns, requestURL);
2592 props->SetPropertyAsInterface(u"window"_ns, aWindow);
2593
2594 obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
2595 "recording-device-events", nullptr);
2596 LOG("Sent recording-device-events for url '%s'", pageURL.get());
2597
2598 return NS_OK;
2599}
2600
2601void MediaManager::DeviceListChanged() {
2602 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2602); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2602; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2603 if (sHasMainThreadShutdown) {
2604 return;
2605 }
2606 // Invalidate immediately to provide an up-to-date device list for future
2607 // enumerations on platforms with sane device-list-changed events.
2608 InvalidateDeviceCache();
2609
2610 // Wait 200 ms, because
2611 // A) on some Windows machines, if we call EnumerateRawDevices immediately
2612 // after receiving devicechange event, we'd get an outdated devices list.
2613 // B) Waiting helps coalesce multiple calls on us into one, which can happen
2614 // if a device with both audio input and output is attached or removed.
2615 // We want to react & fire a devicechange event only once in that case.
2616
2617 // The wait is extended if another hardware device-list-changed notification
2618 // is received to provide the full 200ms for EnumerateRawDevices().
2619 if (mDeviceChangeTimer) {
2620 mDeviceChangeTimer->Cancel();
2621 } else {
2622 mDeviceChangeTimer = MakeRefPtr<MediaTimer>();
2623 }
2624 // However, if this would cause a delay of over 1000ms in handling the
2625 // oldest unhandled event, then respond now and set the timer to run
2626 // EnumerateRawDevices() again in 200ms.
2627 auto now = TimeStamp::NowLoRes();
2628 auto enumerateDelay = TimeDuration::FromMilliseconds(200);
2629 auto coalescenceLimit = TimeDuration::FromMilliseconds(1000) - enumerateDelay;
2630 if (!mUnhandledDeviceChangeTime) {
2631 mUnhandledDeviceChangeTime = now;
2632 } else if (now - mUnhandledDeviceChangeTime > coalescenceLimit) {
2633 HandleDeviceListChanged();
2634 mUnhandledDeviceChangeTime = now;
2635 }
2636 RefPtr<MediaManager> self = this;
2637 mDeviceChangeTimer->WaitFor(enumerateDelay, __func__)
2638 ->Then(
2639 GetCurrentSerialEventTarget(), __func__,
2640 [self, this] {
2641 // Invalidate again for the sake of platforms with inconsistent
2642 // timing between device-list-changed notification and enumeration.
2643 InvalidateDeviceCache();
2644
2645 mUnhandledDeviceChangeTime = TimeStamp();
2646 HandleDeviceListChanged();
2647 },
2648 [] { /* Timer was canceled by us, or we're in shutdown. */ });
2649}
2650
2651void MediaManager::EnsureNoPlaceholdersInDeviceCache() {
2652 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2652); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2652; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2653
2654 if (mPhysicalDevices) {
2655 // Invalidate the list if there is a placeholder
2656 for (const auto& device : *mPhysicalDevices) {
2657 if (device->mIsPlaceholder) {
2658 InvalidateDeviceCache();
2659 break;
2660 }
2661 }
2662 }
2663}
2664
2665void MediaManager::InvalidateDeviceCache() {
2666 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2667
2668 mPhysicalDevices = nullptr;
2669 // Disconnect any in-progress enumeration, which may now be out of date,
2670 // from updating mPhysicalDevices or resolving future device request
2671 // promises.
2672 mPendingDevicesPromises = nullptr;
2673}
2674
2675void MediaManager::HandleDeviceListChanged() {
2676 mDeviceListChangeEvent.Notify();
2677
2678 GetPhysicalDevices()->Then(
2679 GetCurrentSerialEventTarget(), __func__,
2680 [self = RefPtr(this), this](RefPtr<const MediaDeviceSetRefCnt> aDevices) {
2681 if (!MediaManager::GetIfExists()) {
2682 return;
2683 }
2684
2685 nsTHashSet<nsString> deviceIDs;
2686 for (const auto& device : *aDevices) {
2687 deviceIDs.Insert(device->mRawID);
2688 }
2689 // For any real removed cameras or microphones, notify their
2690 // listeners cleanly that the source has stopped, so JS knows and
2691 // usage indicators update.
2692 // First collect the listeners in an array to stop them after
2693 // iterating the hashtable. The StopRawID() method indirectly
2694 // modifies the mActiveWindows and would assert-crash if the
2695 // iterator were active while the table is being enumerated.
2696 const auto windowListeners = ToArray(mActiveWindows.Values());
2697 for (const RefPtr<GetUserMediaWindowListener>& l : windowListeners) {
2698 const auto activeDevices = l->GetDevices();
2699 for (const RefPtr<LocalMediaDevice>& device : *activeDevices) {
2700 if (device->IsFake()) {
2701 continue;
2702 }
2703 MediaSourceEnum mediaSource = device->GetMediaSource();
2704 if (mediaSource != MediaSourceEnum::Microphone &&
2705 mediaSource != MediaSourceEnum::Camera) {
2706 continue;
2707 }
2708 if (!deviceIDs.Contains(device->RawID())) {
2709 // Device has been removed
2710 l->StopRawID(device->RawID());
2711 }
2712 }
2713 }
2714 },
2715 [](RefPtr<MediaMgrError>&& reason) {
2716 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2716); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "EnumerateRawDevices does not reject"
")"); do { *((volatile int*)__null) = 2716; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2717 });
2718}
2719
2720size_t MediaManager::AddTaskAndGetCount(uint64_t aWindowID,
2721 const nsAString& aCallID,
2722 RefPtr<GetUserMediaTask> aTask) {
2723 // Store the task w/callbacks.
2724 mActiveCallbacks.InsertOrUpdate(aCallID, std::move(aTask));
2725
2726 // Add a WindowID cross-reference so OnNavigation can tear things down
2727 nsTArray<nsString>* const array = mCallIds.GetOrInsertNew(aWindowID);
2728 array->AppendElement(aCallID);
2729
2730 return array->Length();
2731}
2732
2733RefPtr<GetUserMediaTask> MediaManager::TakeGetUserMediaTask(
2734 const nsAString& aCallID) {
2735 RefPtr<GetUserMediaTask> task;
2736 mActiveCallbacks.Remove(aCallID, getter_AddRefs(task));
2737 if (!task) {
2738 return nullptr;
2739 }
2740 nsTArray<nsString>* array;
2741 mCallIds.Get(task->GetWindowID(), &array);
2742 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2742); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { *((volatile int*)__null) = 2742; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2743 array->RemoveElement(aCallID);
2744 return task;
2745}
2746
2747void MediaManager::NotifyAllowed(const nsString& aCallID,
2748 const LocalMediaDeviceSet& aDevices) {
2749 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2750 nsCOMPtr<nsIMutableArray> devicesCopy = nsArray::Create();
2751 for (const auto& device : aDevices) {
2752 nsresult rv = devicesCopy->AppendElement(device);
2753 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2753)
) {
2754 obs->NotifyObservers(nullptr, "getUserMedia:response:deny",
2755 aCallID.get());
2756 return;
2757 }
2758 }
2759 obs->NotifyObservers(devicesCopy, "getUserMedia:privileged:allow",
2760 aCallID.get());
2761}
2762
2763nsresult MediaManager::GenerateUUID(nsAString& aResult) {
2764 nsresult rv;
2765 nsCOMPtr<nsIUUIDGenerator> uuidgen =
2766 do_GetService("@mozilla.org/uuid-generator;1", &rv);
2767 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, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2767); return rv; } } while (false)
;
2768
2769 // Generate a call ID.
2770 nsID id;
2771 rv = uuidgen->GenerateUUIDInPlace(&id);
2772 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, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2772); return rv; } } while (false)
;
2773
2774 char buffer[NSID_LENGTH39];
2775 id.ToProvidedString(buffer);
2776 aResult.Assign(NS_ConvertUTF8toUTF16(buffer));
2777 return NS_OK;
2778}
2779
2780enum class GetUserMediaSecurityState {
2781 Other = 0,
2782 HTTPS = 1,
2783 File = 2,
2784 App = 3,
2785 Localhost = 4,
2786 Loop = 5,
2787 Privileged = 6
2788};
2789
2790/**
2791 * This function is used in getUserMedia when privacy.resistFingerprinting is
2792 * true. Only mediaSource of audio/video constraint will be kept. On mobile
2793 * facing mode is also kept.
2794 */
2795static void ReduceConstraint(
2796 OwningBooleanOrMediaTrackConstraints& aConstraint) {
2797 // Not requesting stream.
2798 if (!MediaManager::IsOn(aConstraint)) {
2799 return;
2800 }
2801
2802 // It looks like {audio: true}, do nothing.
2803 if (!aConstraint.IsMediaTrackConstraints()) {
2804 return;
2805 }
2806
2807 // Keep mediaSource.
2808 Maybe<nsString> mediaSource;
2809 if (aConstraint.GetAsMediaTrackConstraints().mMediaSource.WasPassed()) {
2810 mediaSource =
2811 Some(aConstraint.GetAsMediaTrackConstraints().mMediaSource.Value());
2812 }
2813
2814 Maybe<OwningStringOrStringSequenceOrConstrainDOMStringParameters> facingMode;
2815 if (aConstraint.GetAsMediaTrackConstraints().mFacingMode.WasPassed()) {
2816 facingMode =
2817 Some(aConstraint.GetAsMediaTrackConstraints().mFacingMode.Value());
2818 }
2819
2820 aConstraint.Uninit();
2821 if (mediaSource) {
2822 aConstraint.SetAsMediaTrackConstraints().mMediaSource.Construct(
2823 *mediaSource);
2824 } else {
2825 Unused << aConstraint.SetAsMediaTrackConstraints();
2826 }
2827
2828#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_UIKIT)
2829 if (facingMode) {
2830 aConstraint.SetAsMediaTrackConstraints().mFacingMode.Construct(*facingMode);
2831 } else {
2832 Unused << aConstraint.SetAsMediaTrackConstraints();
2833 }
2834#endif
2835}
2836
2837/**
2838 * The entry point for this file. A call from Navigator::mozGetUserMedia
2839 * will end up here. MediaManager is a singleton that is responsible
2840 * for handling all incoming getUserMedia calls from every window.
2841 */
2842RefPtr<MediaManager::StreamPromise> MediaManager::GetUserMedia(
2843 nsPIDOMWindowInner* aWindow,
2844 const MediaStreamConstraints& aConstraintsPassedIn,
2845 CallerType aCallerType) {
2846 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2846); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 2846; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2847 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2847); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindow" ")"
); do { *((volatile int*)__null) = 2847; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2848 uint64_t windowID = aWindow->WindowID();
2849
2850 MediaStreamConstraints c(aConstraintsPassedIn); // use a modifiable copy
2851
2852 if (sHasMainThreadShutdown) {
2853 return StreamPromise::CreateAndReject(
2854 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError,
2855 "In shutdown"),
2856 __func__);
2857 }
2858
2859 // Determine permissions early (while we still have a stack).
2860
2861 nsIURI* docURI = aWindow->GetDocumentURI();
2862 if (!docURI) {
2863 return StreamPromise::CreateAndReject(
2864 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError), __func__);
2865 }
2866 bool isChrome = (aCallerType == CallerType::System);
2867 bool privileged =
2868 isChrome ||
2869 Preferences::GetBool("media.navigator.permission.disabled", false);
2870 bool isSecure = aWindow->IsSecureContext();
2871 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
2872 nsCString host;
2873 nsresult rv = docURI->GetHost(host);
Value stored to 'rv' during its initialization is never read
2874
2875 nsCOMPtr<nsIPrincipal> principal =
2876 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
2877 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2877)
) {
2878 return StreamPromise::CreateAndReject(
2879 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2880 __func__);
2881 }
2882
2883 Document* doc = aWindow->GetExtantDoc();
2884 if (NS_WARN_IF(!doc)NS_warn_if_impl(!doc, "!doc", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2884)
) {
2885 return StreamPromise::CreateAndReject(
2886 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2887 __func__);
2888 }
2889
2890 // Disallow access to null principal pages and http pages (unless pref)
2891 if (principal->GetIsNullPrincipal() ||
2892 !(isSecure || StaticPrefs::media_getusermedia_insecure_enabled())) {
2893 return StreamPromise::CreateAndReject(
2894 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2895 __func__);
2896 }
2897
2898 // This principal needs to be sent to different threads and so via IPC.
2899 // For this reason it's better to convert it to PrincipalInfo right now.
2900 ipc::PrincipalInfo principalInfo;
2901 rv = PrincipalToPrincipalInfo(principal, &principalInfo);
2902 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 2902)
) {
2903 return StreamPromise::CreateAndReject(
2904 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
2905 __func__);
2906 }
2907
2908 const bool resistFingerprinting =
2909 !isChrome && doc->ShouldResistFingerprinting(RFPTarget::MediaDevices);
2910 if (resistFingerprinting) {
2911 ReduceConstraint(c.mVideo);
2912 ReduceConstraint(c.mAudio);
2913 }
2914
2915 if (!Preferences::GetBool("media.navigator.video.enabled", true)) {
2916 c.mVideo.SetAsBoolean() = false;
2917 }
2918
2919 MediaSourceEnum videoType = MediaSourceEnum::Other; // none
2920 MediaSourceEnum audioType = MediaSourceEnum::Other; // none
2921
2922 if (c.mVideo.IsMediaTrackConstraints()) {
2923 auto& vc = c.mVideo.GetAsMediaTrackConstraints();
2924 if (!vc.mMediaSource.WasPassed()) {
2925 vc.mMediaSource.Construct().AssignASCII(
2926 dom::GetEnumString(MediaSourceEnum::Camera));
2927 }
2928 videoType = dom::StringToEnum<MediaSourceEnum>(vc.mMediaSource.Value())
2929 .valueOr(MediaSourceEnum::Other);
2930 Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
2931 (uint32_t)videoType);
2932 switch (videoType) {
2933 case MediaSourceEnum::Camera:
2934 break;
2935
2936 case MediaSourceEnum::Browser:
2937 // If no window id is passed in then default to the caller's window.
2938 // Functional defaults are helpful in tests, but also a natural outcome
2939 // of the constraints API's limited semantics for requiring input.
2940 if (!vc.mBrowserWindow.WasPassed()) {
2941 nsPIDOMWindowOuter* outer = aWindow->GetOuterWindow();
2942 vc.mBrowserWindow.Construct(outer->WindowID());
2943 }
2944 [[fallthrough]];
2945 case MediaSourceEnum::Screen:
2946 case MediaSourceEnum::Window:
2947 // Deny screensharing request if support is disabled, or
2948 // the requesting document is not from a host on the whitelist.
2949 if (!Preferences::GetBool(
2950 ((videoType == MediaSourceEnum::Browser)
2951 ? "media.getusermedia.browser.enabled"
2952 : "media.getusermedia.screensharing.enabled"),
2953 false) ||
2954 (!privileged && !aWindow->IsSecureContext())) {
2955 return StreamPromise::CreateAndReject(
2956 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
2957 __func__);
2958 }
2959 break;
2960
2961 case MediaSourceEnum::Microphone:
2962 case MediaSourceEnum::Other:
2963 default: {
2964 return StreamPromise::CreateAndReject(
2965 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
2966 "", u"mediaSource"_ns),
2967 __func__);
2968 }
2969 }
2970
2971 if (!privileged) {
2972 // Only allow privileged content to explicitly pick full-screen,
2973 // application or tabsharing, since these modes are still available for
2974 // testing. All others get "Window" (*) sharing.
2975 //
2976 // *) We overload "Window" with the new default getDisplayMedia spec-
2977 // mandated behavior of not influencing user-choice, which we currently
2978 // implement as a list containing BOTH windows AND screen(s).
2979 //
2980 // Notes on why we chose "Window" as the one to overload. Two reasons:
2981 //
2982 // 1. It's the closest logically & behaviorally (multi-choice, no default)
2983 // 2. Screen is still useful in tests (implicit default is entire screen)
2984 //
2985 // For UX reasons we don't want "Entire Screen" to be the first/default
2986 // choice (in our code first=default). It's a "scary" source that comes
2987 // with complicated warnings on-top that would be confusing as the first
2988 // thing people see, and also deserves to be listed as last resort for
2989 // privacy reasons.
2990
2991 if (videoType == MediaSourceEnum::Screen ||
2992 videoType == MediaSourceEnum::Browser) {
2993 videoType = MediaSourceEnum::Window;
2994 vc.mMediaSource.Value().AssignASCII(dom::GetEnumString(videoType));
2995 }
2996 // only allow privileged content to set the window id
2997 if (vc.mBrowserWindow.WasPassed()) {
2998 vc.mBrowserWindow.Value() = -1;
2999 }
3000 if (vc.mAdvanced.WasPassed()) {
3001 for (MediaTrackConstraintSet& cs : vc.mAdvanced.Value()) {
3002 if (cs.mBrowserWindow.WasPassed()) {
3003 cs.mBrowserWindow.Value() = -1;
3004 }
3005 }
3006 }
3007 }
3008 } else if (IsOn(c.mVideo)) {
3009 videoType = MediaSourceEnum::Camera;
3010 Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
3011 (uint32_t)videoType);
3012 }
3013
3014 if (c.mAudio.IsMediaTrackConstraints()) {
3015 auto& ac = c.mAudio.GetAsMediaTrackConstraints();
3016 if (!ac.mMediaSource.WasPassed()) {
3017 ac.mMediaSource.Construct(NS_ConvertASCIItoUTF16(
3018 dom::GetEnumString(MediaSourceEnum::Microphone)));
3019 }
3020 audioType = dom::StringToEnum<MediaSourceEnum>(ac.mMediaSource.Value())
3021 .valueOr(MediaSourceEnum::Other);
3022 Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
3023 (uint32_t)audioType);
3024
3025 switch (audioType) {
3026 case MediaSourceEnum::Microphone:
3027 break;
3028
3029 case MediaSourceEnum::AudioCapture:
3030 // Only enable AudioCapture if the pref is enabled. If it's not, we can
3031 // deny right away.
3032 if (!Preferences::GetBool("media.getusermedia.audio.capture.enabled")) {
3033 return StreamPromise::CreateAndReject(
3034 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3035 __func__);
3036 }
3037 break;
3038
3039 case MediaSourceEnum::Other:
3040 default: {
3041 return StreamPromise::CreateAndReject(
3042 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::OverconstrainedError,
3043 "", u"mediaSource"_ns),
3044 __func__);
3045 }
3046 }
3047 } else if (IsOn(c.mAudio)) {
3048 audioType = MediaSourceEnum::Microphone;
3049 Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
3050 (uint32_t)audioType);
3051 }
3052
3053 // Create a window listener if it doesn't already exist.
3054 RefPtr<GetUserMediaWindowListener> windowListener =
3055 GetOrMakeWindowListener(aWindow);
3056 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3056); AnnotateMozCrashReason("MOZ_ASSERT" "(" "windowListener"
")"); do { *((volatile int*)__null) = 3056; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3057 // Create an inactive DeviceListener to act as a placeholder, so the
3058 // window listener doesn't clean itself up until we're done.
3059 auto placeholderListener = MakeRefPtr<DeviceListener>();
3060 windowListener->Register(placeholderListener);
3061
3062 { // Check Permissions Policy. Reject if a requested feature is disabled.
3063 bool disabled = !IsOn(c.mAudio) && !IsOn(c.mVideo);
3064 if (IsOn(c.mAudio)) {
3065 if (audioType == MediaSourceEnum::Microphone) {
3066 if (Preferences::GetBool("media.getusermedia.microphone.deny", false) ||
3067 !FeaturePolicyUtils::IsFeatureAllowed(doc, u"microphone"_ns)) {
3068 disabled = true;
3069 }
3070 } else if (!FeaturePolicyUtils::IsFeatureAllowed(doc,
3071 u"display-capture"_ns)) {
3072 disabled = true;
3073 }
3074 }
3075 if (IsOn(c.mVideo)) {
3076 if (videoType == MediaSourceEnum::Camera) {
3077 if (Preferences::GetBool("media.getusermedia.camera.deny", false) ||
3078 !FeaturePolicyUtils::IsFeatureAllowed(doc, u"camera"_ns)) {
3079 disabled = true;
3080 }
3081 } else if (!FeaturePolicyUtils::IsFeatureAllowed(doc,
3082 u"display-capture"_ns)) {
3083 disabled = true;
3084 }
3085 }
3086
3087 if (disabled) {
3088 placeholderListener->Stop();
3089 return StreamPromise::CreateAndReject(
3090 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3091 __func__);
3092 }
3093 }
3094
3095 // Get list of all devices, with origin-specific device ids.
3096
3097 MediaEnginePrefs prefs = mPrefs;
3098
3099 nsString callID;
3100 rv = GenerateUUID(callID);
3101 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3101); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3101; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3102
3103 bool hasVideo = videoType != MediaSourceEnum::Other;
3104 bool hasAudio = audioType != MediaSourceEnum::Other;
3105
3106 // Handle fake requests from content. For gUM we don't consider resist
3107 // fingerprinting as users should be prompted anyway.
3108 bool forceFakes = c.mFake.WasPassed() && c.mFake.Value();
3109 // fake:true is effective only for microphone and camera devices, so
3110 // permission must be requested for screen capture even if fake:true is set.
3111 bool hasOnlyForcedFakes =
3112 forceFakes && (!hasVideo || videoType == MediaSourceEnum::Camera) &&
3113 (!hasAudio || audioType == MediaSourceEnum::Microphone);
3114 bool askPermission =
3115 (!privileged ||
3116 Preferences::GetBool("media.navigator.permission.force")) &&
3117 (!hasOnlyForcedFakes ||
3118 Preferences::GetBool("media.navigator.permission.fake"));
3119
3120 LOG("%s: Preparing to enumerate devices. windowId=%" PRIu64"l" "u"
3121 ", videoType=%" PRIu8"u" ", audioType=%" PRIu8"u"
3122 ", forceFakes=%s, askPermission=%s",
3123 __func__, windowID, static_cast<uint8_t>(videoType),
3124 static_cast<uint8_t>(audioType), forceFakes ? "true" : "false",
3125 askPermission ? "true" : "false");
3126
3127 EnumerationFlags flags = EnumerationFlag::AllowPermissionRequest;
3128 if (forceFakes) {
3129 flags += EnumerationFlag::ForceFakes;
3130 }
3131 RefPtr<MediaManager> self = this;
3132 return EnumerateDevicesImpl(
3133 aWindow, CreateEnumerationParams(videoType, audioType, flags))
3134 ->Then(
3135 GetCurrentSerialEventTarget(), __func__,
3136 [self, windowID, c, windowListener,
3137 aCallerType](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) {
3138 LOG("GetUserMedia: post enumeration promise success callback "
3139 "starting");
3140 // Ensure that our windowID is still good.
3141 RefPtr<nsPIDOMWindowInner> window =
3142 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3143 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3144 LOG("GetUserMedia: bad window (%" PRIu64"l" "u"
3145 ") in post enumeration success callback!",
3146 windowID);
3147 return LocalDeviceSetPromise::CreateAndReject(
3148 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3149 __func__);
3150 }
3151 // Apply any constraints. This modifies the passed-in list.
3152 return self->SelectSettings(c, aCallerType, std::move(aDevices));
3153 },
3154 [](RefPtr<MediaMgrError>&& aError) {
3155 LOG("GetUserMedia: post enumeration EnumerateDevicesImpl "
3156 "failure callback called!");
3157 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3158 __func__);
3159 })
3160 ->Then(
3161 GetCurrentSerialEventTarget(), __func__,
3162 [self, windowID, c, windowListener, placeholderListener, hasAudio,
3163 hasVideo, askPermission, prefs, isSecure, isHandlingUserInput,
3164 callID, principalInfo, aCallerType, resistFingerprinting,
3165 audioType](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3166 LOG("GetUserMedia: starting post enumeration promise2 success "
3167 "callback!");
3168
3169 // Ensure that the window is still good.
3170 RefPtr<nsPIDOMWindowInner> window =
3171 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3172 if (!window || !self->IsWindowListenerStillActive(windowListener)) {
3173 LOG("GetUserMedia: bad window (%" PRIu64"l" "u"
3174 ") in post enumeration success callback 2!",
3175 windowID);
3176 placeholderListener->Stop();
3177 return StreamPromise::CreateAndReject(
3178 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3179 __func__);
3180 }
3181 if (!aDevices->Length()) {
3182 LOG("GetUserMedia: no devices found in post enumeration promise2 "
3183 "success callback! Calling error handler!");
3184 placeholderListener->Stop();
3185 // When privacy.resistFingerprinting = true, no
3186 // available device implies content script is requesting
3187 // a fake device, so report NotAllowedError.
3188 auto error = resistFingerprinting
3189 ? MediaMgrError::Name::NotAllowedError
3190 : MediaMgrError::Name::NotFoundError;
3191 return StreamPromise::CreateAndReject(
3192 MakeRefPtr<MediaMgrError>(error), __func__);
3193 }
3194
3195 // Time to start devices. Create the necessary device listeners and
3196 // remove the placeholder.
3197 RefPtr<DeviceListener> audioListener;
3198 RefPtr<DeviceListener> videoListener;
3199 if (hasAudio) {
3200 audioListener = MakeRefPtr<DeviceListener>();
3201 windowListener->Register(audioListener);
3202 }
3203 if (hasVideo) {
3204 videoListener = MakeRefPtr<DeviceListener>();
3205 windowListener->Register(videoListener);
3206 }
3207 placeholderListener->Stop();
3208
3209 bool focusSource = mozilla::Preferences::GetBool(
3210 "media.getusermedia.window.focus_source.enabled", true);
3211
3212 // Incremental hack to compile. To be replaced by deeper
3213 // refactoring. MediaManager allows
3214 // "neither-resolve-nor-reject" semantics, so we cannot
3215 // use MozPromiseHolder here.
3216 MozPromiseHolder<StreamPromise> holder;
3217 RefPtr<StreamPromise> p = holder.Ensure(__func__);
3218
3219 // Pass callbacks and listeners along to GetUserMediaStreamTask.
3220 auto task = MakeRefPtr<GetUserMediaStreamTask>(
3221 c, std::move(holder), windowID, std::move(windowListener),
3222 std::move(audioListener), std::move(videoListener), prefs,
3223 principalInfo, aCallerType, focusSource);
3224
3225 // It is time to ask for user permission, prime voice processing
3226 // now. Use a local lambda to enable a guard pattern.
3227 [&] {
3228 if (audioType != MediaSourceEnum::Microphone) {
3229 return;
3230 }
3231
3232 if (!StaticPrefs::
3233 media_getusermedia_microphone_voice_stream_priming_enabled() ||
3234 !StaticPrefs::
3235 media_getusermedia_microphone_prefer_voice_stream_with_processing_enabled()) {
3236 return;
3237 }
3238
3239 if (const auto fc = FlattenedConstraints(
3240 NormalizedConstraints(GetInvariant(c.mAudio)));
3241 !fc.mEchoCancellation.Get(prefs.mAecOn) &&
3242 !fc.mAutoGainControl.Get(prefs.mAgcOn && prefs.mAecOn) &&
3243 !fc.mNoiseSuppression.Get(prefs.mNoiseOn && prefs.mAecOn)) {
3244 return;
3245 }
3246
3247 if (GetPersistentPermissions(windowID)
3248 .map([](auto&& aState) {
3249 return aState.mMicrophonePermission ==
3250 PersistentPermissionState::Deny;
3251 })
3252 .unwrapOr(true)) {
3253 return;
3254 }
3255
3256 task->PrimeVoiceProcessing();
3257 }();
3258
3259 size_t taskCount =
3260 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3261
3262 if (!askPermission) {
3263 self->NotifyAllowed(callID, *aDevices);
3264 } else {
3265 auto req = MakeRefPtr<GetUserMediaRequest>(
3266 window, callID, std::move(aDevices), c, isSecure,
3267 isHandlingUserInput);
3268 if (!Preferences::GetBool("media.navigator.permission.force") &&
3269 taskCount > 1) {
3270 // there is at least 1 pending gUM request
3271 // For the scarySources test case, always send the
3272 // request
3273 self->mPendingGUMRequest.AppendElement(req.forget());
3274 } else {
3275 nsCOMPtr<nsIObserverService> obs =
3276 services::GetObserverService();
3277 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3278 }
3279 }
3280#ifdef MOZ_WEBRTC1
3281 self->mLogHandle = EnsureWebrtcLogging();
3282#endif
3283 return p;
3284 },
3285 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3286 LOG("GetUserMedia: post enumeration SelectSettings failure "
3287 "callback called!");
3288 placeholderListener->Stop();
3289 return StreamPromise::CreateAndReject(std::move(aError), __func__);
3290 });
3291};
3292
3293RefPtr<LocalDeviceSetPromise> MediaManager::AnonymizeDevices(
3294 nsPIDOMWindowInner* aWindow, RefPtr<const MediaDeviceSetRefCnt> aDevices) {
3295 // Get an origin-key (for either regular or private browsing).
3296 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3297 uint64_t windowId = aWindow->WindowID();
3298 nsCOMPtr<nsIPrincipal> principal =
3299 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3300 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3300); AnnotateMozCrashReason("MOZ_ASSERT" "(" "principal" ")"
); do { *((volatile int*)__null) = 3300; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3301 ipc::PrincipalInfo principalInfo;
3302 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3303 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3303)
) {
3304 return LocalDeviceSetPromise::CreateAndReject(
3305 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3306 __func__);
3307 }
3308 bool resistFingerprinting =
3309 aWindow->AsGlobal()->ShouldResistFingerprinting(RFPTarget::MediaDevices);
3310 bool persist =
3311 IsActivelyCapturingOrHasAPermission(windowId) && !resistFingerprinting;
3312 return media::GetPrincipalKey(principalInfo, persist)
3313 ->Then(
3314 GetMainThreadSerialEventTarget(), __func__,
3315 [rawDevices = std::move(aDevices), windowId,
3316 resistFingerprinting](const nsCString& aOriginKey) {
3317 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3317); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aOriginKey.IsEmpty()"
")"); do { *((volatile int*)__null) = 3317; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3318 RefPtr anonymized = new LocalMediaDeviceSetRefCnt();
3319 for (const RefPtr<MediaDevice>& device : *rawDevices) {
3320 nsString name = device->mRawName;
3321 if (name.Find(u"AirPods"_ns) != -1) {
3322 name = u"AirPods"_ns;
3323 }
3324
3325 nsString id = device->mRawID;
3326 if (resistFingerprinting) {
3327 nsRFPService::GetMediaDeviceName(name, device->mKind);
3328 id = name;
3329 id.AppendInt(windowId);
3330 }
3331 // An empty id represents a virtual default device, for which
3332 // the exposed deviceId is the empty string.
3333 if (!id.IsEmpty()) {
3334 nsContentUtils::AnonymizeId(id, aOriginKey);
3335 }
3336
3337 nsString groupId = device->mRawGroupID;
3338 if (resistFingerprinting) {
3339 nsRFPService::GetMediaDeviceGroup(groupId, device->mKind);
3340 }
3341 // Use window id to salt group id in order to make it session
3342 // based as required by the spec. This does not provide unique
3343 // group ids through out a browser restart. However, this is not
3344 // against the spec. Furthermore, since device ids are the same
3345 // after a browser restart the fingerprint is not bigger.
3346 groupId.AppendInt(windowId);
3347 nsContentUtils::AnonymizeId(groupId, aOriginKey);
3348 anonymized->EmplaceBack(
3349 new LocalMediaDevice(device, id, groupId, name));
3350 }
3351 return LocalDeviceSetPromise::CreateAndResolve(anonymized,
3352 __func__);
3353 },
3354 [](nsresult rs) {
3355 NS_WARNING("AnonymizeDevices failed to get Principal Key")NS_DebugBreak(NS_DEBUG_WARNING, "AnonymizeDevices failed to get Principal Key"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3355)
;
3356 return LocalDeviceSetPromise::CreateAndReject(
3357 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3358 __func__);
3359 });
3360}
3361
3362RefPtr<LocalDeviceSetPromise> MediaManager::EnumerateDevicesImpl(
3363 nsPIDOMWindowInner* aWindow, EnumerationParams aParams) {
3364 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3364); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3364; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3365
3366 uint64_t windowId = aWindow->WindowID();
3367 LOG("%s: windowId=%" PRIu64"l" "u" ", aVideoInputType=%" PRIu8"u"
3368 ", aAudioInputType=%" PRIu8"u",
3369 __func__, windowId, static_cast<uint8_t>(aParams.VideoInputType()),
3370 static_cast<uint8_t>(aParams.AudioInputType()));
3371
3372 // To get a device list anonymized for a particular origin, we must:
3373 // 1. Get the raw devices list
3374 // 2. Anonymize the raw list with an origin-key.
3375
3376 // Add the window id here to check for that and abort silently if no longer
3377 // exists.
3378 RefPtr<GetUserMediaWindowListener> windowListener =
3379 GetOrMakeWindowListener(aWindow);
3380 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3380); AnnotateMozCrashReason("MOZ_ASSERT" "(" "windowListener"
")"); do { *((volatile int*)__null) = 3380; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3381 // Create an inactive DeviceListener to act as a placeholder, so the
3382 // window listener doesn't clean itself up until we're done.
3383 auto placeholderListener = MakeRefPtr<DeviceListener>();
3384 windowListener->Register(placeholderListener);
3385
3386 return MaybeRequestPermissionAndEnumerateRawDevices(std::move(aParams))
3387 ->Then(
3388 GetMainThreadSerialEventTarget(), __func__,
3389 [self = RefPtr(this), this, window = nsCOMPtr(aWindow),
3390 placeholderListener](RefPtr<MediaDeviceSetRefCnt> aDevices) mutable {
3391 // Only run if window is still on our active list.
3392 MediaManager* mgr = MediaManager::GetIfExists();
3393 if (!mgr || placeholderListener->Stopped()) {
3394 // The listener has already been removed if the window is no
3395 // longer active.
3396 return LocalDeviceSetPromise::CreateAndReject(
3397 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3398 __func__);
3399 }
3400 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())"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mgr->IsWindowStillActive(window->WindowID())"
")"); do { *((volatile int*)__null) = 3400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3401 placeholderListener->Stop();
3402 return AnonymizeDevices(window, aDevices);
3403 },
3404 [placeholderListener](RefPtr<MediaMgrError>&& aError) {
3405 // EnumerateDevicesImpl may fail if a new doc has been set, in which
3406 // case the OnNavigation() method should have removed all previous
3407 // active listeners, or if a platform device access request was not
3408 // granted.
3409 placeholderListener->Stop();
3410 return LocalDeviceSetPromise::CreateAndReject(std::move(aError),
3411 __func__);
3412 });
3413}
3414
3415RefPtr<LocalDevicePromise> MediaManager::SelectAudioOutput(
3416 nsPIDOMWindowInner* aWindow, const dom::AudioOutputOptions& aOptions,
3417 CallerType aCallerType) {
3418 bool isHandlingUserInput = UserActivation::IsHandlingUserInput();
3419 nsCOMPtr<nsIPrincipal> principal =
3420 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
3421 if (!FeaturePolicyUtils::IsFeatureAllowed(aWindow->GetExtantDoc(),
3422 u"speaker-selection"_ns)) {
3423 return LocalDevicePromise::CreateAndReject(
3424 MakeRefPtr<MediaMgrError>(
3425 MediaMgrError::Name::NotAllowedError,
3426 "Document's Permissions Policy does not allow selectAudioOutput()"),
3427 __func__);
3428 }
3429 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3429)
) {
3430 return LocalDevicePromise::CreateAndReject(
3431 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3432 __func__);
3433 }
3434 // Disallow access to null principal.
3435 if (principal->GetIsNullPrincipal()) {
3436 return LocalDevicePromise::CreateAndReject(
3437 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::NotAllowedError),
3438 __func__);
3439 }
3440 ipc::PrincipalInfo principalInfo;
3441 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
3442 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3442)
) {
3443 return LocalDevicePromise::CreateAndReject(
3444 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::SecurityError),
3445 __func__);
3446 }
3447 uint64_t windowID = aWindow->WindowID();
3448 const bool resistFingerprinting =
3449 aWindow->AsGlobal()->ShouldResistFingerprinting(aCallerType,
3450 RFPTarget::MediaDevices);
3451 return EnumerateDevicesImpl(
3452 aWindow, CreateEnumerationParams(
3453 MediaSourceEnum::Other, MediaSourceEnum::Other,
3454 {EnumerationFlag::EnumerateAudioOutputs,
3455 EnumerationFlag::AllowPermissionRequest}))
3456 ->Then(
3457 GetCurrentSerialEventTarget(), __func__,
3458 [self = RefPtr<MediaManager>(this), windowID, aOptions, aCallerType,
3459 resistFingerprinting, isHandlingUserInput,
3460 principalInfo](RefPtr<LocalMediaDeviceSetRefCnt> aDevices) mutable {
3461 // Ensure that the window is still good.
3462 RefPtr<nsPIDOMWindowInner> window =
3463 nsGlobalWindowInner::GetInnerWindowWithId(windowID);
3464 if (!window) {
3465 LOG("SelectAudioOutput: bad window (%" PRIu64"l" "u"
3466 ") in post enumeration success callback!",
3467 windowID);
3468 return LocalDevicePromise::CreateAndReject(
3469 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError),
3470 __func__);
3471 }
3472 if (aDevices->IsEmpty()) {
3473 LOG("SelectAudioOutput: no devices found");
3474 auto error = resistFingerprinting
3475 ? MediaMgrError::Name::NotAllowedError
3476 : MediaMgrError::Name::NotFoundError;
3477 return LocalDevicePromise::CreateAndReject(
3478 MakeRefPtr<MediaMgrError>(error), __func__);
3479 }
3480 MozPromiseHolder<LocalDevicePromise> holder;
3481 RefPtr<LocalDevicePromise> p = holder.Ensure(__func__);
3482 auto task = MakeRefPtr<SelectAudioOutputTask>(
3483 std::move(holder), windowID, aCallerType, principalInfo);
3484 nsString callID;
3485 nsresult rv = GenerateUUID(callID);
3486 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3486); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3486; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3487 size_t taskCount =
3488 self->AddTaskAndGetCount(windowID, callID, std::move(task));
3489 bool askPermission =
3490 !Preferences::GetBool("media.navigator.permission.disabled") ||
3491 Preferences::GetBool("media.navigator.permission.force");
3492 if (!askPermission) {
3493 self->NotifyAllowed(callID, *aDevices);
3494 } else {
3495 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window->IsSecureContext()"
")"); do { *((volatile int*)__null) = 3495; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3496 auto req = MakeRefPtr<GetUserMediaRequest>(
3497 window, callID, std::move(aDevices), aOptions, true,
3498 isHandlingUserInput);
3499 if (taskCount > 1) {
3500 // there is at least 1 pending gUM request
3501 self->mPendingGUMRequest.AppendElement(req.forget());
3502 } else {
3503 nsCOMPtr<nsIObserverService> obs =
3504 services::GetObserverService();
3505 obs->NotifyObservers(req, "getUserMedia:request", nullptr);
3506 }
3507 }
3508 return p;
3509 },
3510 [](RefPtr<MediaMgrError> aError) {
3511 LOG("SelectAudioOutput: EnumerateDevicesImpl "
3512 "failure callback called!");
3513 return LocalDevicePromise::CreateAndReject(std::move(aError),
3514 __func__);
3515 });
3516}
3517
3518MediaEngine* MediaManager::GetBackend() {
3519 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3519); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3519; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3520 // Plugin backends as appropriate. The default engine also currently
3521 // includes picture support for Android.
3522 // This IS called off main-thread.
3523 if (!mBackend) {
3524#if defined(MOZ_WEBRTC1)
3525 mBackend = new MediaEngineWebRTC();
3526#else
3527 mBackend = new MediaEngineFake();
3528#endif
3529 mDeviceListChangeListener = mBackend->DeviceListChangeEvent().Connect(
3530 AbstractThread::MainThread(), this, &MediaManager::DeviceListChanged);
3531 }
3532 return mBackend;
3533}
3534
3535void MediaManager::OnNavigation(uint64_t aWindowID) {
3536 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3536); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3536; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3537 LOG("OnNavigation for %" PRIu64"l" "u", aWindowID);
3538
3539 // Stop the streams for this window. The runnables check this value before
3540 // making a call to content.
3541
3542 nsTArray<nsString>* callIDs;
3543 if (mCallIds.Get(aWindowID, &callIDs)) {
3544 for (auto& callID : *callIDs) {
3545 mActiveCallbacks.Remove(callID);
3546 for (auto& request : mPendingGUMRequest.Clone()) {
3547 nsString id;
3548 request->GetCallID(id);
3549 if (id == callID) {
3550 mPendingGUMRequest.RemoveElement(request);
3551 }
3552 }
3553 }
3554 mCallIds.Remove(aWindowID);
3555 }
3556
3557 if (RefPtr<GetUserMediaWindowListener> listener =
3558 GetWindowListener(aWindowID)) {
3559 listener->RemoveAll();
3560 }
3561 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)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3561); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowListener(aWindowID)"
")"); do { *((volatile int*)__null) = 3561; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3562}
3563
3564void MediaManager::OnCameraMute(bool aMute) {
3565 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3565; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3566 LOG("OnCameraMute for all windows");
3567 mCamerasMuted = aMute;
3568 // This is safe since we're on main-thread, and the windowlist can only
3569 // be added to from the main-thread
3570 for (const auto& window : mActiveWindows.Values()) {
3571 window->MuteOrUnmuteCameras(aMute);
3572 }
3573}
3574
3575void MediaManager::OnMicrophoneMute(bool aMute) {
3576 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3576); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3576; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3577 LOG("OnMicrophoneMute for all windows");
3578 mMicrophonesMuted = aMute;
3579 // This is safe since we're on main-thread, and the windowlist can only
3580 // be added to from the main-thread
3581 for (const auto& window : mActiveWindows.Values()) {
3582 window->MuteOrUnmuteMicrophones(aMute);
3583 }
3584}
3585
3586RefPtr<GetUserMediaWindowListener> MediaManager::GetOrMakeWindowListener(
3587 nsPIDOMWindowInner* aWindow) {
3588 Document* doc = aWindow->GetExtantDoc();
3589 if (!doc) {
3590 // The window has been destroyed. Destroyed windows don't have listeners.
3591 return nullptr;
3592 }
3593 nsIPrincipal* principal = doc->NodePrincipal();
3594 uint64_t windowId = aWindow->WindowID();
3595 RefPtr<GetUserMediaWindowListener> windowListener =
3596 GetWindowListener(windowId);
3597 if (windowListener) {
3598 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { *((volatile int*)__null) = 3599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3599 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PrincipalHandleMatches(windowListener->GetPrincipalHandle(), principal)"
")"); do { *((volatile int*)__null) = 3599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3600 } else {
3601 windowListener = new GetUserMediaWindowListener(
3602 windowId, MakePrincipalHandle(principal));
3603 AddWindowID(windowId, windowListener);
3604 }
3605 return windowListener;
3606}
3607
3608void MediaManager::AddWindowID(uint64_t aWindowId,
3609 RefPtr<GetUserMediaWindowListener> aListener) {
3610 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3610; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3611 // Store the WindowID in a hash table and mark as active. The entry is removed
3612 // when this window is closed or navigated away from.
3613 // This is safe since we're on main-thread, and the windowlist can only
3614 // be invalidated from the main-thread (see OnNavigation)
3615 if (IsWindowStillActive(aWindowId)) {
3616 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Window already added" ")"); do { *((volatile int*)__null) =
3616; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
3617 return;
3618 }
3619
3620 aListener->MuteOrUnmuteCameras(mCamerasMuted);
3621 aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted);
3622 GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener));
3623
3624 RefPtr<WindowGlobalChild> wgc =
3625 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3626 if (wgc) {
3627 wgc->BlockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3628 }
3629}
3630
3631void MediaManager::RemoveWindowID(uint64_t aWindowId) {
3632 RefPtr<WindowGlobalChild> wgc =
3633 WindowGlobalChild::GetByInnerWindowId(aWindowId);
3634 if (wgc) {
3635 wgc->UnblockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
3636 }
3637
3638 mActiveWindows.Remove(aWindowId);
3639
3640 // get outer windowID
3641 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId);
3642 if (!window) {
3643 LOG("No inner window for %" PRIu64"l" "u", aWindowId);
3644 return;
3645 }
3646
3647 auto* outer = window->GetOuterWindow();
3648 if (!outer) {
3649 LOG("No outer window for inner %" PRIu64"l" "u", aWindowId);
3650 return;
3651 }
3652
3653 uint64_t outerID = outer->WindowID();
3654
3655 // Notify the UI that this window no longer has gUM active
3656 char windowBuffer[32];
3657 SprintfLiteral(windowBuffer, "%" PRIu64"l" "u", outerID);
3658 nsString data = NS_ConvertUTF8toUTF16(windowBuffer);
3659
3660 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3661 obs->NotifyWhenScriptSafe(nullptr, "recording-window-ended", data.get());
3662 LOG("Sent recording-window-ended for window %" PRIu64"l" "u" " (outer %" PRIu64"l" "u" ")",
3663 aWindowId, outerID);
3664}
3665
3666bool MediaManager::IsWindowListenerStillActive(
3667 const RefPtr<GetUserMediaWindowListener>& aListener) {
3668 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3668); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aListener"
")"); do { *((volatile int*)__null) = 3668; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3669 return aListener && aListener == GetWindowListener(aListener->WindowID());
3670}
3671
3672void MediaManager::GetPref(nsIPrefBranch* aBranch, const char* aPref,
3673 const char* aData, int32_t* aVal) {
3674 int32_t temp;
3675 if (aData == nullptr || strcmp(aPref, aData) == 0) {
3676 if (NS_SUCCEEDED(aBranch->GetIntPref(aPref, &temp))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aBranch->GetIntPref
(aPref, &temp))), 1)))
) {
3677 *aVal = temp;
3678 }
3679 }
3680}
3681
3682void MediaManager::GetPrefBool(nsIPrefBranch* aBranch, const char* aPref,
3683 const char* aData, bool* aVal) {
3684 bool temp;
3685 if (aData == nullptr || strcmp(aPref, aData) == 0) {
3686 if (NS_SUCCEEDED(aBranch->GetBoolPref(aPref, &temp))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aBranch->GetBoolPref
(aPref, &temp))), 1)))
) {
3687 *aVal = temp;
3688 }
3689 }
3690}
3691
3692void MediaManager::GetPrefs(nsIPrefBranch* aBranch, const char* aData) {
3693 GetPref(aBranch, "media.navigator.video.default_width", aData,
3694 &mPrefs.mWidth);
3695 GetPref(aBranch, "media.navigator.video.default_height", aData,
3696 &mPrefs.mHeight);
3697 GetPref(aBranch, "media.navigator.video.default_fps", aData, &mPrefs.mFPS);
3698 GetPref(aBranch, "media.navigator.audio.fake_frequency", aData,
3699 &mPrefs.mFreq);
3700#ifdef MOZ_WEBRTC1
3701 GetPrefBool(aBranch, "media.getusermedia.audio.processing.platform.enabled",
3702 aData, &mPrefs.mUsePlatformProcessing);
3703 GetPrefBool(aBranch, "media.getusermedia.audio.processing.aec.enabled", aData,
3704 &mPrefs.mAecOn);
3705 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc.enabled", aData,
3706 &mPrefs.mAgcOn);
3707 GetPrefBool(aBranch, "media.getusermedia.audio.processing.hpf.enabled", aData,
3708 &mPrefs.mHPFOn);
3709 GetPrefBool(aBranch, "media.getusermedia.audio.processing.noise.enabled",
3710 aData, &mPrefs.mNoiseOn);
3711 GetPrefBool(aBranch, "media.getusermedia.audio.processing.transient.enabled",
3712 aData, &mPrefs.mTransientOn);
3713 GetPrefBool(aBranch, "media.getusermedia.audio.processing.agc2.forced", aData,
3714 &mPrefs.mAgc2Forced);
3715 // Use 0 or 1 to force to false or true
3716 // EchoCanceller3Config::echo_removal_control.has_clock_drift.
3717 // -1 is the default, which means automatically set has_clock_drift as
3718 // deemed appropriate.
3719 GetPref(aBranch, "media.getusermedia.audio.processing.aec.expect_drift",
3720 aData, &mPrefs.mExpectDrift);
3721 GetPref(aBranch, "media.getusermedia.audio.processing.agc", aData,
3722 &mPrefs.mAgc);
3723 GetPref(aBranch, "media.getusermedia.audio.processing.noise", aData,
3724 &mPrefs.mNoise);
3725 GetPref(aBranch, "media.getusermedia.audio.max_channels", aData,
3726 &mPrefs.mChannels);
3727#endif
3728 LOG("%s: default prefs: %dx%d @%dfps, %dHz test tones, platform processing: "
3729 "%s, aec: %s, agc: %s, hpf: %s, noise: %s, drift: %s, agc level: %d, agc "
3730 "version: "
3731 "%s, noise level: %d, transient: %s, channels %d",
3732 __FUNCTION__, mPrefs.mWidth, mPrefs.mHeight, mPrefs.mFPS, mPrefs.mFreq,
3733 mPrefs.mUsePlatformProcessing ? "on" : "off",
3734 mPrefs.mAecOn ? "on" : "off", mPrefs.mAgcOn ? "on" : "off",
3735 mPrefs.mHPFOn ? "on" : "off", mPrefs.mNoiseOn ? "on" : "off",
3736 mPrefs.mExpectDrift < 0 ? "auto"
3737 : mPrefs.mExpectDrift ? "on"
3738 : "off",
3739 mPrefs.mAgc, mPrefs.mAgc2Forced ? "2" : "1", mPrefs.mNoise,
3740 mPrefs.mTransientOn ? "on" : "off", mPrefs.mChannels);
3741}
3742
3743void MediaManager::Shutdown() {
3744 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3744); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3744; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3745 if (sHasMainThreadShutdown) {
3746 return;
3747 }
3748
3749 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3750
3751 obs->RemoveObserver(this, "last-pb-context-exited");
3752 obs->RemoveObserver(this, "getUserMedia:privileged:allow");
3753 obs->RemoveObserver(this, "getUserMedia:response:allow");
3754 obs->RemoveObserver(this, "getUserMedia:response:deny");
3755 obs->RemoveObserver(this, "getUserMedia:response:noOSPermission");
3756 obs->RemoveObserver(this, "getUserMedia:revoke");
3757 obs->RemoveObserver(this, "getUserMedia:muteVideo");
3758 obs->RemoveObserver(this, "getUserMedia:unmuteVideo");
3759 obs->RemoveObserver(this, "getUserMedia:muteAudio");
3760 obs->RemoveObserver(this, "getUserMedia:unmuteAudio");
3761 obs->RemoveObserver(this, "application-background");
3762 obs->RemoveObserver(this, "application-foreground");
3763
3764 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1");
3765 if (prefs) {
3766 ForeachObservedPref([&](const nsLiteralCString& aPrefName) {
3767 prefs->RemoveObserver(aPrefName, this);
3768 });
3769 }
3770
3771 if (mDeviceChangeTimer) {
3772 mDeviceChangeTimer->Cancel();
3773 // Drop ref to MediaTimer early to avoid blocking SharedThreadPool shutdown
3774 mDeviceChangeTimer = nullptr;
3775 }
3776
3777 {
3778 // Close off any remaining active windows.
3779
3780 // Live capture at this point is rare but can happen. Stopping it will make
3781 // the window listeners attempt to remove themselves from the active windows
3782 // table. We cannot touch the table at point so we grab a copy of the window
3783 // listeners first.
3784 const auto listeners = ToArray(GetActiveWindows()->Values());
3785 for (const auto& listener : listeners) {
3786 listener->RemoveAll();
3787 }
3788 }
3789 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetActiveWindows()->Count() == 0"
")"); do { *((volatile int*)__null) = 3789; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3790
3791 GetActiveWindows()->Clear();
3792 mActiveCallbacks.Clear();
3793 mCallIds.Clear();
3794 mPendingGUMRequest.Clear();
3795#ifdef MOZ_WEBRTC1
3796 mLogHandle = nullptr;
3797#endif
3798
3799 // From main thread's point of view, shutdown is now done.
3800 // All that remains is shutting down the media thread.
3801 sHasMainThreadShutdown = true;
3802
3803 // Release the backend (and call Shutdown()) from within mMediaThread.
3804 // Don't use MediaManager::Dispatch() because we're
3805 // sHasMainThreadShutdown == true here!
3806 MOZ_ALWAYS_SUCCEEDS(mMediaThread->Dispatch(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3807 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]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3808 LOG("MediaManager Thread Shutdown");do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3809 MOZ_ASSERT(IsInMediaThread());do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3810 // 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]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3811 // where we started it from!do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3812 if (mBackend) {do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3813 mBackend->Shutdown(); // idempotentdo { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3814 mDeviceListChangeListener.DisconnectIfExists();do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3815 }do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3816 // last reference, will invoke Shutdown() againdo { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3817 mBackend = nullptr;do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
3818 })))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [
self = RefPtr(this), this]() { LOG("MediaManager Thread Shutdown"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsInMediaThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsInMediaThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInMediaThread()"
")"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); if (mBackend
) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists
(); } mBackend = nullptr; })))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3818); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mMediaThread->Dispatch( NS_NewRunnableFunction(__func__, [self = RefPtr(this), this]() { LOG(\"MediaManager Thread Shutdown\"); do { static_assert( mozilla::detail::AssertionConditionType<decltype(IsInMediaThread())>::isValid, \"invalid assertion condition\"); if ((__builtin_expect(!!(!(!!(IsInMediaThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(\"IsInMediaThread()\", \"/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp\", 3809); AnnotateMozCrashReason(\"MOZ_ASSERT\" \"(\" \"IsInMediaThread()\" \")\"); do { *((volatile int*)__null) = 3809; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (mBackend) { mBackend->Shutdown(); mDeviceListChangeListener.DisconnectIfExists(); } mBackend = nullptr; })))"
")"); do { *((volatile int*)__null) = 3818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3819
3820 // note that this == sSingleton
3821 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3821); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this == sSingleton"
")"); do { *((volatile int*)__null) = 3821; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3822
3823 // Explicitly shut down the TaskQueue so that it releases its
3824 // SharedThreadPool when all tasks have completed. SharedThreadPool blocks
3825 // XPCOM shutdown from proceeding beyond "xpcom-shutdown-threads" until all
3826 // SharedThreadPools are released, but the nsComponentManager keeps a
3827 // reference to the MediaManager for the nsIMediaManagerService until much
3828 // later in shutdown. This also provides additional assurance that no
3829 // further tasks will be queued.
3830 mMediaThread->BeginShutdown()->Then(
3831 GetMainThreadSerialEventTarget(), __func__, [] {
3832 LOG("MediaManager shutdown lambda running, releasing MediaManager "
3833 "singleton");
3834 // Remove async shutdown blocker
3835 media::MustGetShutdownBarrier()->RemoveBlocker(
3836 sSingleton->mShutdownBlocker);
3837
3838 sSingleton = nullptr;
3839 });
3840}
3841
3842void MediaManager::SendPendingGUMRequest() {
3843 if (mPendingGUMRequest.Length() > 0) {
3844 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
3845 obs->NotifyObservers(mPendingGUMRequest[0], "getUserMedia:request",
3846 nullptr);
3847 mPendingGUMRequest.RemoveElementAt(0);
3848 }
3849}
3850
3851bool IsGUMResponseNoAccess(const char* aTopic,
3852 MediaMgrError::Name& aErrorName) {
3853 if (!strcmp(aTopic, "getUserMedia:response:deny")) {
3854 aErrorName = MediaMgrError::Name::NotAllowedError;
3855 return true;
3856 }
3857
3858 if (!strcmp(aTopic, "getUserMedia:response:noOSPermission")) {
3859 aErrorName = MediaMgrError::Name::NotFoundError;
3860 return true;
3861 }
3862
3863 return false;
3864}
3865
3866static MediaSourceEnum ParseScreenColonWindowID(const char16_t* aData,
3867 uint64_t* aWindowIDOut) {
3868 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindowIDOut"
")"); do { *((volatile int*)__null) = 3868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3869 // may be windowid or screen:windowid
3870 const nsDependentString data(aData);
3871 if (Substring(data, 0, strlen("screen:")).EqualsLiteral("screen:")) {
3872 nsresult rv;
3873 *aWindowIDOut = Substring(data, strlen("screen:")).ToInteger64(&rv);
3874 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3874); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3874; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3875 return MediaSourceEnum::Screen;
3876 }
3877 nsresult rv;
3878 *aWindowIDOut = data.ToInteger64(&rv);
3879 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3879); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3879; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3880 return MediaSourceEnum::Camera;
3881}
3882
3883nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
3884 const char16_t* aData) {
3885 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3885); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3885; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3886
3887 MediaMgrError::Name gumNoAccessError = MediaMgrError::Name::NotAllowedError;
3888
3889 if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
3890 nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(aSubject));
3891 if (branch) {
3892 GetPrefs(branch, NS_ConvertUTF16toUTF8(aData).get());
3893 DeviceListChanged();
3894 }
3895 } else if (!strcmp(aTopic, "last-pb-context-exited")) {
3896 // Clear memory of private-browsing-specific deviceIds. Fire and forget.
3897 media::SanitizeOriginKeys(0, true);
3898 return NS_OK;
3899 } else if (!strcmp(aTopic, "getUserMedia:got-device-permission")) {
3900 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSubject" ")"
); do { *((volatile int*)__null) = 3900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3901 nsCOMPtr<nsIRunnable> task = do_QueryInterface(aSubject);
3902 MediaManager::Dispatch(NewTaskFrom([task] { task->Run(); }));
3903 return NS_OK;
3904 } else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
3905 !strcmp(aTopic, "getUserMedia:response:allow")) {
3906 nsString key(aData);
3907 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
3908 if (!task) {
3909 return NS_OK;
3910 }
3911
3912 if (sHasMainThreadShutdown) {
3913 task->Denied(MediaMgrError::Name::AbortError, "In shutdown"_ns);
3914 return NS_OK;
3915 }
3916 if (NS_WARN_IF(!aSubject)NS_warn_if_impl(!aSubject, "!aSubject", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3916)
) {
3917 return NS_ERROR_FAILURE; // ignored
3918 }
3919 // Permission has been granted. aSubject contains the particular device
3920 // or devices selected and approved by the user, if any.
3921 nsCOMPtr<nsIArray> array(do_QueryInterface(aSubject));
3922 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3922); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array" ")")
; do { *((volatile int*)__null) = 3922; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3923 uint32_t len = 0;
3924 array->GetLength(&len);
3925 RefPtr<LocalMediaDevice> audioInput;
3926 RefPtr<LocalMediaDevice> videoInput;
3927 RefPtr<LocalMediaDevice> audioOutput;
3928 for (uint32_t i = 0; i < len; i++) {
3929 nsCOMPtr<nsIMediaDevice> device;
3930 array->QueryElementAt(i, NS_GET_IID(nsIMediaDevice)(nsIMediaDevice::COMTypeInfo<nsIMediaDevice, void>::kIID
)
,
3931 getter_AddRefs(device));
3932 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3932); AnnotateMozCrashReason("MOZ_ASSERT" "(" "device" ")"
); do { *((volatile int*)__null) = 3932; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // shouldn't be returning anything else...
3933 if (!device) {
3934 continue;
3935 }
3936
3937 // Casting here is safe because a LocalMediaDevice is created
3938 // only in Gecko side, JS can only query for an instance.
3939 auto* dev = static_cast<LocalMediaDevice*>(device.get());
3940 switch (dev->Kind()) {
3941 case MediaDeviceKind::Videoinput:
3942 if (!videoInput) {
3943 videoInput = dev;
3944 }
3945 break;
3946 case MediaDeviceKind::Audioinput:
3947 if (!audioInput) {
3948 audioInput = dev;
3949 }
3950 break;
3951 case MediaDeviceKind::Audiooutput:
3952 if (!audioOutput) {
3953 audioOutput = dev;
3954 }
3955 break;
3956 default:
3957 MOZ_CRASH("Unexpected device kind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected device kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3957); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected device kind"
")"); do { *((volatile int*)__null) = 3957; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
3958 }
3959 }
3960
3961 if (GetUserMediaStreamTask* streamTask = task->AsGetUserMediaStreamTask()) {
3962 bool needVideo = IsOn(streamTask->GetConstraints().mVideo);
3963 bool needAudio = IsOn(streamTask->GetConstraints().mAudio);
3964 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3964); AnnotateMozCrashReason("MOZ_ASSERT" "(" "needVideo || needAudio"
")"); do { *((volatile int*)__null) = 3964; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3965
3966 if ((needVideo && !videoInput) || (needAudio && !audioInput)) {
3967 task->Denied(MediaMgrError::Name::NotAllowedError);
3968 return NS_OK;
3969 }
3970 streamTask->Allowed(std::move(audioInput), std::move(videoInput));
3971 return NS_OK;
3972 }
3973 if (SelectAudioOutputTask* outputTask = task->AsSelectAudioOutputTask()) {
3974 if (!audioOutput) {
3975 task->Denied(MediaMgrError::Name::NotAllowedError);
3976 return NS_OK;
3977 }
3978 outputTask->Allowed(std::move(audioOutput));
3979 return NS_OK;
3980 }
3981
3982 NS_WARNING("Unknown task type in getUserMedia")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown task type in getUserMedia"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 3982)
;
3983 return NS_ERROR_FAILURE;
3984
3985 } else if (IsGUMResponseNoAccess(aTopic, gumNoAccessError)) {
3986 nsString key(aData);
3987 RefPtr<GetUserMediaTask> task = TakeGetUserMediaTask(key);
3988 if (task) {
3989 task->Denied(gumNoAccessError);
3990 SendPendingGUMRequest();
3991 }
3992 return NS_OK;
3993
3994 } else if (!strcmp(aTopic, "getUserMedia:revoke")) {
3995 uint64_t windowID;
3996 if (ParseScreenColonWindowID(aData, &windowID) == MediaSourceEnum::Screen) {
3997 LOG("Revoking ScreenCapture access for window %" PRIu64"l" "u", windowID);
3998 StopScreensharing(windowID);
3999 } else {
4000 LOG("Revoking MediaCapture access for window %" PRIu64"l" "u", windowID);
4001 OnNavigation(windowID);
4002 }
4003 return NS_OK;
4004 } else if (!strcmp(aTopic, "getUserMedia:muteVideo") ||
4005 !strcmp(aTopic, "getUserMedia:unmuteVideo")) {
4006 OnCameraMute(!strcmp(aTopic, "getUserMedia:muteVideo"));
4007 return NS_OK;
4008 } else if (!strcmp(aTopic, "getUserMedia:muteAudio") ||
4009 !strcmp(aTopic, "getUserMedia:unmuteAudio")) {
4010 OnMicrophoneMute(!strcmp(aTopic, "getUserMedia:muteAudio"));
4011 return NS_OK;
4012 } else if ((!strcmp(aTopic, "application-background") ||
4013 !strcmp(aTopic, "application-foreground")) &&
4014 StaticPrefs::media_getusermedia_camera_background_mute_enabled()) {
4015 // On mobile we turn off any cameras (but not mics) while in the background.
4016 // Keeping things simple for now by duplicating test-covered code above.
4017 //
4018 // NOTE: If a mobile device ever wants to implement "getUserMedia:muteVideo"
4019 // as well, it'd need to update this code to handle & test the combinations.
4020 OnCameraMute(!strcmp(aTopic, "application-background"));
4021 }
4022
4023 return NS_OK;
4024}
4025
4026NS_IMETHODIMPnsresult
4027MediaManager::CollectReports(nsIHandleReportCallback* aHandleReport,
4028 nsISupports* aData, bool aAnonymize) {
4029 size_t amount = 0;
4030 amount += mActiveWindows.ShallowSizeOfExcludingThis(MallocSizeOf);
4031 for (const GetUserMediaWindowListener* listener : mActiveWindows.Values()) {
4032 amount += listener->SizeOfIncludingThis(MallocSizeOf);
4033 }
4034 amount += mActiveCallbacks.ShallowSizeOfExcludingThis(MallocSizeOf);
4035 for (const GetUserMediaTask* task : mActiveCallbacks.Values()) {
4036 // Assume nsString buffers for keys are accounted in mCallIds.
4037 amount += task->SizeOfIncludingThis(MallocSizeOf);
4038 }
4039 amount += mCallIds.ShallowSizeOfExcludingThis(MallocSizeOf);
4040 for (const auto& array : mCallIds.Values()) {
4041 amount += array->ShallowSizeOfExcludingThis(MallocSizeOf);
4042 for (const nsString& callID : *array) {
4043 amount += callID.SizeOfExcludingThisEvenIfShared(MallocSizeOf);
4044 }
4045 }
4046 amount += mPendingGUMRequest.ShallowSizeOfExcludingThis(MallocSizeOf);
4047 // GetUserMediaRequest pointees of mPendingGUMRequest do not have support
4048 // for memory accounting. mPendingGUMRequest logic should probably be moved
4049 // to the front end (bug 1691625).
4050 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)
4051 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)
4052 "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)
;
4053 return NS_OK;
4054}
4055
4056nsresult MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray) {
4057 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4057); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aArray" ")"
); do { *((volatile int*)__null) = 4057; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4058
4059 nsCOMPtr<nsIMutableArray> array = nsArray::Create();
4060
4061 for (const auto& entry : mActiveWindows) {
4062 const uint64_t& id = entry.GetKey();
4063 RefPtr<GetUserMediaWindowListener> winListener = entry.GetData();
4064 if (!winListener) {
4065 continue;
4066 }
4067
4068 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(id);
4069 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4069); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { *((volatile int*)__null) = 4069; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4070 // XXXkhuey ...
4071 if (!window) {
4072 continue;
4073 }
4074
4075 if (winListener->CapturingVideo() || winListener->CapturingAudio()) {
4076 array->AppendElement(ToSupports(window));
4077 }
4078 }
4079
4080 array.forget(aArray);
4081 return NS_OK;
4082}
4083
4084struct CaptureWindowStateData {
4085 uint16_t* mCamera;
4086 uint16_t* mMicrophone;
4087 uint16_t* mScreenShare;
4088 uint16_t* mWindowShare;
4089 uint16_t* mAppShare;
4090 uint16_t* mBrowserShare;
4091};
4092
4093NS_IMETHODIMPnsresult
4094MediaManager::MediaCaptureWindowState(
4095 nsIDOMWindow* aCapturedWindow, uint16_t* aCamera, uint16_t* aMicrophone,
4096 uint16_t* aScreen, uint16_t* aWindow, uint16_t* aBrowser,
4097 nsTArray<RefPtr<nsIMediaDevice>>& aDevices) {
4098 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4098); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4098; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4099
4100 CaptureState camera = CaptureState::Off;
4101 CaptureState microphone = CaptureState::Off;
4102 CaptureState screen = CaptureState::Off;
4103 CaptureState window = CaptureState::Off;
4104 CaptureState browser = CaptureState::Off;
4105 RefPtr<LocalMediaDeviceSetRefCnt> devices;
4106
4107 nsCOMPtr<nsPIDOMWindowInner> piWin = do_QueryInterface(aCapturedWindow);
4108 if (piWin) {
4109 if (RefPtr<GetUserMediaWindowListener> listener =
4110 GetWindowListener(piWin->WindowID())) {
4111 camera = listener->CapturingSource(MediaSourceEnum::Camera);
4112 microphone = listener->CapturingSource(MediaSourceEnum::Microphone);
4113 screen = listener->CapturingSource(MediaSourceEnum::Screen);
4114 window = listener->CapturingSource(MediaSourceEnum::Window);
4115 browser = listener->CapturingSource(MediaSourceEnum::Browser);
4116 devices = listener->GetDevices();
4117 }
4118 }
4119
4120 *aCamera = FromCaptureState(camera);
4121 *aMicrophone = FromCaptureState(microphone);
4122 *aScreen = FromCaptureState(screen);
4123 *aWindow = FromCaptureState(window);
4124 *aBrowser = FromCaptureState(browser);
4125 if (devices) {
4126 for (auto& device : *devices) {
4127 aDevices.AppendElement(device);
4128 }
4129 }
4130
4131 LOG("%s: window %" PRIu64"l" "u" " capturing %s %s %s %s %s", __FUNCTION__,
4132 piWin ? piWin->WindowID() : -1,
4133 *aCamera == nsIMediaManagerService::STATE_CAPTURE_ENABLED
4134 ? "camera (enabled)"
4135 : (*aCamera == nsIMediaManagerService::STATE_CAPTURE_DISABLED
4136 ? "camera (disabled)"
4137 : ""),
4138 *aMicrophone == nsIMediaManagerService::STATE_CAPTURE_ENABLED
4139 ? "microphone (enabled)"
4140 : (*aMicrophone == nsIMediaManagerService::STATE_CAPTURE_DISABLED
4141 ? "microphone (disabled)"
4142 : ""),
4143 *aScreen ? "screenshare" : "", *aWindow ? "windowshare" : "",
4144 *aBrowser ? "browsershare" : "");
4145
4146 return NS_OK;
4147}
4148
4149NS_IMETHODIMPnsresult
4150MediaManager::SanitizeDeviceIds(int64_t aSinceWhen) {
4151 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4151; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4152 LOG("%s: sinceWhen = %" PRId64"l" "d", __FUNCTION__, aSinceWhen);
4153
4154 media::SanitizeOriginKeys(aSinceWhen, false); // we fire and forget
4155 return NS_OK;
4156}
4157
4158void MediaManager::StopScreensharing(uint64_t aWindowID) {
4159 // We need to stop window/screensharing for all streams in this innerwindow.
4160
4161 if (RefPtr<GetUserMediaWindowListener> listener =
4162 GetWindowListener(aWindowID)) {
4163 listener->StopSharing();
4164 }
4165}
4166
4167bool MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId) {
4168 // Does page currently have a gUM stream active?
4169
4170 nsCOMPtr<nsIArray> array;
4171 GetActiveMediaCaptureWindows(getter_AddRefs(array));
4172 uint32_t len;
4173 array->GetLength(&len);
4174 for (uint32_t i = 0; i < len; i++) {
4175 nsCOMPtr<nsPIDOMWindowInner> win;
4176 array->QueryElementAt(i, NS_GET_IID(nsPIDOMWindowInner)(nsPIDOMWindowInner::COMTypeInfo<nsPIDOMWindowInner, void>
::kIID)
,
4177 getter_AddRefs(win));
4178 if (win && win->WindowID() == aWindowId) {
4179 return true;
4180 }
4181 }
4182
4183 // Or are persistent permissions (audio or video) granted?
4184
4185 return GetPersistentPermissions(aWindowId)
4186 .map([](auto&& aState) {
4187 return aState.mMicrophonePermission ==
4188 PersistentPermissionState::Allow ||
4189 aState.mCameraPermission == PersistentPermissionState::Allow;
4190 })
4191 .unwrapOr(false);
4192}
4193
4194DeviceListener::DeviceListener()
4195 : mStopped(false),
4196 mMainThreadCheck(nullptr),
4197 mPrincipalHandle(PRINCIPAL_HANDLE_NONEnullptr),
4198 mWindowListener(nullptr) {}
4199
4200void DeviceListener::Register(GetUserMediaWindowListener* aListener) {
4201 LOG("DeviceListener %p registering with window listener %p", this, aListener);
4202
4203 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4203); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aListener" ") ("
"No listener" ")"); do { *((volatile int*)__null) = 4203; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4204 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mWindowListener"
") (" "Already registered" ")"); do { *((volatile int*)__null
) = 4204; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
4205 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4205); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { *((volatile int*)__null
) = 4205; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
4206
4207 mPrincipalHandle = aListener->GetPrincipalHandle();
4208 mWindowListener = aListener;
4209}
4210
4211void DeviceListener::Activate(RefPtr<LocalMediaDevice> aDevice,
4212 RefPtr<LocalTrackSource> aTrackSource,
4213 bool aStartMuted) {
4214 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4214); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4214; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4215
4216 LOG("DeviceListener %p activating %s device %p", this,
4217 dom::GetEnumString(aDevice->Kind()).get(), aDevice.get());
4218
4219 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4219); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mStopped" ") ("
"Cannot activate stopped device listener" ")"); do { *((volatile
int*)__null) = 4219; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4220 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4220); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!Activated()"
") (" "Already activated" ")"); do { *((volatile int*)__null
) = 4220; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
4221
4222 mMainThreadCheck = PR_GetCurrentThread();
4223 bool offWhileDisabled =
4224 (aDevice->GetMediaSource() == MediaSourceEnum::Microphone &&
4225 Preferences::GetBool(
4226 "media.getusermedia.microphone.off_while_disabled.enabled", true)) ||
4227 (aDevice->GetMediaSource() == MediaSourceEnum::Camera &&
4228 Preferences::GetBool(
4229 "media.getusermedia.camera.off_while_disabled.enabled", true));
4230
4231 if (MediaEventSource<void>* event = aDevice->Source()->CaptureEndedEvent()) {
4232 mCaptureEndedListener = event->Connect(AbstractThread::MainThread(), this,
4233 &DeviceListener::Stop);
4234 }
4235
4236 mDeviceState = MakeUnique<DeviceState>(
4237 std::move(aDevice), std::move(aTrackSource), offWhileDisabled);
4238 mDeviceState->mDeviceMuted = aStartMuted;
4239 if (aStartMuted) {
4240 mDeviceState->mTrackSource->Mute();
4241 }
4242}
4243
4244RefPtr<DeviceListener::DeviceListenerPromise>
4245DeviceListener::InitializeAsync() {
4246 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4246); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4246; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4247 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4247); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mStopped"
")"); do { *((volatile int*)__null) = 4247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4248
4249 return MediaManager::Dispatch<DeviceListenerPromise>(
4250 __func__,
4251 [principal = GetPrincipalHandle(), device = mDeviceState->mDevice,
4252 track = mDeviceState->mTrackSource->mTrack,
4253 deviceMuted = mDeviceState->mDeviceMuted](
4254 MozPromiseHolder<DeviceListenerPromise>& aHolder) {
4255 auto kind = device->Kind();
4256 device->SetTrack(track, principal);
4257 nsresult rv = deviceMuted ? NS_OK : device->Start();
4258 if (kind == MediaDeviceKind::Audioinput ||
4259 kind == MediaDeviceKind::Videoinput) {
4260 if ((rv == NS_ERROR_NOT_AVAILABLE &&
4261 kind == MediaDeviceKind::Audioinput) ||
4262 (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && kind == MediaDeviceKind::Videoinput)) {
4263 PR_Sleep(200);
4264 rv = device->Start();
4265 }
4266 if (rv == NS_ERROR_NOT_AVAILABLE &&
4267 kind == MediaDeviceKind::Audioinput) {
4268 nsCString log;
4269 log.AssignLiteral("Concurrent mic process limit.");
4270 aHolder.Reject(MakeRefPtr<MediaMgrError>(
4271 MediaMgrError::Name::NotReadableError,
4272 std::move(log)),
4273 __func__);
4274 return;
4275 }
4276 }
4277 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4278 nsCString log;
4279 log.AppendPrintf("Starting %s failed",
4280 dom::GetEnumString(kind).get());
4281 aHolder.Reject(
4282 MakeRefPtr<MediaMgrError>(MediaMgrError::Name::AbortError,
4283 std::move(log)),
4284 __func__);
4285 return;
4286 }
4287 LOG("started %s device %p", dom::GetEnumString(kind).get(),
4288 device.get());
4289 aHolder.Resolve(true, __func__);
4290 })
4291 ->Then(
4292 GetMainThreadSerialEventTarget(), __func__,
4293 [self = RefPtr<DeviceListener>(this), this]() {
4294 if (mStopped) {
4295 // We were shut down during the async init
4296 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4297 }
4298
4299 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4299); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { *((volatile int*)__null) = 4299; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4300 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4300); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { *((volatile int*)__null) = 4300; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4301 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4301); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped"
")"); do { *((volatile int*)__null) = 4301; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4302
4303 mDeviceState->mDeviceEnabled = true;
4304 mDeviceState->mTrackEnabled = true;
4305 mDeviceState->mTrackEnabledTime = TimeStamp::Now();
4306 return DeviceListenerPromise::CreateAndResolve(true, __func__);
4307 },
4308 [self = RefPtr<DeviceListener>(this),
4309 this](RefPtr<MediaMgrError>&& aResult) {
4310 if (mStopped) {
4311 return DeviceListenerPromise::CreateAndReject(std::move(aResult),
4312 __func__);
4313 }
4314
4315 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4315); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mTrackEnabled"
")"); do { *((volatile int*)__null) = 4315; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4316 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4316); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mDeviceEnabled"
")"); do { *((volatile int*)__null) = 4316; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4317 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4317); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mDeviceState->mStopped"
")"); do { *((volatile int*)__null) = 4317; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4318
4319 Stop();
4320 return DeviceListenerPromise::CreateAndReject(std::move(aResult),
4321 __func__);
4322 });
4323}
4324
4325void DeviceListener::Stop() {
4326 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4326); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4326; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4327
4328 if (mStopped) {
4329 return;
4330 }
4331 mStopped = true;
4332
4333 LOG("DeviceListener %p stopping", this);
4334
4335 if (mDeviceState) {
4336 mDeviceState->mDisableTimer->Cancel();
4337
4338 if (mDeviceState->mStopped) {
4339 // device already stopped.
4340 return;
4341 }
4342 mDeviceState->mStopped = true;
4343
4344 mDeviceState->mTrackSource->Stop();
4345
4346 MediaManager::Dispatch(NewTaskFrom([device = mDeviceState->mDevice]() {
4347 device->Stop();
4348 device->Deallocate();
4349 }));
4350
4351 mWindowListener->ChromeAffectingStateChanged();
4352 }
4353
4354 mCaptureEndedListener.DisconnectIfExists();
4355
4356 // Keep a strong ref to the removed window listener.
4357 RefPtr<GetUserMediaWindowListener> windowListener = mWindowListener;
4358 mWindowListener = nullptr;
4359 windowListener->Remove(this);
4360}
4361
4362void DeviceListener::GetSettings(MediaTrackSettings& aOutSettings) const {
4363 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4363); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4363; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4364 LocalMediaDevice* device = GetDevice();
4365 device->GetSettings(aOutSettings);
4366
4367 MediaSourceEnum mediaSource = device->GetMediaSource();
4368 if (mediaSource == MediaSourceEnum::Camera ||
4369 mediaSource == MediaSourceEnum::Microphone) {
4370 aOutSettings.mDeviceId.Construct(device->mID);
4371 aOutSettings.mGroupId.Construct(device->mGroupID);
4372 }
4373}
4374
4375void DeviceListener::GetCapabilities(
4376 MediaTrackCapabilities& aOutCapabilities) const {
4377 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4377); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4377; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4378 LocalMediaDevice* device = GetDevice();
4379 device->GetCapabilities(aOutCapabilities);
4380
4381 MediaSourceEnum mediaSource = device->GetMediaSource();
4382 if (mediaSource == MediaSourceEnum::Camera ||
4383 mediaSource == MediaSourceEnum::Microphone) {
4384 aOutCapabilities.mDeviceId.Construct(device->mID);
4385 aOutCapabilities.mGroupId.Construct(device->mGroupID);
4386 }
4387}
4388
4389auto DeviceListener::UpdateDevice(bool aOn) -> RefPtr<DeviceOperationPromise> {
4390 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4390); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4390; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4391 RefPtr<DeviceListener> self = this;
4392 DeviceState& state = *mDeviceState;
4393 return MediaManager::Dispatch<DeviceOperationPromise>(
4394 __func__,
4395 [self, device = state.mDevice,
4396 aOn](MozPromiseHolder<DeviceOperationPromise>& h) {
4397 LOG("Turning %s device (%s)", aOn ? "on" : "off",
4398 NS_ConvertUTF16toUTF8(device->mName).get());
4399 h.Resolve(aOn ? device->Start() : device->Stop(), __func__);
4400 })
4401 ->Then(
4402 GetMainThreadSerialEventTarget(), __func__,
4403 [self, this, &state, aOn](nsresult aResult) {
4404 if (state.mStopped) {
4405 // Device was stopped on main thread during the operation. Done.
4406 return DeviceOperationPromise::CreateAndResolve(aResult,
4407 __func__);
4408 }
4409 LOG("DeviceListener %p turning %s %s input device %s", this,
4410 aOn ? "on" : "off",
4411 dom::GetEnumString(GetDevice()->Kind()).get(),
4412 NS_SUCCEEDED(aResult)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aResult)), 1))) ? "succeeded" : "failed");
4413
4414 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT) {
4415 // This path handles errors from starting or stopping the
4416 // device. NS_ERROR_ABORT are for cases where *we* aborted. They
4417 // need graceful handling.
4418 if (aOn) {
4419 // Starting the device failed. Stopping the track here will
4420 // make the MediaStreamTrack end after a pass through the
4421 // MediaTrackGraph.
4422 Stop();
4423 } else {
4424 // Stopping the device failed. This is odd, but not fatal.
4425 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4425); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "The device should be stoppable" ")"
); do { *((volatile int*)__null) = 4425; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4426 }
4427 }
4428 return DeviceOperationPromise::CreateAndResolve(aResult, __func__);
4429 },
4430 []() {
4431 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4431); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { *((volatile int*)__null) = 4431; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4432 return DeviceOperationPromise::CreateAndReject(false, __func__);
4433 });
4434}
4435
4436void DeviceListener::SetDeviceEnabled(bool aEnable) {
4437 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4437); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4437; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4438 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set enabled state for" ")"); do { *((volatile
int*)__null) = 4438; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4439
4440 DeviceState& state = *mDeviceState;
4441
4442 LOG("DeviceListener %p %s %s device", this,
4443 aEnable ? "enabling" : "disabling",
4444 dom::GetEnumString(GetDevice()->Kind()).get());
4445
4446 state.mTrackEnabled = aEnable;
4447
4448 if (state.mStopped) {
4449 // Device terminally stopped. Updating device state is pointless.
4450 return;
4451 }
4452
4453 if (state.mOperationInProgress) {
4454 // If a timer is in progress, it needs to be canceled now so the next
4455 // DisableTrack() gets a fresh start. Canceling will trigger another
4456 // operation.
4457 state.mDisableTimer->Cancel();
4458 return;
4459 }
4460
4461 if (state.mDeviceEnabled == aEnable) {
4462 // Device is already in the desired state.
4463 return;
4464 }
4465
4466 // All paths from here on must end in setting
4467 // `state.mOperationInProgress` to false.
4468 state.mOperationInProgress = true;
4469
4470 RefPtr<MediaTimerPromise> timerPromise;
4471 if (aEnable) {
4472 timerPromise = MediaTimerPromise::CreateAndResolve(true, __func__);
4473 state.mTrackEnabledTime = TimeStamp::Now();
4474 } else {
4475 const TimeDuration maxDelay =
4476 TimeDuration::FromMilliseconds(Preferences::GetUint(
4477 GetDevice()->Kind() == MediaDeviceKind::Audioinput
4478 ? "media.getusermedia.microphone.off_while_disabled.delay_ms"
4479 : "media.getusermedia.camera.off_while_disabled.delay_ms",
4480 3000));
4481 const TimeDuration durationEnabled =
4482 TimeStamp::Now() - state.mTrackEnabledTime;
4483 const TimeDuration delay = TimeDuration::Max(
4484 TimeDuration::FromMilliseconds(0), maxDelay - durationEnabled);
4485 timerPromise = state.mDisableTimer->WaitFor(delay, __func__);
4486 }
4487
4488 RefPtr<DeviceListener> self = this;
4489 timerPromise
4490 ->Then(
4491 GetMainThreadSerialEventTarget(), __func__,
4492 [self, this, &state, aEnable]() mutable {
4493 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable"
") (" "Device operation hasn't started" ")"); do { *((volatile
int*)__null) = 4494; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
4494 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mDeviceEnabled != aEnable"
") (" "Device operation hasn't started" ")"); do { *((volatile
int*)__null) = 4494; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4495 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mOperationInProgress"
") (" "It's our responsibility to reset the inProgress state"
")"); do { *((volatile int*)__null) = 4496; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4496 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mOperationInProgress"
") (" "It's our responsibility to reset the inProgress state"
")"); do { *((volatile int*)__null) = 4496; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4497
4498 LOG("DeviceListener %p %s %s device - starting device operation",
4499 this, aEnable ? "enabling" : "disabling",
4500 dom::GetEnumString(GetDevice()->Kind()).get());
4501
4502 if (state.mStopped) {
4503 // Source was stopped between timer resolving and this runnable.
4504 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4505 __func__);
4506 }
4507
4508 state.mDeviceEnabled = aEnable;
4509
4510 if (mWindowListener) {
4511 mWindowListener->ChromeAffectingStateChanged();
4512 }
4513 if (!state.mOffWhileDisabled || state.mDeviceMuted) {
4514 // If the feature to turn a device off while disabled is itself
4515 // disabled, or the device is currently user agent muted, then
4516 // we shortcut the device operation and tell the
4517 // ux-updating code that everything went fine.
4518 return DeviceOperationPromise::CreateAndResolve(NS_OK, __func__);
4519 }
4520 return UpdateDevice(aEnable);
4521 },
4522 []() {
4523 // Timer was canceled by us. We signal this with NS_ERROR_ABORT.
4524 return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT,
4525 __func__);
4526 })
4527 ->Then(
4528 GetMainThreadSerialEventTarget(), __func__,
4529 [self, this, &state, aEnable](nsresult aResult) mutable {
4530 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4531); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable"
")"); do { *((volatile int*)__null) = 4531; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4531 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4531); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mDeviceEnabled == aEnable"
")"); do { *((volatile int*)__null) = 4531; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4532 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state.mOperationInProgress"
")"); do { *((volatile int*)__null) = 4532; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4533 state.mOperationInProgress = false;
4534
4535 if (state.mStopped) {
4536 // Device was stopped on main thread during the operation.
4537 // Nothing to do.
4538 return;
4539 }
4540
4541 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0))) && aResult != NS_ERROR_ABORT && !aEnable) {
4542 // To keep our internal state sane in this case, we disallow
4543 // future stops due to disable.
4544 state.mOffWhileDisabled = false;
4545 return;
4546 }
4547
4548 // This path is for a device operation aResult that was success or
4549 // NS_ERROR_ABORT (*we* canceled the operation).
4550 // At this point we have to follow up on the intended state, i.e.,
4551 // update the device state if the track state changed in the
4552 // meantime.
4553
4554 if (state.mTrackEnabled != state.mDeviceEnabled) {
4555 // Track state changed during this operation. We'll start over.
4556 SetDeviceEnabled(state.mTrackEnabled);
4557 }
4558 },
4559 []() { 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4559); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected and unhandled reject"
")"); do { *((volatile int*)__null) = 4559; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; });
4560}
4561
4562void DeviceListener::SetDeviceMuted(bool aMute) {
4563 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4563); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4563; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4564 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4564); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Activated()"
") (" "No device to set muted state for" ")"); do { *((volatile
int*)__null) = 4564; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4565
4566 DeviceState& state = *mDeviceState;
4567
4568 LOG("DeviceListener %p %s %s device", this, aMute ? "muting" : "unmuting",
4569 dom::GetEnumString(GetDevice()->Kind()).get());
4570
4571 if (state.mStopped) {
4572 // Device terminally stopped. Updating device state is pointless.
4573 return;
4574 }
4575
4576 if (state.mDeviceMuted == aMute) {
4577 // Device is already in the desired state.
4578 return;
4579 }
4580
4581 LOG("DeviceListener %p %s %s device - starting device operation", this,
4582 aMute ? "muting" : "unmuting",
4583 dom::GetEnumString(GetDevice()->Kind()).get());
4584
4585 state.mDeviceMuted = aMute;
4586
4587 if (mWindowListener) {
4588 mWindowListener->ChromeAffectingStateChanged();
4589 }
4590 // Update trackSource to fire mute/unmute events on all its tracks
4591 if (aMute) {
4592 state.mTrackSource->Mute();
4593 } else {
4594 state.mTrackSource->Unmute();
4595 }
4596 if (!state.mOffWhileDisabled || !state.mDeviceEnabled) {
4597 // If the pref to turn the underlying device is itself off, or the device
4598 // is already off, it's unecessary to do anything else.
4599 return;
4600 }
4601 UpdateDevice(!aMute);
4602}
4603
4604void DeviceListener::MuteOrUnmuteCamera(bool aMute) {
4605 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4605); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4605; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4606
4607 if (mStopped) {
4608 return;
4609 }
4610
4611 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4611); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mWindowListener"
")"); do { *((volatile int*)__null) = 4611; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4612 LOG("DeviceListener %p MuteOrUnmuteCamera: %s", this,
4613 aMute ? "mute" : "unmute");
4614
4615 if (GetDevice() &&
4616 (GetDevice()->GetMediaSource() == MediaSourceEnum::Camera)) {
4617 SetDeviceMuted(aMute);
4618 }
4619}
4620
4621void DeviceListener::MuteOrUnmuteMicrophone(bool aMute) {
4622 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4622); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4622; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4623
4624 if (mStopped) {
4625 return;
4626 }
4627
4628 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4628); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mWindowListener"
")"); do { *((volatile int*)__null) = 4628; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4629 LOG("DeviceListener %p MuteOrUnmuteMicrophone: %s", this,
4630 aMute ? "mute" : "unmute");
4631
4632 if (GetDevice() &&
4633 (GetDevice()->GetMediaSource() == MediaSourceEnum::Microphone)) {
4634 SetDeviceMuted(aMute);
4635 }
4636}
4637
4638bool DeviceListener::CapturingVideo() const {
4639 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4639); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4639; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4640 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4641 MediaEngineSource::IsVideo(GetDevice()->GetMediaSource()) &&
4642 (!GetDevice()->IsFake() ||
4643 Preferences::GetBool("media.navigator.permission.fake"));
4644}
4645
4646bool DeviceListener::CapturingAudio() const {
4647 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4647); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4647; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4648 return Activated() && mDeviceState && !mDeviceState->mStopped &&
4649 MediaEngineSource::IsAudio(GetDevice()->GetMediaSource()) &&
4650 (!GetDevice()->IsFake() ||
4651 Preferences::GetBool("media.navigator.permission.fake"));
4652}
4653
4654CaptureState DeviceListener::CapturingSource(MediaSourceEnum aSource) const {
4655 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4655); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4655; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4656 if (GetDevice()->GetMediaSource() != aSource) {
4657 // This DeviceListener doesn't capture a matching source
4658 return CaptureState::Off;
4659 }
4660
4661 if (mDeviceState->mStopped) {
4662 // The source is a match but has been permanently stopped
4663 return CaptureState::Off;
4664 }
4665
4666 if ((aSource == MediaSourceEnum::Camera ||
4667 aSource == MediaSourceEnum::Microphone) &&
4668 GetDevice()->IsFake() &&
4669 !Preferences::GetBool("media.navigator.permission.fake")) {
4670 // Fake Camera and Microphone only count if there is no fake permission
4671 return CaptureState::Off;
4672 }
4673
4674 // Source is a match and is active and unmuted
4675
4676 if (mDeviceState->mDeviceEnabled && !mDeviceState->mDeviceMuted) {
4677 return CaptureState::Enabled;
4678 }
4679
4680 return CaptureState::Disabled;
4681}
4682
4683RefPtr<DeviceListener::DeviceListenerPromise> DeviceListener::ApplyConstraints(
4684 const MediaTrackConstraints& aConstraints, CallerType aCallerType) {
4685 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4686
4687 if (mStopped || mDeviceState->mStopped) {
4688 LOG("DeviceListener %p %s device applyConstraints, but device is stopped",
4689 this, dom::GetEnumString(GetDevice()->Kind()).get());
4690 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4691 }
4692
4693 MediaManager* mgr = MediaManager::GetIfExists();
4694 if (!mgr) {
4695 return DeviceListenerPromise::CreateAndResolve(false, __func__);
4696 }
4697
4698 return MediaManager::Dispatch<DeviceListenerPromise>(
4699 __func__, [device = mDeviceState->mDevice, aConstraints, aCallerType](
4700 MozPromiseHolder<DeviceListenerPromise>& aHolder) mutable {
4701 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()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4701); AnnotateMozCrashReason("MOZ_ASSERT" "(" "MediaManager::IsInMediaThread()"
")"); do { *((volatile int*)__null) = 4701; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4702 MediaManager* mgr = MediaManager::GetIfExists();
4703 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4703); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mgr"
")"); do { *((volatile int*)__null) = 4703; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // Must exist while media thread is alive
4704 const char* badConstraint = nullptr;
4705 nsresult rv =
4706 device->Reconfigure(aConstraints, mgr->mPrefs, &badConstraint);
4707 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4708 if (rv == NS_ERROR_INVALID_ARG) {
4709 // Reconfigure failed due to constraints
4710 if (!badConstraint) {
4711 nsTArray<RefPtr<LocalMediaDevice>> devices;
4712 devices.AppendElement(device);
4713 badConstraint = MediaConstraintsHelper::SelectSettings(
4714 NormalizedConstraints(aConstraints), devices, aCallerType);
4715 }
4716 } else {
4717 // Unexpected. ApplyConstraints* cannot fail with any other error.
4718 badConstraint = "";
4719 LOG("ApplyConstraints-Task: Unexpected fail %" PRIx32"x",
4720 static_cast<uint32_t>(rv));
4721 }
4722
4723 aHolder.Reject(MakeRefPtr<MediaMgrError>(
4724 MediaMgrError::Name::OverconstrainedError, "",
4725 NS_ConvertASCIItoUTF16(badConstraint)),
4726 __func__);
4727 return;
4728 }
4729 // Reconfigure was successful
4730 aHolder.Resolve(false, __func__);
4731 });
4732}
4733
4734PrincipalHandle DeviceListener::GetPrincipalHandle() const {
4735 return mPrincipalHandle;
4736}
4737
4738void GetUserMediaWindowListener::StopSharing() {
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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4739); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4739; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4740
4741 for (auto& l : mActiveListeners.Clone()) {
4742 MediaSourceEnum source = l->GetDevice()->GetMediaSource();
4743 if (source == MediaSourceEnum::Screen ||
4744 source == MediaSourceEnum::Window ||
4745 source == MediaSourceEnum::AudioCapture) {
4746 l->Stop();
4747 }
4748 }
4749}
4750
4751void GetUserMediaWindowListener::StopRawID(const nsString& removedDeviceID) {
4752 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4752); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4752; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4753
4754 for (auto& l : mActiveListeners.Clone()) {
4755 if (removedDeviceID.Equals(l->GetDevice()->RawID())) {
4756 l->Stop();
4757 }
4758 }
4759}
4760
4761void GetUserMediaWindowListener::MuteOrUnmuteCameras(bool aMute) {
4762 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4762); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4762; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4763
4764 if (mCamerasAreMuted == aMute) {
4765 return;
4766 }
4767 mCamerasAreMuted = aMute;
4768
4769 for (auto& l : mActiveListeners) {
4770 if (l->GetDevice()->Kind() == MediaDeviceKind::Videoinput) {
4771 l->MuteOrUnmuteCamera(aMute);
4772 }
4773 }
4774}
4775
4776void GetUserMediaWindowListener::MuteOrUnmuteMicrophones(bool aMute) {
4777 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Only call on main thread" ")"); do { *((volatile int*
)__null) = 4777; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4778
4779 if (mMicrophonesAreMuted == aMute) {
4780 return;
4781 }
4782 mMicrophonesAreMuted = aMute;
4783
4784 for (auto& l : mActiveListeners) {
4785 if (l->GetDevice()->Kind() == MediaDeviceKind::Audioinput) {
4786 l->MuteOrUnmuteMicrophone(aMute);
4787 }
4788 }
4789}
4790
4791void GetUserMediaWindowListener::ChromeAffectingStateChanged() {
4792 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4792); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4792; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4793
4794 // We wait until stable state before notifying chrome so chrome only does
4795 // one update if more updates happen in this event loop.
4796
4797 if (mChromeNotificationTaskPosted) {
4798 return;
4799 }
4800
4801 nsCOMPtr<nsIRunnable> runnable =
4802 NewRunnableMethod("GetUserMediaWindowListener::NotifyChrome", this,
4803 &GetUserMediaWindowListener::NotifyChrome);
4804 nsContentUtils::RunInStableState(runnable.forget());
4805 mChromeNotificationTaskPosted = true;
4806}
4807
4808void GetUserMediaWindowListener::NotifyChrome() {
4809 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mChromeNotificationTaskPosted"
")"); do { *((volatile int*)__null) = 4809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4810 mChromeNotificationTaskPosted = false;
4811
4812 NS_DispatchToMainThread(NS_NewRunnableFunction(
4813 "MediaManager::NotifyChrome", [windowID = mWindowID]() {
4814 auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowID);
4815 if (!window) {
4816 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4816); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should have window" ")"); do { *
((volatile int*)__null) = 4816; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
4817 return;
4818 }
4819
4820 nsresult rv = MediaManager::NotifyRecordingStatusChange(window);
4821 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4822 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/MediaManager.cpp"
, 4822); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Should be able to notify chrome"
")"); do { *((volatile int*)__null) = 4822; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4823 return;
4824 }
4825 }));
4826}
4827
4828#undef LOG
4829
4830} // namespace mozilla