Bug 934425 - Create a method in MediaManager to look up a given sink id. r=jib

Implement a new method in MediaManager that enumerates audio output devices and looks up for a given sink id asynchronously.

Differential Revision: https://phabricator.services.mozilla.com/D5870

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alex Chronopoulos 2018-10-12 08:44:23 +00:00
parent 12ad318568
commit 662ff54a4e
2 changed files with 76 additions and 0 deletions

View File

@ -3414,6 +3414,61 @@ MediaManager::EnumerateDevices(nsPIDOMWindowInner* aWindow,
return NS_OK;
}
RefPtr<SinkInfoPromise>
MediaManager::GetSinkDevice(nsPIDOMWindowInner* aWindow,
const nsString& aDeviceId)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
// We have to add the window id here because enumerate methods
// check for that and abort silently if it does not exist.
uint64_t windowId = aWindow->WindowID();
nsIPrincipal* principal = aWindow->GetExtantDoc()->NodePrincipal();
RefPtr<GetUserMediaWindowListener> windowListener = GetWindowListener(windowId);
if (windowListener) {
PrincipalHandle existingPrincipalHandle =
windowListener->GetPrincipalHandle();
MOZ_ASSERT(PrincipalHandleMatches(existingPrincipalHandle, principal));
} else {
windowListener = new GetUserMediaWindowListener(mMediaThread, windowId,
MakePrincipalHandle(principal));
AddWindowID(windowId, windowListener);
}
// Create an inactive SourceListener to act as a placeholder, so the
// window listener doesn't clean itself up until we're done.
RefPtr<SourceListener> sourceListener = new SourceListener();
windowListener->Register(sourceListener);
bool isSecure = aWindow->IsSecureContext();
return EnumerateDevicesImpl(aWindow->WindowID(),
MediaSourceEnum::Other,
MediaSourceEnum::Other,
MediaSinkEnum::Speaker,
DeviceEnumerationType::Normal,
DeviceEnumerationType::Normal)
->Then(GetCurrentThreadSerialEventTarget(), __func__,
[aDeviceId, isSecure](RefPtr<MediaDeviceSetRefCnt>&& aDevices) {
for (RefPtr<MediaDevice>& device : **aDevices) {
if (aDeviceId.IsEmpty() && device->mSinkInfo->Preferred()) {
return SinkInfoPromise::CreateAndResolve(device->mSinkInfo, __func__);
}
if (device->mID.Equals(aDeviceId)) {
// TODO: Check if the application is authorized to play audio
// through this device (Bug 1493982).
if (isSecure || device->mSinkInfo->Preferred()) {
return SinkInfoPromise::CreateAndResolve(device->mSinkInfo, __func__);
}
return SinkInfoPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR, __func__);
}
}
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
}, [](RefPtr<MediaStreamError>&& reason) {
return SinkInfoPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
});
}
/*
* GetUserMediaDevices - called by the UI-part of getUserMedia from chrome JS.
*/

View File

@ -138,6 +138,7 @@ public:
};
typedef nsRefPtrHashtable<nsUint64HashKey, GetUserMediaWindowListener> WindowTable;
typedef MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true> SinkInfoPromise;
class MediaManager final : public nsIMediaManagerService,
public nsIObserver
@ -227,6 +228,26 @@ public:
dom::CallerType aCallerType);
nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow, dom::Promise& aPromise);
// 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. The default device is always allowed. Non default
// devices are allowed only in secure context. 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.
// Currently, this happens only on non-default default devices
// and non https connections. 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);
bool IsActivelyCapturingOrHasAPermission(uint64_t aWindowId);