--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -274,16 +274,17 @@ function getHost(uri, href) {
}
function prompt(aBrowser, aRequest) {
let {audioDevices: audioDevices, videoDevices: videoDevices,
sharingScreen: sharingScreen, sharingAudio: sharingAudio,
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;
let stringId = "getUserMedia.share" + requestTypes.join("And") + ".message";
let message = stringBundle.getFormattedString(stringId, [host]);
let mainLabel;
if (sharingScreen || sharingAudio) {
@@ -369,17 +370,26 @@ function prompt(aBrowser, aRequest) {
// to avoid granting permissions automatically to background tabs.
if (aRequest.secure) {
let perms = Services.perms;
let micPerm = perms.testExactPermission(uri, "microphone");
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;
// Screen sharing shouldn't follow the camera permissions.
if (videoDevices.length && sharingScreen)
camPerm = perms.UNKNOWN_ACTION;
// We don't check that permissions are set to ALLOW_ACTION in this
@@ -510,21 +520,24 @@ function prompt(aBrowser, aRequest) {
this.mainAction.callback = function(aRemember) {
let allowedDevices = [];
let perms = Services.perms;
if (videoDevices.length) {
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) {
if (!sharingAudio) {
let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
let allowMic = audioDeviceIndex != "-1";
if (allowMic)
allowedDevices.push(audioDeviceIndex);
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -629,23 +629,25 @@ VideoDevice::GetSource()
AudioDevice::Source*
AudioDevice::GetSource()
{
return static_cast<Source*>(&*mSource);
}
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,
const MediaEnginePrefs &aPrefs) {
return GetSource()->Restart(aConstraints, aPrefs, mID);
}
nsresult AudioDevice::Restart(const dom::MediaTrackConstraints &aConstraints,
@@ -1198,26 +1200,28 @@ public:
MOZ_ASSERT(mDeviceChosen);
// Allocate a video or audio device and return a MediaStream via
// a GetUserMediaStreamRunnable.
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"),
NS_LITERAL_STRING("Failed to allocate audiosource"));
return;
}
}
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) {
mAudioDevice->GetSource()->Deallocate();
}
Fail(NS_LITERAL_STRING("SourceUnavailableError"),
NS_LITERAL_STRING("Failed to allocate videosource"));
return;
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -89,31 +89,33 @@ class VideoDevice : public MediaDevice
{
public:
typedef MediaEngineVideoSource Source;
explicit VideoDevice(Source* aSource);
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);
};
class AudioDevice : public MediaDevice
{
public:
typedef MediaEngineAudioSource Source;
explicit AudioDevice(Source* aSource);
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);
};
/**
* This class is an implementation of MediaStreamListener. This is used
* to Start() and Stop() the underlying MediaEngineSource when MediaStreams
* are assigned and deassigned in content.
--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -346,23 +346,25 @@ CamerasChild::RecvReplyGetCaptureDevice(
monitor.Notify();
return true;
}
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;
});
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
LOG(("Capture Device allocated: %d", mReplyInteger));
capture_id = mReplyInteger;
--- a/dom/media/systemservices/CamerasChild.h
+++ b/dom/media/systemservices/CamerasChild.h
@@ -176,17 +176,18 @@ public:
const int capture_id);
int StartCapture(CaptureEngine aCapEngine,
const int capture_id, webrtc::CaptureCapability& capability,
webrtc::ExternalRenderer* func);
int StopCapture(CaptureEngine aCapEngine, const int capture_id);
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,
webrtc::CaptureCapability& capability);
int GetCaptureDevice(CaptureEngine aCapEngine,
unsigned int list_number, char* device_nameUTF8,
const unsigned int device_nameUTF8Length,
char* unique_idUTF8,
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -6,20 +6,24 @@
#include "CamerasParent.h"
#include "CamerasUtils.h"
#include "MediaEngine.h"
#include "MediaUtils.h"
#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"
#undef LOG
#undef LOG_ENABLED
mozilla::LazyLogModule gCamerasParentLog("CamerasParent");
#define LOG(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Debug, args)
#define LOG_ENABLED() MOZ_LOG_TEST(gCamerasParentLog, mozilla::LogLevel::Debug)
@@ -636,49 +640,137 @@ CamerasParent::RecvGetCaptureDevice(cons
});
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
return NS_OK;
});
DispatchToVideoCaptureThread(webrtc_runnable);
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;
}
int
CamerasParent::ReleaseCaptureDevice(const int& aCapEngine,
const int& capnum)
{
int error = -1;
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -81,17 +81,17 @@ class CamerasParent : public PCamerasPa
{
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
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;
virtual bool RecvGetCaptureCapability(const int&, const nsCString&, const int&) override;
virtual bool RecvGetCaptureDevice(const int&, const int&) override;
virtual bool RecvStartCapture(const int&, const int&, const CaptureCapability&) override;
virtual bool RecvStopCapture(const int&, const int&) override;
virtual bool RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
--- a/dom/media/systemservices/PCameras.ipdl
+++ b/dom/media/systemservices/PCameras.ipdl
@@ -40,17 +40,17 @@ child:
parent:
async NumberOfCaptureDevices(int engine);
async NumberOfCapabilities(int engine, nsCString deviceUniqueIdUTF8);
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);
// transfers frame back
async ReleaseFrame(Shmem s);
// Ask parent to delete us
async AllDone();
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -166,17 +166,18 @@ public:
void SetHasFakeTracks(bool aHasFakeTracks) {
mHasFakeTracks = aHasFakeTracks;
}
/* 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,
const nsString& aDeviceId) = 0;
protected:
// Only class' own members can be initialized in constructor initializer list.
explicit MediaEngineSource(MediaEngineState aState)
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -82,17 +82,18 @@ MediaEngineDefaultVideoSource::GetBestFi
}
#endif
return distance;
}
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;
}
mOpts = aPrefs;
mOpts.mWidth = mOpts.mWidth ? mOpts.mWidth : MediaEngine::DEFAULT_43_VIDEO_WIDTH;
mOpts.mHeight = mOpts.mHeight ? mOpts.mHeight : MediaEngine::DEFAULT_43_VIDEO_HEIGHT;
@@ -391,17 +392,18 @@ MediaEngineDefaultAudioSource::GetBestFi
}
#endif
return distance;
}
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;
}
mState = kAllocated;
// generate sine wave (default 1KHz)
mSineGenerator = new SineWaveGenerator(AUDIO_RATE,
--- a/dom/media/webrtc/MediaEngineDefault.h
+++ b/dom/media/webrtc/MediaEngineDefault.h
@@ -40,17 +40,18 @@ public:
void Shutdown() override {};
void GetName(nsAString&) override;
void GetUUID(nsACString&) override;
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;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
void NotifyPull(MediaStreamGraph* aGraph,
@@ -109,17 +110,18 @@ public:
void Shutdown() override {};
void GetName(nsAString&) override;
void GetUUID(nsACString&) override;
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;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
void AppendToSegment(AudioSegment& aSegment, TrackTicks aSamples);
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -95,17 +95,18 @@ MediaEngineRemoteVideoSource::Shutdown()
mState = kReleased;
mInitDone = false;
return;
}
nsresult
MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
- const nsString& aDeviceId)
+ const nsString& aDeviceId,
+ const nsACString& aOrigin)
{
LOG((__PRETTY_FUNCTION__));
AssertIsOnOwningThread();
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
@@ -115,21 +116,22 @@ MediaEngineRemoteVideoSource::Allocate(c
// (This may change depending on spec changes for Constraints/settings)
if (!ChooseCapability(aConstraints, aPrefs, aDeviceId)) {
return NS_ERROR_UNEXPECTED;
}
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()) {
LOG(("Video device %d reallocated", mCaptureIndex));
} else {
LOG(("Video device %d allocated shared", mCaptureIndex));
}
}
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -68,17 +68,18 @@ public:
// MediaEngineCameraVideoSource
MediaEngineRemoteVideoSource(int aIndex, mozilla::camera::CaptureEngine aCapEngine,
dom::MediaSourceEnum aMediaSource,
const char* aMonitorName = "RemoteVideo.Monitor");
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;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream* aSource,
--- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -123,17 +123,18 @@ MediaEngineTabVideoSource::GetUUID(nsACS
#define DEFAULT_TABSHARE_VIDEO_MAX_WIDTH 4096
#define DEFAULT_TABSHARE_VIDEO_MAX_HEIGHT 4096
#define DEFAULT_TABSHARE_VIDEO_FRAMERATE 30
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.
mWindowId = aConstraints.mBrowserWindow.WasPassed() ?
aConstraints.mBrowserWindow.Value() : -1;
return Restart(aConstraints, aPrefs, aDeviceId);
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -18,17 +18,18 @@ class MediaEngineTabVideoSource : public
NS_DECL_NSITIMERCALLBACK
MediaEngineTabVideoSource();
void Shutdown() override {};
void GetName(nsAString_internal&) override;
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 {};
void NotifyPull(mozilla::MediaStreamGraph*, mozilla::SourceMediaStream*, mozilla::TrackID, mozilla::StreamTime) override;
nsresult Stop(mozilla::SourceMediaStream*, mozilla::TrackID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const mozilla::MediaEnginePrefs& aPrefs,
const nsString& aDeviceId) override;
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -67,17 +67,18 @@ public:
explicit MediaEngineWebRTCAudioCaptureSource(const char* aUuid)
: MediaEngineAudioSource(kReleased)
{
}
void GetName(nsAString& aName) override;
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;
}
nsresult Deallocate() override
{
// Nothing to do here, everything is managed in MediaManager.cpp
return NS_OK;
@@ -430,17 +431,18 @@ public:
Init();
}
void GetName(nsAString& aName) override;
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;
nsresult Deallocate() override;
nsresult Start(SourceMediaStream* aStream, TrackID aID) override;
nsresult Stop(SourceMediaStream* aSource, TrackID aID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -215,17 +215,18 @@ uint32_t MediaEngineWebRTCMicrophoneSour
break; // distance is read from first entry only
}
return distance;
}
nsresult
MediaEngineWebRTCMicrophoneSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
- const nsString& aDeviceId)
+ const nsString& aDeviceId,
+ const nsACString& aOrigin)
{
AssertIsOnOwningThread();
if (mState == kReleased) {
if (mInitDone) {
if (mAudioInput->SetRecordingDevice(mCapIndex)) {
return NS_ERROR_FAILURE;
}
mState = kAllocated;