From 9ddd163dc7b4a973b1db1325743f65edfe2e2ac5 Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Tue, 3 Mar 2015 09:51:05 -0500 Subject: [PATCH] Bug 1046245 - enumerateDevices returns label for pages w/active gUM or persistent permissions. r=jesup --- dom/media/MediaDevices.cpp | 53 +++++++++++++++++++++++++++++++++++--- dom/media/MediaManager.cpp | 18 +++++++++++++ dom/media/MediaManager.h | 1 + 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/dom/media/MediaDevices.cpp b/dom/media/MediaDevices.cpp index 5fec9edf5c1..29074dcefda 100644 --- a/dom/media/MediaDevices.cpp +++ b/dom/media/MediaDevices.cpp @@ -9,6 +9,7 @@ #include "mozilla/MediaManager.h" #include "nsIEventTarget.h" #include "nsIScriptGlobalObject.h" +#include "nsIPermissionManager.h" #include "nsPIDOMWindow.h" namespace mozilla { @@ -39,10 +40,43 @@ private: class MediaDevices::EnumDevResolver : public nsIGetUserMediaDevicesSuccessCallback { + static bool HasAPersistentPermission(uint64_t aWindowId) + { + nsPIDOMWindow *window = static_cast + (nsGlobalWindow::GetInnerWindowWithId(aWindowId)); + if (NS_WARN_IF(!window)) { + return false; + } + // Check if this site has persistent permissions. + nsresult rv; + nsCOMPtr mgr = + do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; // no permission manager no permissions! + } + + uint32_t audio = nsIPermissionManager::UNKNOWN_ACTION; + uint32_t video = nsIPermissionManager::UNKNOWN_ACTION; + { + auto* principal = window->GetExtantDoc()->NodePrincipal(); + rv = mgr->TestExactPermissionFromPrincipal(principal, "microphone", &audio); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + rv = mgr->TestExactPermissionFromPrincipal(principal, "camera", &video); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + } + return audio == nsIPermissionManager::ALLOW_ACTION || + video == nsIPermissionManager::ALLOW_ACTION; + } + public: NS_DECL_ISUPPORTS - explicit EnumDevResolver(Promise* aPromise) : mPromise(aPromise) {} + EnumDevResolver(Promise* aPromise, uint64_t aWindowId) + : mPromise(aPromise), mWindowId(aWindowId) {} NS_IMETHOD OnSuccess(nsIVariant* aDevices) override @@ -83,9 +117,19 @@ public: if (isVideo || isAudio) { MediaDeviceKind kind = isVideo ? MediaDeviceKind::Videoinput : MediaDeviceKind::Audioinput; - // TODO: return anonymized id, +label (origins w/gUM permission) (1046245) + nsString id; + nsString name; + device->GetId(id); + // Include name only if page currently has a gUM stream active or + // persistent permissions (audio or video) have been granted + if (MediaManager::Get()->IsWindowActivelyCapturing(mWindowId) || + HasAPersistentPermission(mWindowId) || + Preferences::GetBool("media.navigator.permission.disabled", false)) { + device->GetName(name); + } + // TODO: return anonymized origin-persistent id (1046245) nsRefPtr info = new MediaDeviceInfo(nsString(), kind, - nsString()); + name); infos.AppendElement(info); } } @@ -96,6 +140,7 @@ public: private: virtual ~EnumDevResolver() {} nsRefPtr mPromise; + uint64_t mWindowId; }; class MediaDevices::GumRejecter : public nsIDOMGetUserMediaErrorCallback @@ -150,7 +195,7 @@ MediaDevices::EnumerateDevices(ErrorResult &aRv) nsRefPtr p = Promise::Create(go, aRv); NS_ENSURE_TRUE(!aRv.Failed(), nullptr); - nsRefPtr resolver = new EnumDevResolver(p); + nsRefPtr resolver = new EnumDevResolver(p, window->WindowID()); nsRefPtr rejecter = new GumRejecter(p); aRv = MediaManager::Get()->EnumerateDevices(window, resolver, rejecter); diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index 11577100bd6..2073c999b9a 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -2368,6 +2368,24 @@ MediaManager::StopMediaStreams() } } +bool +MediaManager::IsWindowActivelyCapturing(uint64_t aWindowId) +{ + nsCOMPtr array; + GetActiveMediaCaptureWindows(getter_AddRefs(array)); + uint32_t len; + array->Count(&len); + for (uint32_t i = 0; i < len; i++) { + nsCOMPtr window; + array->GetElementAt(i, getter_AddRefs(window)); + nsCOMPtr win(do_QueryInterface(window)); + if (win && win->WindowID() == aWindowId) { + return true; + } + } + return false; +} + void GetUserMediaCallbackMediaStreamListener::AudioConfig(bool aEchoOn, uint32_t aEcho, diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index c2a89fb1d0c..c0a4cd23c62 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -603,6 +603,7 @@ public: nsresult EnumerateDevices(nsPIDOMWindow* aWindow, dom::Promise& aPromise); void OnNavigation(uint64_t aWindowID); + bool IsWindowActivelyCapturing(uint64_t aWindowId); MediaEnginePrefs mPrefs;