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:
Karl Tomlinson 2021-07-06 23:37:33 +00:00
Родитель 832509f1a5
Коммит ebbb65d72e
4 изменённых файлов: 53 добавлений и 32 удалений

Просмотреть файл

@ -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