mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1177242 - Verify whether sandboxed Content process has permissions to access the camera/mic. r=jesup
This commit is contained in:
parent
403ceb2af6
commit
f96bb1b52c
@ -279,6 +279,7 @@ function prompt(aBrowser, aRequest) {
|
||||
requestTypes: requestTypes} = aRequest;
|
||||
let uri = Services.io.newURI(aRequest.documentURI, null, null);
|
||||
let host = getHost(uri);
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
|
||||
let chromeDoc = aBrowser.ownerDocument;
|
||||
let chromeWin = chromeDoc.defaultView;
|
||||
let stringBundle = chromeWin.gNavigatorBundle;
|
||||
@ -374,7 +375,16 @@ function prompt(aBrowser, aRequest) {
|
||||
if (micPerm == perms.PROMPT_ACTION)
|
||||
micPerm = perms.UNKNOWN_ACTION;
|
||||
|
||||
let camPermanentPerm = perms.testExactPermanentPermission(principal, "camera");
|
||||
let camPerm = perms.testExactPermission(uri, "camera");
|
||||
|
||||
// Session approval given but never used to allocate a camera, remove
|
||||
// and ask again
|
||||
if (camPerm && !camPermanentPerm) {
|
||||
perms.remove(uri, "camera");
|
||||
camPerm = perms.UNKNOWN_ACTION;
|
||||
}
|
||||
|
||||
if (camPerm == perms.PROMPT_ACTION)
|
||||
camPerm = perms.UNKNOWN_ACTION;
|
||||
|
||||
@ -515,11 +525,14 @@ function prompt(aBrowser, aRequest) {
|
||||
let listId = "webRTC-select" + (sharingScreen ? "Window" : "Camera") + "-menulist";
|
||||
let videoDeviceIndex = chromeDoc.getElementById(listId).value;
|
||||
let allowCamera = videoDeviceIndex != "-1";
|
||||
if (allowCamera)
|
||||
if (allowCamera) {
|
||||
allowedDevices.push(videoDeviceIndex);
|
||||
if (aRemember) {
|
||||
perms.add(uri, "camera",
|
||||
allowCamera ? perms.ALLOW_ACTION : perms.DENY_ACTION);
|
||||
// Session permission will be removed after use
|
||||
// (it's really one-shot, not for the entire session)
|
||||
perms.add(uri, "camera", perms.ALLOW_ACTION,
|
||||
aRemember ? perms.EXPIRE_NEVER : perms.EXPIRE_SESSION);
|
||||
} else if (aRemember) {
|
||||
perms.add(uri, "camera", perms.DENY_ACTION);
|
||||
}
|
||||
}
|
||||
if (audioDevices.length) {
|
||||
|
@ -634,13 +634,15 @@ AudioDevice::GetSource()
|
||||
}
|
||||
|
||||
nsresult VideoDevice::Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs) {
|
||||
return GetSource()->Allocate(aConstraints, aPrefs, mID);
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsACString& aOrigin) {
|
||||
return GetSource()->Allocate(aConstraints, aPrefs, mID, aOrigin);
|
||||
}
|
||||
|
||||
nsresult AudioDevice::Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs) {
|
||||
return GetSource()->Allocate(aConstraints, aPrefs, mID);
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsACString& aOrigin) {
|
||||
return GetSource()->Allocate(aConstraints, aPrefs, mID, aOrigin);
|
||||
}
|
||||
|
||||
nsresult VideoDevice::Restart(const dom::MediaTrackConstraints &aConstraints,
|
||||
@ -1203,7 +1205,8 @@ public:
|
||||
nsresult rv;
|
||||
|
||||
if (mAudioDevice) {
|
||||
rv = mAudioDevice->Allocate(GetInvariant(mConstraints.mAudio), mPrefs);
|
||||
rv = mAudioDevice->Allocate(GetInvariant(mConstraints.mAudio),
|
||||
mPrefs, mOrigin);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Failed to allocate audiosource %d",rv));
|
||||
Fail(NS_LITERAL_STRING("SourceUnavailableError"),
|
||||
@ -1212,7 +1215,8 @@ public:
|
||||
}
|
||||
}
|
||||
if (mVideoDevice) {
|
||||
rv = mVideoDevice->Allocate(GetInvariant(mConstraints.mVideo), mPrefs);
|
||||
rv = mVideoDevice->Allocate(GetInvariant(mConstraints.mVideo),
|
||||
mPrefs, mOrigin);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Failed to allocate videosource %d\n",rv));
|
||||
if (mAudioDevice) {
|
||||
|
@ -94,7 +94,8 @@ public:
|
||||
NS_IMETHOD GetType(nsAString& aType);
|
||||
Source* GetSource();
|
||||
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs);
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsACString& aOrigin);
|
||||
nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs);
|
||||
};
|
||||
@ -108,7 +109,8 @@ public:
|
||||
NS_IMETHOD GetType(nsAString& aType);
|
||||
Source* GetSource();
|
||||
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs);
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsACString& aOrigin);
|
||||
nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs);
|
||||
};
|
||||
|
@ -351,13 +351,15 @@ int
|
||||
CamerasChild::AllocateCaptureDevice(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int unique_idUTF8Length,
|
||||
int& capture_id)
|
||||
int& capture_id,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
nsCString unique_id(unique_idUTF8);
|
||||
nsCString origin(aOrigin);
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
media::NewRunnableFrom([this, aCapEngine, unique_id]() -> nsresult {
|
||||
if (this->SendAllocateCaptureDevice(aCapEngine, unique_id)) {
|
||||
media::NewRunnableFrom([this, aCapEngine, unique_id, origin]() -> nsresult {
|
||||
if (this->SendAllocateCaptureDevice(aCapEngine, unique_id, origin)) {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -181,7 +181,8 @@ public:
|
||||
int AllocateCaptureDevice(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int unique_idUTF8Length,
|
||||
int& capture_id);
|
||||
int& capture_id,
|
||||
const nsACString& aOrigin);
|
||||
int GetCaptureCapability(CaptureEngine aCapEngine,
|
||||
const char* unique_idUTF8,
|
||||
const unsigned int capability_number,
|
||||
|
@ -11,10 +11,14 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
|
||||
@ -641,39 +645,127 @@ CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
||||
return true;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetPrincipalFromOrigin(const nsACString& aOrigin, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
nsAutoCString originNoSuffix;
|
||||
mozilla::PrincipalOriginAttributes attrs;
|
||||
if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mozilla::BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
principal.forget(aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find out whether the given origin has permission to use the
|
||||
// camera. If the permission is not persistent, we'll make it
|
||||
// a one-shot by removing the (session) permission.
|
||||
static bool
|
||||
HasCameraPermission(const nsCString& aOrigin)
|
||||
{
|
||||
// Name used with nsIPermissionManager
|
||||
static const char* cameraPermission = "camera";
|
||||
bool allowed = false;
|
||||
bool permanent = false;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPermissionManager> mgr =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIIOService> ioServ(do_GetIOService());
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = ioServ->NewURI(aOrigin, nullptr, nullptr, getter_AddRefs(uri));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Permanent permissions are only retrievable via principal, not uri
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = GetPrincipalFromOrigin(aOrigin, getter_AddRefs(principal));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
uint32_t video = nsIPermissionManager::UNKNOWN_ACTION;
|
||||
rv = mgr->TestExactPermissionFromPrincipal(principal,
|
||||
cameraPermission,
|
||||
&video);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
allowed = (video == nsIPermissionManager::ALLOW_ACTION);
|
||||
// Was allowed, now see if this is a persistent permission
|
||||
// or a session one.
|
||||
if (allowed) {
|
||||
rv = mgr->TestExactPermanentPermission(principal,
|
||||
cameraPermission,
|
||||
&video);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
permanent = (video == nsIPermissionManager::ALLOW_ACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Session permissions are removed after one use.
|
||||
if (allowed && !permanent) {
|
||||
mgr->RemoveFromPrincipal(principal, cameraPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
||||
const nsCString& unique_id)
|
||||
const nsCString& unique_id,
|
||||
const nsCString& aOrigin)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
||||
LOG(("%s: Verifying permissions for %s", __PRETTY_FUNCTION__, aOrigin.get()));
|
||||
RefPtr<CamerasParent> self(this);
|
||||
RefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, unique_id]() -> nsresult {
|
||||
int numdev = -1;
|
||||
int error = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
|
||||
RefPtr<nsRunnable> mainthread_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, unique_id, aOrigin]() -> nsresult {
|
||||
// Verify whether the claimed origin has received permission
|
||||
// to use the camera, either persistently or this session (one shot).
|
||||
bool allowed = HasCameraPermission(aOrigin);
|
||||
if (!allowed) {
|
||||
// Developer preference for turning off permission check.
|
||||
if (Preferences::GetBool("media.navigator.permission.disabled", false)
|
||||
|| Preferences::GetBool("media.navigator.permission.fake")) {
|
||||
allowed = true;
|
||||
LOG(("No permission but checks are disabled or fake sources active"));
|
||||
} else {
|
||||
LOG(("No camera permission for this origin"));
|
||||
}
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, numdev, error]() -> nsresult {
|
||||
if (self->IsShuttingDown()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (error) {
|
||||
Unused << self->SendReplyFailure();
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
LOG(("Allocated device nr %d", numdev));
|
||||
Unused << self->SendReplyAllocateCaptureDevice(numdev);
|
||||
return NS_OK;
|
||||
}
|
||||
// After retrieving the permission (or not) on the main thread,
|
||||
// bounce to the WebRTC thread to allocate the device (or not),
|
||||
// then bounce back to the IPC thread for the reply to content.
|
||||
RefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, allowed, aCapEngine, unique_id]() -> nsresult {
|
||||
int numdev = -1;
|
||||
int error = -1;
|
||||
if (allowed && self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, numdev, error]() -> nsresult {
|
||||
if (self->IsShuttingDown()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (error) {
|
||||
Unused << self->SendReplyFailure();
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
LOG(("Allocated device nr %d", numdev));
|
||||
Unused << self->SendReplyAllocateCaptureDevice(numdev);
|
||||
return NS_OK;
|
||||
}
|
||||
});
|
||||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
self->DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return NS_OK;
|
||||
});
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
NS_DispatchToMainThread(mainthread_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
static already_AddRefed<CamerasParent> Create();
|
||||
|
||||
// Messages received form the child. These run on the IPC/PBackground thread.
|
||||
virtual bool RecvAllocateCaptureDevice(const int&, const nsCString&) override;
|
||||
virtual bool RecvAllocateCaptureDevice(const int&, const nsCString&, const nsCString&) override;
|
||||
virtual bool RecvReleaseCaptureDevice(const int&, const int &) override;
|
||||
virtual bool RecvNumberOfCaptureDevices(const int&) override;
|
||||
virtual bool RecvNumberOfCapabilities(const int&, const nsCString&) override;
|
||||
|
@ -45,7 +45,7 @@ parent:
|
||||
async GetCaptureCapability(int engine, nsCString unique_idUTF8, int capability_number);
|
||||
async GetCaptureDevice(int engine, int num);
|
||||
|
||||
async AllocateCaptureDevice(int engine, nsCString unique_idUTF8);
|
||||
async AllocateCaptureDevice(int engine, nsCString unique_idUTF8, nsCString origin);
|
||||
async ReleaseCaptureDevice(int engine, int numdev);
|
||||
async StartCapture(int engine, int numdev, CaptureCapability capability);
|
||||
async StopCapture(int engine, int numdev);
|
||||
|
@ -171,7 +171,8 @@ public:
|
||||
/* This call reserves but does not start the device. */
|
||||
virtual nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId) = 0;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) = 0;
|
||||
|
||||
virtual uint32_t GetBestFitnessDistance(
|
||||
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
|
||||
|
@ -87,7 +87,8 @@ MediaEngineDefaultVideoSource::GetBestFitnessDistance(
|
||||
nsresult
|
||||
MediaEngineDefaultVideoSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
if (mState != kReleased) {
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -396,7 +397,8 @@ MediaEngineDefaultAudioSource::GetBestFitnessDistance(
|
||||
nsresult
|
||||
MediaEngineDefaultAudioSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
if (mState != kReleased) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -45,7 +45,8 @@ public:
|
||||
|
||||
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId) override;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override;
|
||||
nsresult Deallocate() override;
|
||||
nsresult Start(SourceMediaStream*, TrackID) override;
|
||||
nsresult Stop(SourceMediaStream*, TrackID) override;
|
||||
@ -114,7 +115,8 @@ public:
|
||||
|
||||
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId) override;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override;
|
||||
nsresult Deallocate() override;
|
||||
nsresult Start(SourceMediaStream*, TrackID) override;
|
||||
nsresult Stop(SourceMediaStream*, TrackID) override;
|
||||
|
@ -100,7 +100,8 @@ MediaEngineRemoteVideoSource::Shutdown()
|
||||
nsresult
|
||||
MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
AssertIsOnOwningThread();
|
||||
@ -120,11 +121,12 @@ MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstr
|
||||
|
||||
if (mozilla::camera::GetChildAndCall(
|
||||
&mozilla::camera::CamerasChild::AllocateCaptureDevice,
|
||||
mCapEngine, GetUUID().get(), kMaxUniqueIdLength, mCaptureIndex)) {
|
||||
mCapEngine, GetUUID().get(), kMaxUniqueIdLength, mCaptureIndex, aOrigin)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mState = kAllocated;
|
||||
LOG(("Video device %d allocated", mCaptureIndex));
|
||||
LOG(("Video device %d allocated for %s", mCaptureIndex,
|
||||
PromiseFlatCString(aOrigin).get()));
|
||||
} else if (MOZ_LOG_TEST(GetMediaManagerLog(), mozilla::LogLevel::Debug)) {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mSources.IsEmpty()) {
|
||||
|
@ -73,7 +73,8 @@ public:
|
||||
|
||||
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId) override;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override;
|
||||
nsresult Deallocate() override;;
|
||||
nsresult Start(SourceMediaStream*, TrackID) override;
|
||||
nsresult Stop(SourceMediaStream*, TrackID) override;
|
||||
|
@ -128,7 +128,8 @@ MediaEngineTabVideoSource::GetUUID(nsACString_internal& aUuid)
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
// windowId is not a proper constraint, so just read it.
|
||||
// It has no well-defined behavior in advanced, so ignore it there.
|
||||
|
@ -23,7 +23,8 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList
|
||||
void GetUUID(nsACString_internal&) override;
|
||||
nsresult Allocate(const dom::MediaTrackConstraints &,
|
||||
const mozilla::MediaEnginePrefs&,
|
||||
const nsString& aDeviceId) override;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override;
|
||||
nsresult Deallocate() override;
|
||||
nsresult Start(mozilla::SourceMediaStream*, mozilla::TrackID) override;
|
||||
void SetDirectListeners(bool aHasDirectListeners) override {};
|
||||
|
@ -72,7 +72,8 @@ public:
|
||||
void GetUUID(nsACString& aUUID) override;
|
||||
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId) override
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override
|
||||
{
|
||||
// Nothing to do here, everything is managed in MediaManager.cpp
|
||||
return NS_OK;
|
||||
@ -435,7 +436,8 @@ public:
|
||||
|
||||
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId) override;
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin) override;
|
||||
nsresult Deallocate() override;
|
||||
nsresult Start(SourceMediaStream* aStream, TrackID aID) override;
|
||||
nsresult Stop(SourceMediaStream* aSource, TrackID aID) override;
|
||||
|
@ -220,7 +220,8 @@ uint32_t MediaEngineWebRTCMicrophoneSource::GetBestFitnessDistance(
|
||||
nsresult
|
||||
MediaEngineWebRTCMicrophoneSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
|
||||
const MediaEnginePrefs &aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
const nsString& aDeviceId,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
if (mState == kReleased) {
|
||||
|
Loading…
Reference in New Issue
Block a user