зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1654430 - Fix mDeviceIDs to only track real devices and not be overwritten by other enumerateDevices requests. r=pehrsons
Differential Revision: https://phabricator.services.mozilla.com/D89231
This commit is contained in:
Родитель
199d9e5953
Коммит
9dcf1f976c
|
@ -2217,8 +2217,12 @@ void MediaManager::DeviceListChanged() {
|
|||
}
|
||||
mDeviceListChangeEvent.Notify();
|
||||
|
||||
// On some Windows machines, if we call EnumerateRawDevices immediately after
|
||||
// receiving devicechange event, we would get an outdated devices list.
|
||||
// Wait 200 ms, because
|
||||
// A) on some Windows machines, if we call EnumerateRawDevices immediately
|
||||
// after receiving devicechange event, we'd get an outdated devices list.
|
||||
// B) Waiting helps coalesce multiple calls on us into one, which can happen
|
||||
// if a device with both audio input and output is attached or removed.
|
||||
// We want to react & fire a devicechange event only once in that case.
|
||||
|
||||
if (mDeviceChangeTimer) {
|
||||
mDeviceChangeTimer->Cancel();
|
||||
|
@ -2255,18 +2259,18 @@ void MediaManager::DeviceListChanged() {
|
|||
return;
|
||||
}
|
||||
|
||||
nsTArray<nsString> deviceIDs;
|
||||
MediaManager::DeviceIdSet deviceIDs;
|
||||
for (auto& device : *devices) {
|
||||
nsString id;
|
||||
device->GetId(id);
|
||||
if (!deviceIDs.Contains(id)) {
|
||||
deviceIDs.AppendElement(id);
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(deviceIDs.put(std::move(id)));
|
||||
}
|
||||
// For any removed devices, notify their listeners cleanly that the
|
||||
// source has stopped, so JS knows and usage indicators update.
|
||||
for (auto& id : mDeviceIDs) {
|
||||
if (deviceIDs.Contains(id)) {
|
||||
// For any real removed cameras, microphones or speakers, notify
|
||||
// their listeners cleanly that the source has stopped, so JS knows
|
||||
// and usage indicators update.
|
||||
for (auto iter = mDeviceIDs.iter(); !iter.done(); iter.next()) {
|
||||
const auto& id = iter.get();
|
||||
if (deviceIDs.has(id)) {
|
||||
// Device has not been removed
|
||||
continue;
|
||||
}
|
||||
|
@ -3127,7 +3131,8 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
})
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[aWindowId, originKey, aOutDevices](bool) {
|
||||
[aWindowId, originKey, aVideoInputEnumType, aAudioInputEnumType,
|
||||
aOutDevices](bool) {
|
||||
// Only run if window is still on our active list.
|
||||
MediaManager* mgr = MediaManager::GetIfExists();
|
||||
if (!mgr || !mgr->IsWindowStillActive(aWindowId)) {
|
||||
|
@ -3136,12 +3141,17 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateDevicesImpl(
|
|||
__func__);
|
||||
}
|
||||
|
||||
mgr->mDeviceIDs.Clear();
|
||||
for (auto& device : *aOutDevices) {
|
||||
nsString id;
|
||||
device->GetId(id);
|
||||
if (!mgr->mDeviceIDs.Contains(id)) {
|
||||
mgr->mDeviceIDs.AppendElement(id);
|
||||
if (device->mKind == MediaDeviceKind::Audiooutput ||
|
||||
(device->mKind == MediaDeviceKind::Audioinput &&
|
||||
aAudioInputEnumType != DeviceEnumerationType::Fake &&
|
||||
device->GetMediaSource() == MediaSourceEnum::Microphone) ||
|
||||
(device->mKind == MediaDeviceKind::Videoinput &&
|
||||
aVideoInputEnumType != DeviceEnumerationType::Fake &&
|
||||
device->GetMediaSource() == MediaSourceEnum::Camera)) {
|
||||
nsString id;
|
||||
device->GetId(id);
|
||||
MOZ_ALWAYS_TRUE(mgr->mDeviceIDs.put(std::move(id)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3670,7 +3680,7 @@ void MediaManager::Shutdown() {
|
|||
mActiveCallbacks.Clear();
|
||||
mCallIds.Clear();
|
||||
mPendingGUMRequest.Clear();
|
||||
mDeviceIDs.Clear();
|
||||
mDeviceIDs.clear();
|
||||
#ifdef MOZ_WEBRTC
|
||||
StopWebRtcLog();
|
||||
#endif
|
||||
|
|
|
@ -358,7 +358,21 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
static StaticRefPtr<MediaManager> sSingleton;
|
||||
static StaticMutex sSingletonMutex;
|
||||
|
||||
nsTArray<nsString> mDeviceIDs;
|
||||
struct nsStringHasher {
|
||||
using Key = nsString;
|
||||
using Lookup = nsString;
|
||||
|
||||
static HashNumber hash(const Lookup& aLookup) {
|
||||
return HashString(aLookup.get());
|
||||
}
|
||||
|
||||
static bool match(const Key& aKey, const Lookup& aLookup) {
|
||||
return aKey == aLookup;
|
||||
}
|
||||
};
|
||||
|
||||
using DeviceIdSet = HashSet<nsString, nsStringHasher, InfallibleAllocPolicy>;
|
||||
DeviceIdSet mDeviceIDs;
|
||||
|
||||
// Connect/Disconnect on media thread only
|
||||
MediaEventListener mDeviceListChangeListener;
|
||||
|
|
|
@ -47,7 +47,9 @@ class MediaEngine {
|
|||
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void SetFakeDeviceChangeEventsEnabled(bool aEnable) {}
|
||||
virtual void SetFakeDeviceChangeEventsEnabled(bool aEnable) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(false, "Fake events may not have started/stopped");
|
||||
}
|
||||
|
||||
virtual MediaEventSource<void>& DeviceListChangeEvent() = 0;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче