2015-08-31 15:51:29 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set sw=2 ts=8 et ft=cpp : */
|
2012-07-12 15:53:08 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
Bug 1299515 - Flatten MediaEngineSource class hierarchy. r=jib
The scope of flattening this hierarchy quickly grows large, so this patch does
a couple more things:
- Creates a pure interface MediaEngineSourceInterface and a base class
MediaEngineSource with common defaults and refcount support (no state!)
- Breaks out some of the helper classes to dedicated files, e.g.,
AllocationHandle, MediaEnginePrefs.
- Clarifies the threading model (written on one thread *and* under lock,
read under either)
- Fixes style, indentation, include-sorting in the affected files
- Adds comments, especially for clarifying what responsibilities methods have,
and thread usage of class members
- Changes Monitors to Mutexes since we only use them as Mutexes anyhow
- Makes MediaEngineRemoteVideoSource no longer a shared source since we now
support scaling in this source and CamerasChild can act as a broker of frames.
This greatly simplifies it. The only shared source is now
MediaEngineWebRTCMicrophoneSource, so the sharing specific common methods have
been moved to that source.
MozReview-Commit-ID: KeVZQo6gLm2
--HG--
rename : dom/media/webrtc/MediaEngine.h => dom/media/webrtc/MediaEnginePrefs.h
extra : rebase_source : c785a5feb896312912170475d6b8d997e712e48f
2018-01-24 18:49:13 +03:00
|
|
|
#include "MediaEngineWebRTC.h"
|
2013-02-20 19:18:54 +04:00
|
|
|
|
Bug 1299515 - Flatten MediaEngineSource class hierarchy. r=jib
The scope of flattening this hierarchy quickly grows large, so this patch does
a couple more things:
- Creates a pure interface MediaEngineSourceInterface and a base class
MediaEngineSource with common defaults and refcount support (no state!)
- Breaks out some of the helper classes to dedicated files, e.g.,
AllocationHandle, MediaEnginePrefs.
- Clarifies the threading model (written on one thread *and* under lock,
read under either)
- Fixes style, indentation, include-sorting in the affected files
- Adds comments, especially for clarifying what responsibilities methods have,
and thread usage of class members
- Changes Monitors to Mutexes since we only use them as Mutexes anyhow
- Makes MediaEngineRemoteVideoSource no longer a shared source since we now
support scaling in this source and CamerasChild can act as a broker of frames.
This greatly simplifies it. The only shared source is now
MediaEngineWebRTCMicrophoneSource, so the sharing specific common methods have
been moved to that source.
MozReview-Commit-ID: KeVZQo6gLm2
--HG--
rename : dom/media/webrtc/MediaEngine.h => dom/media/webrtc/MediaEnginePrefs.h
extra : rebase_source : c785a5feb896312912170475d6b8d997e712e48f
2018-01-24 18:49:13 +03:00
|
|
|
#include "CamerasChild.h"
|
2013-01-12 03:30:20 +04:00
|
|
|
#include "CSFLog.h"
|
2015-08-31 15:51:29 +03:00
|
|
|
#include "MediaEngineRemoteVideoSource.h"
|
2018-08-29 15:38:43 +03:00
|
|
|
#include "MediaEngineWebRTCAudio.h"
|
2019-03-27 17:10:24 +03:00
|
|
|
#include "MediaManager.h"
|
2014-04-18 23:15:10 +04:00
|
|
|
#include "MediaTrackConstraints.h"
|
2018-07-16 12:30:46 +03:00
|
|
|
#include "mozilla/dom/MediaDeviceInfo.h"
|
Bug 1299515 - Flatten MediaEngineSource class hierarchy. r=jib
The scope of flattening this hierarchy quickly grows large, so this patch does
a couple more things:
- Creates a pure interface MediaEngineSourceInterface and a base class
MediaEngineSource with common defaults and refcount support (no state!)
- Breaks out some of the helper classes to dedicated files, e.g.,
AllocationHandle, MediaEnginePrefs.
- Clarifies the threading model (written on one thread *and* under lock,
read under either)
- Fixes style, indentation, include-sorting in the affected files
- Adds comments, especially for clarifying what responsibilities methods have,
and thread usage of class members
- Changes Monitors to Mutexes since we only use them as Mutexes anyhow
- Makes MediaEngineRemoteVideoSource no longer a shared source since we now
support scaling in this source and CamerasChild can act as a broker of frames.
This greatly simplifies it. The only shared source is now
MediaEngineWebRTCMicrophoneSource, so the sharing specific common methods have
been moved to that source.
MozReview-Commit-ID: KeVZQo6gLm2
--HG--
rename : dom/media/webrtc/MediaEngine.h => dom/media/webrtc/MediaEnginePrefs.h
extra : rebase_source : c785a5feb896312912170475d6b8d997e712e48f
2018-01-24 18:49:13 +03:00
|
|
|
#include "mozilla/Logging.h"
|
|
|
|
#include "nsIComponentRegistrar.h"
|
|
|
|
#include "prenv.h"
|
2013-10-18 00:48:30 +04:00
|
|
|
|
2019-10-29 16:01:47 +03:00
|
|
|
#define FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS 500
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
|
Bug 1299515 - Flatten MediaEngineSource class hierarchy. r=jib
The scope of flattening this hierarchy quickly grows large, so this patch does
a couple more things:
- Creates a pure interface MediaEngineSourceInterface and a base class
MediaEngineSource with common defaults and refcount support (no state!)
- Breaks out some of the helper classes to dedicated files, e.g.,
AllocationHandle, MediaEnginePrefs.
- Clarifies the threading model (written on one thread *and* under lock,
read under either)
- Fixes style, indentation, include-sorting in the affected files
- Adds comments, especially for clarifying what responsibilities methods have,
and thread usage of class members
- Changes Monitors to Mutexes since we only use them as Mutexes anyhow
- Makes MediaEngineRemoteVideoSource no longer a shared source since we now
support scaling in this source and CamerasChild can act as a broker of frames.
This greatly simplifies it. The only shared source is now
MediaEngineWebRTCMicrophoneSource, so the sharing specific common methods have
been moved to that source.
MozReview-Commit-ID: KeVZQo6gLm2
--HG--
rename : dom/media/webrtc/MediaEngine.h => dom/media/webrtc/MediaEnginePrefs.h
extra : rebase_source : c785a5feb896312912170475d6b8d997e712e48f
2018-01-24 18:49:13 +03:00
|
|
|
static mozilla::LazyLogModule sGetUserMediaLog("GetUserMedia");
|
2013-05-02 16:00:12 +04:00
|
|
|
#undef LOG
|
2016-05-06 16:11:17 +03:00
|
|
|
#define LOG(args) MOZ_LOG(sGetUserMediaLog, mozilla::LogLevel::Debug, args)
|
2013-05-02 16:00:12 +04:00
|
|
|
|
2012-07-12 15:53:08 +04:00
|
|
|
namespace mozilla {
|
2014-02-15 02:41:07 +04:00
|
|
|
|
2019-10-29 16:01:30 +03:00
|
|
|
using camera::CamerasChild;
|
|
|
|
using camera::GetChildAndCall;
|
|
|
|
|
2019-09-20 13:13:51 +03:00
|
|
|
CubebDeviceEnumerator* GetEnumerator() {
|
|
|
|
return CubebDeviceEnumerator::GetInstance();
|
|
|
|
}
|
|
|
|
|
2013-12-06 23:34:40 +04:00
|
|
|
MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs& aPrefs)
|
2019-10-29 16:01:36 +03:00
|
|
|
: mDelayAgnostic(aPrefs.mDelayAgnostic),
|
2020-07-11 15:31:49 +03:00
|
|
|
mExtendedFilter(aPrefs.mExtendedFilter) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
GetChildAndCall(
|
|
|
|
&CamerasChild::ConnectDeviceListChangeListener<MediaEngineWebRTC>,
|
|
|
|
&mCameraListChangeListener, AbstractThread::MainThread(), this,
|
|
|
|
&MediaEngineWebRTC::DeviceListChanged);
|
|
|
|
mMicrophoneListChangeListener =
|
|
|
|
GetEnumerator()->OnAudioInputDeviceListChange().Connect(
|
|
|
|
AbstractThread::MainThread(), this,
|
|
|
|
&MediaEngineWebRTC::DeviceListChanged);
|
|
|
|
mSpeakerListChangeListener =
|
|
|
|
GetEnumerator()->OnAudioOutputDeviceListChange().Connect(
|
|
|
|
AbstractThread::MainThread(), this,
|
|
|
|
&MediaEngineWebRTC::DeviceListChanged);
|
2013-10-18 00:48:30 +04:00
|
|
|
}
|
2012-07-12 15:53:08 +04:00
|
|
|
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
void MediaEngineWebRTC::SetFakeDeviceChangeEventsEnabled(bool aEnable) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
|
|
|
|
// To simulate the devicechange event in mochitest, we schedule a timer to
|
|
|
|
// issue "devicechange" repeatedly until disabled.
|
|
|
|
|
|
|
|
if (aEnable && !mFakeDeviceChangeEventTimer) {
|
|
|
|
NS_NewTimerWithFuncCallback(
|
|
|
|
getter_AddRefs(mFakeDeviceChangeEventTimer),
|
|
|
|
&FakeDeviceChangeEventTimerTick, this,
|
|
|
|
FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS, nsITimer::TYPE_REPEATING_SLACK,
|
2020-07-09 09:12:10 +03:00
|
|
|
"MediaEngineWebRTC::mFakeDeviceChangeEventTimer",
|
|
|
|
GetCurrentSerialEventTarget());
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aEnable && mFakeDeviceChangeEventTimer) {
|
|
|
|
mFakeDeviceChangeEventTimer->Cancel();
|
|
|
|
mFakeDeviceChangeEventTimer = nullptr;
|
|
|
|
return;
|
|
|
|
}
|
2016-08-09 11:37:04 +03:00
|
|
|
}
|
|
|
|
|
2018-05-07 20:33:41 +03:00
|
|
|
void MediaEngineWebRTC::EnumerateVideoDevices(
|
2018-12-28 02:40:36 +03:00
|
|
|
uint64_t aWindowId, camera::CaptureEngine aCapEngine,
|
2018-07-11 09:59:13 +03:00
|
|
|
nsTArray<RefPtr<MediaDevice>>* aDevices) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
|
2018-12-28 02:40:36 +03:00
|
|
|
// flag sources with cross-origin exploit potential
|
|
|
|
bool scaryKind = (aCapEngine == camera::ScreenEngine ||
|
|
|
|
aCapEngine == camera::BrowserEngine);
|
2018-05-07 20:33:41 +03:00
|
|
|
/*
|
|
|
|
* We still enumerate every time, in case a new device was plugged in since
|
|
|
|
* the last call. TODO: Verify that WebRTC actually does deal with hotplugging
|
|
|
|
* new devices (with or without new engine creation) and accordingly adjust.
|
|
|
|
* Enumeration is not neccessary if GIPS reports the same set of devices
|
2019-03-27 17:10:10 +03:00
|
|
|
* for a given instance of the engine.
|
2018-05-07 20:33:41 +03:00
|
|
|
*/
|
|
|
|
int num;
|
2019-02-27 22:50:04 +03:00
|
|
|
#if defined(_ARM64_) && defined(XP_WIN)
|
|
|
|
// There are problems with using DirectShow on versions of Windows before
|
|
|
|
// 19H1 on arm64. This disables the camera on older versions of Windows.
|
|
|
|
if (aCapEngine == camera::CameraEngine) {
|
|
|
|
typedef ULONG (*RtlGetVersionFn)(LPOSVERSIONINFOEXW);
|
|
|
|
RtlGetVersionFn RtlGetVersion;
|
|
|
|
RtlGetVersion = (RtlGetVersionFn)GetProcAddress(GetModuleHandleA("ntdll"),
|
|
|
|
"RtlGetVersion");
|
|
|
|
if (RtlGetVersion) {
|
|
|
|
OSVERSIONINFOEXW info;
|
|
|
|
info.dwOSVersionInfoSize = sizeof(info);
|
|
|
|
RtlGetVersion(&info);
|
|
|
|
// 19H1 is 18346
|
|
|
|
if (info.dwBuildNumber < 18346) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2019-10-29 16:01:30 +03:00
|
|
|
num = GetChildAndCall(&CamerasChild::NumberOfCaptureDevices, aCapEngine);
|
2018-05-07 20:33:41 +03:00
|
|
|
|
|
|
|
for (int i = 0; i < num; i++) {
|
|
|
|
char deviceName[MediaEngineSource::kMaxDeviceNameLength];
|
|
|
|
char uniqueId[MediaEngineSource::kMaxUniqueIdLength];
|
|
|
|
bool scarySource = false;
|
|
|
|
|
|
|
|
// paranoia
|
|
|
|
deviceName[0] = '\0';
|
|
|
|
uniqueId[0] = '\0';
|
|
|
|
int error;
|
|
|
|
|
2019-10-29 16:01:30 +03:00
|
|
|
error = GetChildAndCall(&CamerasChild::GetCaptureDevice, aCapEngine, i,
|
|
|
|
deviceName, sizeof(deviceName), uniqueId,
|
|
|
|
sizeof(uniqueId), &scarySource);
|
2018-05-07 20:33:41 +03:00
|
|
|
if (error) {
|
|
|
|
LOG(("camera:GetCaptureDevice: Failed %d", error));
|
|
|
|
continue;
|
|
|
|
}
|
2012-11-13 05:46:52 +04:00
|
|
|
#ifdef DEBUG
|
2018-05-07 20:33:41 +03:00
|
|
|
LOG((" Capture Device Index %d, Name %s", i, deviceName));
|
|
|
|
|
|
|
|
webrtc::CaptureCapability cap;
|
2019-10-29 16:01:30 +03:00
|
|
|
int numCaps = GetChildAndCall(&CamerasChild::NumberOfCapabilities,
|
|
|
|
aCapEngine, uniqueId);
|
2018-05-07 20:33:41 +03:00
|
|
|
LOG(("Number of Capabilities %d", numCaps));
|
|
|
|
for (int j = 0; j < numCaps; j++) {
|
2019-10-29 16:01:30 +03:00
|
|
|
if (GetChildAndCall(&CamerasChild::GetCaptureCapability, aCapEngine,
|
|
|
|
uniqueId, j, cap) != 0) {
|
2018-05-07 20:33:41 +03:00
|
|
|
break;
|
2012-10-04 20:09:35 +04:00
|
|
|
}
|
2018-05-07 20:33:41 +03:00
|
|
|
LOG(("type=%d width=%d height=%d maxFPS=%d",
|
2018-02-20 23:23:09 +03:00
|
|
|
static_cast<int>(cap.videoType), cap.width, cap.height, cap.maxFPS));
|
2018-05-07 20:33:41 +03:00
|
|
|
}
|
2012-10-04 20:09:35 +04:00
|
|
|
#endif
|
|
|
|
|
2018-05-07 20:33:41 +03:00
|
|
|
if (uniqueId[0] == '\0') {
|
|
|
|
// In case a device doesn't set uniqueId!
|
|
|
|
strncpy(uniqueId, deviceName, sizeof(uniqueId));
|
|
|
|
uniqueId[sizeof(uniqueId) - 1] = '\0'; // strncpy isn't safe
|
|
|
|
}
|
2018-01-31 21:02:00 +03:00
|
|
|
|
2018-05-07 20:33:41 +03:00
|
|
|
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
|
|
|
RefPtr<MediaEngineSource> vSource;
|
2018-01-31 21:02:00 +03:00
|
|
|
|
2019-03-27 17:10:24 +03:00
|
|
|
vSource = new MediaEngineRemoteVideoSource(i, aCapEngine,
|
|
|
|
scaryKind || scarySource);
|
2018-07-11 09:59:13 +03:00
|
|
|
aDevices->AppendElement(MakeRefPtr<MediaDevice>(
|
2018-10-12 11:48:22 +03:00
|
|
|
vSource, vSource->GetName(), NS_ConvertUTF8toUTF16(vSource->GetUUID()),
|
2020-07-01 11:29:29 +03:00
|
|
|
vSource->GetGroupId(), u""_ns));
|
2018-05-07 20:33:41 +03:00
|
|
|
}
|
|
|
|
}
|
Bug 1299515 - Flatten MediaEngineSource class hierarchy. r=jib
The scope of flattening this hierarchy quickly grows large, so this patch does
a couple more things:
- Creates a pure interface MediaEngineSourceInterface and a base class
MediaEngineSource with common defaults and refcount support (no state!)
- Breaks out some of the helper classes to dedicated files, e.g.,
AllocationHandle, MediaEnginePrefs.
- Clarifies the threading model (written on one thread *and* under lock,
read under either)
- Fixes style, indentation, include-sorting in the affected files
- Adds comments, especially for clarifying what responsibilities methods have,
and thread usage of class members
- Changes Monitors to Mutexes since we only use them as Mutexes anyhow
- Makes MediaEngineRemoteVideoSource no longer a shared source since we now
support scaling in this source and CamerasChild can act as a broker of frames.
This greatly simplifies it. The only shared source is now
MediaEngineWebRTCMicrophoneSource, so the sharing specific common methods have
been moved to that source.
MozReview-Commit-ID: KeVZQo6gLm2
--HG--
rename : dom/media/webrtc/MediaEngine.h => dom/media/webrtc/MediaEnginePrefs.h
extra : rebase_source : c785a5feb896312912170475d6b8d997e712e48f
2018-01-24 18:49:13 +03:00
|
|
|
|
2018-05-07 20:33:41 +03:00
|
|
|
void MediaEngineWebRTC::EnumerateMicrophoneDevices(
|
2018-07-11 09:59:13 +03:00
|
|
|
uint64_t aWindowId, nsTArray<RefPtr<MediaDevice>>* aDevices) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
2012-07-12 15:53:08 +04:00
|
|
|
|
2018-04-30 16:18:22 +03:00
|
|
|
nsTArray<RefPtr<AudioDeviceInfo>> devices;
|
2019-09-20 13:13:51 +03:00
|
|
|
GetEnumerator()->EnumerateAudioInputDevices(devices);
|
2018-01-31 21:02:00 +03:00
|
|
|
|
2018-04-30 16:18:22 +03:00
|
|
|
DebugOnly<bool> foundPreferredDevice = false;
|
2018-01-31 21:02:00 +03:00
|
|
|
|
2018-04-30 16:18:22 +03:00
|
|
|
for (uint32_t i = 0; i < devices.Length(); i++) {
|
2018-07-04 19:00:57 +03:00
|
|
|
#ifndef ANDROID
|
2018-04-30 16:18:22 +03:00
|
|
|
MOZ_ASSERT(devices[i]->DeviceID());
|
2018-07-04 19:00:57 +03:00
|
|
|
#endif
|
2018-04-30 16:18:22 +03:00
|
|
|
LOG(("Cubeb device %u: type 0x%x, state 0x%x, name %s, id %p", i,
|
|
|
|
devices[i]->Type(), devices[i]->State(),
|
|
|
|
NS_ConvertUTF16toUTF8(devices[i]->Name()).get(),
|
|
|
|
devices[i]->DeviceID()));
|
|
|
|
|
|
|
|
if (devices[i]->State() == CUBEB_DEVICE_STATE_ENABLED) {
|
|
|
|
MOZ_ASSERT(devices[i]->Type() == CUBEB_DEVICE_TYPE_INPUT);
|
|
|
|
RefPtr<MediaEngineSource> source = new MediaEngineWebRTCMicrophoneSource(
|
2018-05-29 16:20:47 +03:00
|
|
|
devices[i], devices[i]->Name(),
|
|
|
|
// Lie and provide the name as UUID
|
2019-03-08 14:51:59 +03:00
|
|
|
NS_ConvertUTF16toUTF8(devices[i]->Name()), devices[i]->GroupID(),
|
|
|
|
devices[i]->MaxChannels(), mDelayAgnostic, mExtendedFilter);
|
2018-05-29 16:20:47 +03:00
|
|
|
RefPtr<MediaDevice> device = MakeRefPtr<MediaDevice>(
|
2018-10-12 11:48:22 +03:00
|
|
|
source, source->GetName(), NS_ConvertUTF8toUTF16(source->GetUUID()),
|
2020-07-01 11:29:29 +03:00
|
|
|
source->GetGroupId(), u""_ns);
|
2018-05-29 16:20:47 +03:00
|
|
|
if (devices[i]->Preferred()) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (!foundPreferredDevice) {
|
|
|
|
foundPreferredDevice = true;
|
|
|
|
} else {
|
2019-04-16 18:42:42 +03:00
|
|
|
// This is possible on windows, there is a default communication
|
|
|
|
// device, and a default device:
|
|
|
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1542739
|
|
|
|
# ifndef XP_WIN
|
2018-05-29 16:20:47 +03:00
|
|
|
MOZ_ASSERT(!foundPreferredDevice,
|
|
|
|
"Found more than one preferred audio input device"
|
|
|
|
"while enumerating");
|
2019-04-16 18:42:42 +03:00
|
|
|
# endif
|
2018-05-29 16:20:47 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
aDevices->InsertElementAt(0, device);
|
|
|
|
} else {
|
|
|
|
aDevices->AppendElement(device);
|
|
|
|
}
|
2018-07-16 12:30:46 +03:00
|
|
|
}
|
|
|
|
}
|
2018-07-16 12:30:46 +03:00
|
|
|
}
|
|
|
|
|
2018-07-16 12:30:46 +03:00
|
|
|
void MediaEngineWebRTC::EnumerateSpeakerDevices(
|
|
|
|
uint64_t aWindowId, nsTArray<RefPtr<MediaDevice>>* aDevices) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
|
|
|
|
2018-07-16 12:30:46 +03:00
|
|
|
nsTArray<RefPtr<AudioDeviceInfo>> devices;
|
2019-09-20 13:13:51 +03:00
|
|
|
GetEnumerator()->EnumerateAudioOutputDevices(devices);
|
2018-11-08 15:33:33 +03:00
|
|
|
|
2019-09-05 20:17:33 +03:00
|
|
|
#ifndef XP_WIN
|
2019-03-19 13:39:57 +03:00
|
|
|
DebugOnly<bool> preferredDeviceFound = false;
|
2019-09-05 20:17:33 +03:00
|
|
|
#endif
|
2018-07-16 12:30:46 +03:00
|
|
|
for (auto& device : devices) {
|
|
|
|
if (device->State() == CUBEB_DEVICE_STATE_ENABLED) {
|
|
|
|
MOZ_ASSERT(device->Type() == CUBEB_DEVICE_TYPE_OUTPUT);
|
2018-05-29 16:20:47 +03:00
|
|
|
nsString uuid(device->Name());
|
2018-07-16 12:30:46 +03:00
|
|
|
// If, for example, input and output are in the same device, uuid
|
|
|
|
// would be the same for both which ends up to create the same
|
|
|
|
// deviceIDs (in JS).
|
2020-07-01 11:29:29 +03:00
|
|
|
uuid.Append(u"_Speaker"_ns);
|
2019-03-08 14:51:45 +03:00
|
|
|
nsString groupId(device->GroupID());
|
2019-03-19 13:39:57 +03:00
|
|
|
if (device->Preferred()) {
|
2019-09-05 20:17:33 +03:00
|
|
|
// In windows is possible to have more than one preferred device
|
|
|
|
#if defined(DEBUG) && !defined(XP_WIN)
|
|
|
|
MOZ_ASSERT(!preferredDeviceFound, "More than one preferred device");
|
2019-03-19 13:39:57 +03:00
|
|
|
preferredDeviceFound = true;
|
|
|
|
#endif
|
|
|
|
aDevices->InsertElementAt(
|
|
|
|
0, MakeRefPtr<MediaDevice>(device, uuid, groupId));
|
|
|
|
} else {
|
|
|
|
aDevices->AppendElement(MakeRefPtr<MediaDevice>(device, uuid, groupId));
|
|
|
|
}
|
2018-07-16 12:30:46 +03:00
|
|
|
}
|
|
|
|
}
|
2018-07-16 12:30:46 +03:00
|
|
|
}
|
|
|
|
|
2018-05-07 20:33:41 +03:00
|
|
|
void MediaEngineWebRTC::EnumerateDevices(
|
|
|
|
uint64_t aWindowId, dom::MediaSourceEnum aMediaSource,
|
2018-04-30 16:18:22 +03:00
|
|
|
MediaSinkEnum aMediaSink, nsTArray<RefPtr<MediaDevice>>* aDevices) {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
2018-07-16 12:30:46 +03:00
|
|
|
MOZ_ASSERT(aMediaSource != dom::MediaSourceEnum::Other ||
|
|
|
|
aMediaSink != MediaSinkEnum::Other);
|
2018-05-07 20:33:41 +03:00
|
|
|
if (MediaEngineSource::IsVideo(aMediaSource)) {
|
2018-12-28 02:40:36 +03:00
|
|
|
switch (aMediaSource) {
|
|
|
|
case dom::MediaSourceEnum::Window:
|
|
|
|
// Since the mediaSource constraint is deprecated, treat the Window
|
|
|
|
// value as a request for getDisplayMedia-equivalent sharing: Combine
|
|
|
|
// window and fullscreen into a single list of choices. The other values
|
|
|
|
// are still useful for testing.
|
|
|
|
EnumerateVideoDevices(aWindowId, camera::WinEngine, aDevices);
|
2020-08-07 19:55:02 +03:00
|
|
|
EnumerateVideoDevices(aWindowId, camera::BrowserEngine, aDevices);
|
2020-08-10 18:58:23 +03:00
|
|
|
EnumerateVideoDevices(aWindowId, camera::ScreenEngine, aDevices);
|
2018-12-28 02:40:36 +03:00
|
|
|
break;
|
|
|
|
case dom::MediaSourceEnum::Screen:
|
|
|
|
EnumerateVideoDevices(aWindowId, camera::ScreenEngine, aDevices);
|
|
|
|
break;
|
|
|
|
case dom::MediaSourceEnum::Browser:
|
|
|
|
EnumerateVideoDevices(aWindowId, camera::BrowserEngine, aDevices);
|
|
|
|
break;
|
|
|
|
case dom::MediaSourceEnum::Camera:
|
|
|
|
EnumerateVideoDevices(aWindowId, camera::CameraEngine, aDevices);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("No valid video source");
|
|
|
|
break;
|
|
|
|
}
|
2018-05-07 20:33:41 +03:00
|
|
|
} else if (aMediaSource == dom::MediaSourceEnum::AudioCapture) {
|
|
|
|
RefPtr<MediaEngineWebRTCAudioCaptureSource> audioCaptureSource =
|
|
|
|
new MediaEngineWebRTCAudioCaptureSource(nullptr);
|
2018-07-11 09:59:13 +03:00
|
|
|
aDevices->AppendElement(MakeRefPtr<MediaDevice>(
|
|
|
|
audioCaptureSource, audioCaptureSource->GetName(),
|
2018-10-12 11:48:22 +03:00
|
|
|
NS_ConvertUTF8toUTF16(audioCaptureSource->GetUUID()),
|
2020-07-01 11:29:29 +03:00
|
|
|
audioCaptureSource->GetGroupId(), u""_ns));
|
2018-07-16 12:30:46 +03:00
|
|
|
} else if (aMediaSource == dom::MediaSourceEnum::Microphone) {
|
2018-07-11 09:59:13 +03:00
|
|
|
EnumerateMicrophoneDevices(aWindowId, aDevices);
|
2018-07-16 12:30:46 +03:00
|
|
|
}
|
2018-07-16 12:30:46 +03:00
|
|
|
|
|
|
|
if (aMediaSink == MediaSinkEnum::Speaker) {
|
|
|
|
EnumerateSpeakerDevices(aWindowId, aDevices);
|
|
|
|
}
|
2018-05-07 20:33:41 +03:00
|
|
|
}
|
|
|
|
|
2012-07-12 15:53:08 +04:00
|
|
|
void MediaEngineWebRTC::Shutdown() {
|
2019-10-29 16:01:36 +03:00
|
|
|
AssertIsOnOwningThread();
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!mFakeDeviceChangeEventTimer);
|
|
|
|
mCameraListChangeListener.DisconnectIfExists();
|
|
|
|
mMicrophoneListChangeListener.DisconnectIfExists();
|
|
|
|
mSpeakerListChangeListener.DisconnectIfExists();
|
2016-08-11 20:04:49 +03:00
|
|
|
|
2015-05-29 21:28:03 +03:00
|
|
|
LOG(("%s", __FUNCTION__));
|
2015-08-31 15:51:29 +03:00
|
|
|
mozilla::camera::Shutdown();
|
2018-04-30 16:18:22 +03:00
|
|
|
}
|
|
|
|
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
/* static */ void MediaEngineWebRTC::FakeDeviceChangeEventTimerTick(
|
|
|
|
nsITimer* aTimer, void* aClosure) {
|
|
|
|
MediaEngineWebRTC* self = static_cast<MediaEngineWebRTC*>(aClosure);
|
2020-07-09 09:12:10 +03:00
|
|
|
self->AssertIsOnOwningThread();
|
Bug 1582637 - Move internal DeviceChange events to higher order functions. r=jib,achronop
This does three major things:
1) Moves the DeviceChange events from manual callbacks/listeners to
MediaEventSource/MediaEventListener. This is the reason this patch is so
large, as it traverses a lot of files.
There are four layers (from low to high):
- CamerasChild for camera device list changes, and CubebDeviceEnumerator for
microphone and speaker device list changes
- MediaEngineWebRTC, which gathers these into a single listener
- MediaManager, which owns the MediaEngineWebRTC backend
- MediaDevices, where the events from MediaManager are exposed to js
2) Changes the fake event triggering from starting a 30-event burst on setting
the js event listener, to a toggle, so that while the pref is on the events
keep coming.
3) Moves the fake event generation from CamerasChild to MediaEngineWebRTC, since
that's the lowest level where we are aware of both video and audio events.
The fake event generation is also greatly simplified. From being a dedicated
thread with periodic runnables, it is now a periodic timer on main thread
that fires while fake events are enabled. MediaEventProducer gracefully
handles thread safety.
Differential Revision: https://phabricator.services.mozilla.com/D48516
--HG--
extra : moz-landing-system : lando
2019-10-29 16:01:43 +03:00
|
|
|
self->DeviceListChanged();
|
|
|
|
}
|
|
|
|
|
2012-07-12 15:53:08 +04:00
|
|
|
} // namespace mozilla
|