зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
12ad318568
Коммит
662ff54a4e
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче