зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1493982 move GetSinkDevice() to MediaDevices for access to device exposure history r=jib
Depends on D118443 Differential Revision: https://phabricator.services.mozilla.com/D118444
This commit is contained in:
Родитель
e73a2aa7e8
Коммит
832509f1a5
|
@ -44,6 +44,7 @@
|
|||
#include "MediaStreamWindowCapturer.h"
|
||||
#include "MediaTrack.h"
|
||||
#include "MediaTrackList.h"
|
||||
#include "Navigator.h"
|
||||
#include "TimeRanges.h"
|
||||
#include "VideoFrameContainer.h"
|
||||
#include "VideoOutput.h"
|
||||
|
@ -75,6 +76,7 @@
|
|||
#include "mozilla/dom/HTMLSourceElement.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/MediaControlUtils.h"
|
||||
#include "mozilla/dom/MediaDevices.h"
|
||||
#include "mozilla/dom/MediaEncryptedEvent.h"
|
||||
#include "mozilla/dom/MediaErrorBinding.h"
|
||||
#include "mozilla/dom/MediaSource.h"
|
||||
|
@ -160,6 +162,7 @@ using namespace mozilla::dom::HTMLMediaElement_Binding;
|
|||
namespace mozilla::dom {
|
||||
|
||||
using AudibleState = AudioChannelService::AudibleState;
|
||||
using SinkInfoPromise = MediaDevices::SinkInfoPromise;
|
||||
|
||||
// Number of milliseconds between progress events as defined by spec
|
||||
static const uint32_t PROGRESS_MS = 350;
|
||||
|
@ -7493,9 +7496,13 @@ already_AddRefed<Promise> HTMLMediaElement::SetSinkId(const nsAString& aSinkId,
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
RefPtr<MediaDevices> mediaDevices = win->Navigator()->GetMediaDevices(aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsString sinkId(aSinkId);
|
||||
MediaManager::Get()
|
||||
->GetSinkDevice(win, sinkId)
|
||||
mediaDevices->GetSinkDevice(sinkId)
|
||||
->Then(
|
||||
mAbstractMainThread, __func__,
|
||||
[self = RefPtr<HTMLMediaElement>(this),
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "mozilla/dom/MediaDevices.h"
|
||||
|
||||
#include "AudioDeviceInfo.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaDeviceInfo.h"
|
||||
|
@ -23,6 +24,8 @@
|
|||
|
||||
namespace mozilla::dom {
|
||||
|
||||
using DeviceEnumerationType = MediaManager::DeviceEnumerationType;
|
||||
|
||||
MediaDevices::MediaDevices(nsPIDOMWindowInner* aWindow)
|
||||
: DOMEventTargetHelper(aWindow) {}
|
||||
|
||||
|
@ -364,6 +367,74 @@ already_AddRefed<Promise> MediaDevices::SelectAudioOutput(
|
|||
return p.forget();
|
||||
}
|
||||
|
||||
static RefPtr<AudioDeviceInfo> CopyWithNullDeviceId(
|
||||
AudioDeviceInfo* aDeviceInfo) {
|
||||
MOZ_ASSERT(aDeviceInfo->Preferred());
|
||||
|
||||
nsString vendor;
|
||||
aDeviceInfo->GetVendor(vendor);
|
||||
uint16_t type;
|
||||
aDeviceInfo->GetType(&type);
|
||||
uint16_t state;
|
||||
aDeviceInfo->GetState(&state);
|
||||
uint16_t pref;
|
||||
aDeviceInfo->GetPreferred(&pref);
|
||||
uint16_t supportedFormat;
|
||||
aDeviceInfo->GetSupportedFormat(&supportedFormat);
|
||||
uint16_t defaultFormat;
|
||||
aDeviceInfo->GetDefaultFormat(&defaultFormat);
|
||||
uint32_t maxChannels;
|
||||
aDeviceInfo->GetMaxChannels(&maxChannels);
|
||||
uint32_t defaultRate;
|
||||
aDeviceInfo->GetDefaultRate(&defaultRate);
|
||||
uint32_t maxRate;
|
||||
aDeviceInfo->GetMaxRate(&maxRate);
|
||||
uint32_t minRate;
|
||||
aDeviceInfo->GetMinRate(&minRate);
|
||||
uint32_t maxLatency;
|
||||
aDeviceInfo->GetMaxLatency(&maxLatency);
|
||||
uint32_t minLatency;
|
||||
aDeviceInfo->GetMinLatency(&minLatency);
|
||||
|
||||
return MakeRefPtr<AudioDeviceInfo>(
|
||||
nullptr, aDeviceInfo->Name(), aDeviceInfo->GroupID(), vendor, type, state,
|
||||
pref, supportedFormat, defaultFormat, maxChannels, defaultRate, maxRate,
|
||||
minRate, maxLatency, minLatency);
|
||||
}
|
||||
|
||||
RefPtr<MediaDevices::SinkInfoPromise> MediaDevices::GetSinkDevice(
|
||||
const nsString& aDeviceId) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
auto devices = MakeRefPtr<MediaManager::MediaDeviceSetRefCnt>();
|
||||
return MediaManager::Get()
|
||||
->EnumerateDevicesImpl(GetOwner(), MediaSourceEnum::Other,
|
||||
MediaSourceEnum::Other, MediaSinkEnum::Speaker,
|
||||
DeviceEnumerationType::Normal,
|
||||
DeviceEnumerationType::Normal, true, devices)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[aDeviceId, devices](bool) {
|
||||
for (RefPtr<MediaDevice>& device : *devices) {
|
||||
if (aDeviceId.IsEmpty() && device->mSinkInfo->Preferred()) {
|
||||
return SinkInfoPromise::CreateAndResolve(
|
||||
CopyWithNullDeviceId(device->mSinkInfo), __func__);
|
||||
}
|
||||
if (device->mID.Equals(aDeviceId)) {
|
||||
// TODO: Check if the application is authorized to play audio
|
||||
// through this device (Bug 1493982).
|
||||
return SinkInfoPromise::CreateAndResolve(device->mSinkInfo,
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
},
|
||||
[](RefPtr<MediaMgrError>&& aError) {
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
});
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(MediaDevices, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(MediaDevices, DOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_BEGIN(MediaDevices)
|
||||
|
|
|
@ -17,7 +17,13 @@
|
|||
#include "nsITimer.h"
|
||||
#include "nsTHashSet.h"
|
||||
|
||||
class AudioDeviceInfo;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
|
||||
class MozPromise;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
|
@ -35,6 +41,8 @@ struct AudioOutputOptions;
|
|||
|
||||
class MediaDevices final : public DOMEventTargetHelper {
|
||||
public:
|
||||
using SinkInfoPromise = MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true>;
|
||||
|
||||
explicit MediaDevices(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -61,6 +69,21 @@ class MediaDevices final : public DOMEventTargetHelper {
|
|||
const AudioOutputOptions& aOptions, CallerType aCallerType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Get the sink that corresponds to the given device id.
|
||||
// It is resposible to check if an application is
|
||||
// authorized to play audio through the requested device.
|
||||
// The returned promise will be resolved with the device
|
||||
// information if the device id matches one and operation is
|
||||
// allowed. It is pending to implement an user authorization model.
|
||||
// The promise will be rejected in the following cases:
|
||||
// NS_ERROR_NOT_AVAILABLE: Device id does not exist.
|
||||
// NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR:
|
||||
// The requested device exists but it is not allowed to be used.
|
||||
// TODO, authorization model to allow an application to play audio through
|
||||
// the device (Bug 1493982).
|
||||
// NS_ERROR_ABORT: General error.
|
||||
RefPtr<SinkInfoPromise> GetSinkDevice(const nsString& aDeviceId);
|
||||
|
||||
// Called when MediaManager encountered a change in its device lists.
|
||||
void OnDeviceChange();
|
||||
|
||||
|
|
|
@ -3258,75 +3258,6 @@ RefPtr<MediaManager::DevicePromise> MediaManager::SelectAudioOutput(
|
|||
});
|
||||
}
|
||||
|
||||
RefPtr<AudioDeviceInfo> CopyWithNullDeviceId(AudioDeviceInfo* aDeviceInfo) {
|
||||
MOZ_ASSERT(aDeviceInfo->Preferred());
|
||||
|
||||
nsString vendor;
|
||||
aDeviceInfo->GetVendor(vendor);
|
||||
uint16_t type;
|
||||
aDeviceInfo->GetType(&type);
|
||||
uint16_t state;
|
||||
aDeviceInfo->GetState(&state);
|
||||
uint16_t pref;
|
||||
aDeviceInfo->GetPreferred(&pref);
|
||||
uint16_t supportedFormat;
|
||||
aDeviceInfo->GetSupportedFormat(&supportedFormat);
|
||||
uint16_t defaultFormat;
|
||||
aDeviceInfo->GetDefaultFormat(&defaultFormat);
|
||||
uint32_t maxChannels;
|
||||
aDeviceInfo->GetMaxChannels(&maxChannels);
|
||||
uint32_t defaultRate;
|
||||
aDeviceInfo->GetDefaultRate(&defaultRate);
|
||||
uint32_t maxRate;
|
||||
aDeviceInfo->GetMaxRate(&maxRate);
|
||||
uint32_t minRate;
|
||||
aDeviceInfo->GetMinRate(&minRate);
|
||||
uint32_t maxLatency;
|
||||
aDeviceInfo->GetMaxLatency(&maxLatency);
|
||||
uint32_t minLatency;
|
||||
aDeviceInfo->GetMinLatency(&minLatency);
|
||||
|
||||
return MakeRefPtr<AudioDeviceInfo>(
|
||||
nullptr, aDeviceInfo->Name(), aDeviceInfo->GroupID(), vendor, type, state,
|
||||
pref, supportedFormat, defaultFormat, maxChannels, defaultRate, maxRate,
|
||||
minRate, maxLatency, minLatency);
|
||||
}
|
||||
|
||||
RefPtr<SinkInfoPromise> MediaManager::GetSinkDevice(nsPIDOMWindowInner* aWindow,
|
||||
const nsString& aDeviceId) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsSecureContext());
|
||||
|
||||
auto devices = MakeRefPtr<MediaDeviceSetRefCnt>();
|
||||
return EnumerateDevicesImpl(aWindow, MediaSourceEnum::Other,
|
||||
MediaSourceEnum::Other, MediaSinkEnum::Speaker,
|
||||
DeviceEnumerationType::Normal,
|
||||
DeviceEnumerationType::Normal, true, devices)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[aDeviceId, devices](bool) {
|
||||
for (RefPtr<MediaDevice>& device : *devices) {
|
||||
if (aDeviceId.IsEmpty() && device->mSinkInfo->Preferred()) {
|
||||
return SinkInfoPromise::CreateAndResolve(
|
||||
CopyWithNullDeviceId(device->mSinkInfo), __func__);
|
||||
}
|
||||
if (device->mID.Equals(aDeviceId)) {
|
||||
// TODO: Check if the application is authorized to play audio
|
||||
// through this device (Bug 1493982).
|
||||
return SinkInfoPromise::CreateAndResolve(device->mSinkInfo,
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
},
|
||||
[](RefPtr<MediaMgrError>&& aError) {
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
});
|
||||
}
|
||||
|
||||
MediaEngine* MediaManager::GetBackend() {
|
||||
MOZ_ASSERT(MediaManager::IsInMediaThread());
|
||||
// Plugin backends as appropriate. The default engine also currently
|
||||
|
|
|
@ -134,7 +134,6 @@ class MediaDevice : public nsIMediaDevice {
|
|||
|
||||
typedef nsRefPtrHashtable<nsUint64HashKey, GetUserMediaWindowListener>
|
||||
WindowTable;
|
||||
typedef MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true> SinkInfoPromise;
|
||||
|
||||
class MediaManager final : public nsIMediaManagerService,
|
||||
public nsIMemoryReporter,
|
||||
|
@ -236,24 +235,22 @@ class MediaManager final : public nsIMediaManagerService,
|
|||
RefPtr<DeviceSetPromise> EnumerateDevices(nsPIDOMWindowInner* aWindow,
|
||||
dom::CallerType aCallerType);
|
||||
|
||||
enum class DeviceEnumerationType : uint8_t {
|
||||
Normal, // Enumeration should not return loopback or fake devices
|
||||
Fake, // Enumeration should return fake device(s)
|
||||
Loopback /* Enumeration should return loopback device(s) (possibly in
|
||||
addition to normal devices) */
|
||||
};
|
||||
RefPtr<MgrPromise> EnumerateDevicesImpl(
|
||||
nsPIDOMWindowInner* aWindow, dom::MediaSourceEnum aVideoInputType,
|
||||
dom::MediaSourceEnum aAudioInputType, MediaSinkEnum aAudioOutputType,
|
||||
DeviceEnumerationType aVideoInputEnumType,
|
||||
DeviceEnumerationType aAudioInputEnumType, bool aForceNoPermRequest,
|
||||
const RefPtr<MediaDeviceSetRefCnt>& aOutDevices);
|
||||
|
||||
RefPtr<DevicePromise> SelectAudioOutput(
|
||||
nsPIDOMWindowInner* aWindow, const dom::AudioOutputOptions& aOptions,
|
||||
dom::CallerType aCallerType);
|
||||
// Get the sink that corresponds to the given device id.
|
||||
// It is resposible to check if an application is
|
||||
// authorized to play audio through the requested device.
|
||||
// The returned promise will be resolved with the device
|
||||
// information if the device id matches one and operation is
|
||||
// allowed. It is pending to implement an user authorization model.
|
||||
// The promise will be rejected in the following cases:
|
||||
// NS_ERROR_NOT_AVAILABLE: Device id does not exist.
|
||||
// NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR:
|
||||
// The requested device exists but it is not allowed to be used.
|
||||
// TODO, authorization model to allow an application to play audio through
|
||||
// the device (Bug 1493982).
|
||||
// NS_ERROR_ABORT: General error.
|
||||
RefPtr<SinkInfoPromise> GetSinkDevice(nsPIDOMWindowInner* aWindow,
|
||||
const nsString& aDeviceId);
|
||||
|
||||
void OnNavigation(uint64_t aWindowID);
|
||||
void OnCameraMute(bool aMute);
|
||||
|
@ -288,13 +285,6 @@ class MediaManager final : public nsIMediaManagerService,
|
|||
const MediaDeviceSet& aAudios);
|
||||
|
||||
private:
|
||||
enum class DeviceEnumerationType : uint8_t {
|
||||
Normal, // Enumeration should not return loopback or fake devices
|
||||
Fake, // Enumeration should return fake device(s)
|
||||
Loopback /* Enumeration should return loopback device(s) (possibly in
|
||||
addition to normal devices) */
|
||||
};
|
||||
|
||||
RefPtr<MgrPromise> EnumerateRawDevices(
|
||||
uint64_t aWindowId, dom::MediaSourceEnum aVideoInputType,
|
||||
dom::MediaSourceEnum aAudioInputType, MediaSinkEnum aAudioOutputType,
|
||||
|
@ -302,13 +292,6 @@ class MediaManager final : public nsIMediaManagerService,
|
|||
DeviceEnumerationType aAudioInputEnumType, bool aForceNoPermRequest,
|
||||
const RefPtr<MediaDeviceSetRefCnt>& aOutDevices);
|
||||
|
||||
RefPtr<MgrPromise> EnumerateDevicesImpl(
|
||||
nsPIDOMWindowInner* aWindow, dom::MediaSourceEnum aVideoInputType,
|
||||
dom::MediaSourceEnum aAudioInputType, MediaSinkEnum aAudioOutputType,
|
||||
DeviceEnumerationType aVideoInputEnumType,
|
||||
DeviceEnumerationType aAudioInputEnumType, bool aForceNoPermRequest,
|
||||
const RefPtr<MediaDeviceSetRefCnt>& aOutDevices);
|
||||
|
||||
RefPtr<BadConstraintsPromise> SelectSettings(
|
||||
const dom::MediaStreamConstraints& aConstraints,
|
||||
dom::CallerType aCallerType,
|
||||
|
|
Загрузка…
Ссылка в новой задаче