зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1493982 accept only sinkIds exposed via enumerateDevices() r=jib
and reject with NotFoundError otherwise. Depends on D118444 Differential Revision: https://phabricator.services.mozilla.com/D118445
This commit is contained in:
Родитель
832509f1a5
Коммит
ebbb65d72e
|
@ -7560,9 +7560,6 @@ already_AddRefed<Promise> HTMLMediaElement::SetSinkId(const nsAString& aSinkId,
|
|||
"The object can not be found here.");
|
||||
break;
|
||||
}
|
||||
case NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR:
|
||||
promise->MaybeReject(NS_ERROR_DOM_NOT_ALLOWED_ERR);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid error.");
|
||||
}
|
||||
|
|
|
@ -405,30 +405,65 @@ static RefPtr<AudioDeviceInfo> CopyWithNullDeviceId(
|
|||
RefPtr<MediaDevices::SinkInfoPromise> MediaDevices::GetSinkDevice(
|
||||
const nsString& aDeviceId) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool isExposed = aDeviceId.IsEmpty() ||
|
||||
mExplicitlyGrantedAudioOutputIds.Contains(aDeviceId);
|
||||
// If the device id is not exposed, then check microphone groupIds.
|
||||
MediaSourceEnum audioInputType = isExposed || !mCanExposeMicrophoneInfo
|
||||
? MediaSourceEnum::Other
|
||||
: MediaSourceEnum::Microphone;
|
||||
|
||||
auto devices = MakeRefPtr<MediaManager::MediaDeviceSetRefCnt>();
|
||||
return MediaManager::Get()
|
||||
->EnumerateDevicesImpl(GetOwner(), MediaSourceEnum::Other,
|
||||
MediaSourceEnum::Other, MediaSinkEnum::Speaker,
|
||||
->EnumerateDevicesImpl(GetOwner(), MediaSourceEnum::Other, audioInputType,
|
||||
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__);
|
||||
[aDeviceId, isExposed, devices](bool) mutable {
|
||||
RefPtr<AudioDeviceInfo> outputInfo;
|
||||
nsString groupId;
|
||||
// Check for a matching device.
|
||||
for (const RefPtr<MediaDevice>& device : *devices) {
|
||||
if (device->mKind != dom::MediaDeviceKind::Audiooutput) {
|
||||
continue;
|
||||
}
|
||||
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__);
|
||||
if (aDeviceId.IsEmpty()) {
|
||||
if (device->mSinkInfo->Preferred()) {
|
||||
outputInfo = CopyWithNullDeviceId(device->mSinkInfo);
|
||||
break;
|
||||
}
|
||||
} else if (aDeviceId.Equals(device->mID)) {
|
||||
outputInfo = device->mSinkInfo;
|
||||
groupId = device->mGroupID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
if (outputInfo && !isExposed) {
|
||||
// Check microphone groups.
|
||||
MOZ_ASSERT(!groupId.IsEmpty());
|
||||
for (const RefPtr<MediaDevice>& device : *devices) {
|
||||
if (device->mKind != dom::MediaDeviceKind::Audioinput) {
|
||||
continue;
|
||||
}
|
||||
if (groupId.Equals(device->mGroupID)) {
|
||||
isExposed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If sinkId is not the empty string and does not match any audio
|
||||
* output device identified by the result that would be provided
|
||||
* by enumerateDevices(), reject p with a new DOMException whose
|
||||
* name is NotFoundError and abort these substeps. */
|
||||
if (!outputInfo || !isExposed) {
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
}
|
||||
return SinkInfoPromise::CreateAndResolve(outputInfo, __func__);
|
||||
},
|
||||
// aRejectMethod =
|
||||
[](RefPtr<MediaMgrError>&& aError) {
|
||||
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
|
||||
__func__);
|
||||
|
|
|
@ -70,18 +70,11 @@ class MediaDevices final : public DOMEventTargetHelper {
|
|||
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.
|
||||
// information if the aDeviceId matches a device that would be exposed by
|
||||
// enumerateDevices().
|
||||
// The promise will be rejected with NS_ERROR_NOT_AVAILABLE if aDeviceId
|
||||
// does not match any exposed device.
|
||||
RefPtr<SinkInfoPromise> GetSinkDevice(const nsString& aDeviceId);
|
||||
|
||||
// Called when MediaManager encountered a change in its device lists.
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[setSinkId-with-selectAudioOutput.https.html]
|
||||
[setSinkId() with deviceID from another window]
|
||||
expected: FAIL
|
||||
|
Загрузка…
Ссылка в новой задаче