Bug 1753131 - use MediaManager device list change coalescing for MediaDevices r=jib

There is a chance that this may result in some associated events no longer
being coalesced into a single devicechange event, but there is little
disadvantage to this while there is an advantage to getting devicechange
events promptly.

Future changes in https://phabricator.services.mozilla.com/D132908 will
track exactly which devices have changed and so filter out no-op
notifications.

Depends on D132892

Differential Revision: https://phabricator.services.mozilla.com/D132893
This commit is contained in:
Karl Tomlinson 2022-02-02 05:35:26 +00:00
parent e533d4090f
commit b2ebc6966e
4 changed files with 11 additions and 30 deletions

View File

@ -22,8 +22,6 @@
#include "nsPIDOMWindow.h"
#include "nsQueryObject.h"
#define DEVICECHANGE_HOLD_TIME_IN_MS 1000
namespace mozilla::dom {
using EnumerationFlag = MediaManager::EnumerationFlag;
@ -34,9 +32,6 @@ MediaDevices::MediaDevices(nsPIDOMWindowInner* aWindow)
MediaDevices::~MediaDevices() {
MOZ_ASSERT(NS_IsMainThread());
if (mFuzzTimer) {
mFuzzTimer->Cancel();
}
mDeviceChangeListener.DisconnectIfExists();
}
@ -534,26 +529,10 @@ void MediaDevices::OnDeviceChange() {
return;
}
if (mFuzzTimer) {
// An event is already in flight.
return;
}
mFuzzTimer = NS_NewTimer();
if (!mFuzzTimer) {
MOZ_ASSERT(false);
return;
}
mFuzzTimer->InitWithNamedFuncCallback(
[](nsITimer*, void* aClosure) {
MediaDevices* md = static_cast<MediaDevices*>(aClosure);
md->DispatchTrustedEvent(u"devicechange"_ns);
md->mFuzzTimer = nullptr;
},
this, DEVICECHANGE_HOLD_TIME_IN_MS, nsITimer::TYPE_ONE_SHOT,
"MediaDevices::mFuzzTimer Callback");
NS_DispatchToCurrentThread(
NS_NewRunnableFunction("devicechange", [self = RefPtr(this), this] {
DispatchTrustedEvent(u"devicechange"_ns);
}));
}
mozilla::dom::EventHandlerNonNull* MediaDevices::GetOndevicechange() {

View File

@ -14,7 +14,6 @@
#include "nsCOMPtr.h"
#include "nsID.h"
#include "nsISupports.h"
#include "nsITimer.h"
#include "nsTHashSet.h"
class AudioDeviceInfo;
@ -95,7 +94,6 @@ class MediaDevices final : public DOMEventTargetHelper {
nsTHashSet<nsString> mExplicitlyGrantedAudioOutputIds;
nsTArray<RefPtr<Promise>> mPendingEnumerateDevicesPromises;
nsCOMPtr<nsITimer> mFuzzTimer;
// Connect/Disconnect on main thread only
MediaEventListener mDeviceChangeListener;

View File

@ -2187,8 +2187,6 @@ void MediaManager::DeviceListChanged() {
if (sHasShutdown) {
return;
}
mDeviceListChangeEvent.Notify();
// 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.
@ -2227,6 +2225,8 @@ void MediaManager::DeviceListChanged() {
}
void MediaManager::HandleDeviceListChanged() {
mDeviceListChangeEvent.Notify();
EnumerateRawDevices(MediaSourceEnum::Camera, MediaSourceEnum::Microphone,
EnumerationFlag::EnumerateAudioOutputs)
->Then(

View File

@ -17,7 +17,11 @@ namespace media {
/* media::NewTaskFrom() - Create a Task from a lambda.
*
* Similar to media::NewRunnableFrom() - Create an nsRunnable from a lambda.
* Similar to media::NewRunnableFrom() - Create an nsRunnable from a lambda,
* but ignore the return value from the lambda.
*
* Prefer NS_NewRunnableFunction(), which provides a specific name, unless the
* lambda really must have a non-void return value that is to be ignored.
*/
template <typename OnRunType>