Remove UserMediaProcessManager processState map
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2019 19:53:42 +0000 (19:53 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2019 19:53:42 +0000 (19:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195056

Reviewed by Eric Carlson.

Before the patch, the WebProcessProxy->ProcessState map was storing the list of manager proxies and process state.
To improve on this model, this patch does the following:
- Move the process state to WebProcessProxy.
- Remove the map and replace it by a set of all manager proxies.

This simplifies the handling.
On WebProcess side, instead of storing the sandbox extensions in each WebPage, we handle them in WebProcess directly.
This mirrors what is being done in UIProcess and reduces the risk of inconsistencies between the two, the risk being that capture would fail.

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::forEach):
(WebKit::UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy):
(WebKit::UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy):
(WebKit::UserMediaPermissionRequestManagerProxy::captureStateChanged):
* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* UIProcess/UserMediaProcessManager.cpp:
(WebKit::UserMediaProcessManager::muteCaptureMediaStreamsExceptIn):
(WebKit::UserMediaProcessManager::willCreateMediaStream):
(WebKit::UserMediaProcessManager::endedCaptureSession):
(WebKit::UserMediaProcessManager::setCaptureEnabled):
(WebKit::UserMediaProcessManager::captureDevicesChanged):
(WebKit::ProcessState::ProcessState): Deleted.
(WebKit::ProcessState::hasVideoExtension const): Deleted.
(WebKit::ProcessState::grantVideoExtension): Deleted.
(WebKit::ProcessState::revokeVideoExtension): Deleted.
(WebKit::ProcessState::hasAudioExtension const): Deleted.
(WebKit::ProcessState::grantAudioExtension): Deleted.
(WebKit::ProcessState::revokeAudioExtension): Deleted.
(WebKit::stateMap): Deleted.
(WebKit::processState): Deleted.
(WebKit::ProcessState::addRequestManager): Deleted.
(WebKit::ProcessState::removeRequestManager): Deleted.
(WebKit::UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy): Deleted.
(WebKit::UserMediaProcessManager::removeUserMediaPermissionRequestManagerProxy): Deleted.
(WebKit::UserMediaProcessManager::startedCaptureSession): Deleted.
* UIProcess/UserMediaProcessManager.h:
* UIProcess/WebProcessProxy.h:
(WebKit::WebProcessProxy::mediaCaptureSandboxExtensions const):
(WebKit::WebProcessProxy::hasVideoCaptureExtension const):
(WebKit::WebProcessProxy::grantVideoCaptureExtension):
(WebKit::WebProcessProxy::revokeVideoCaptureExtension):
(WebKit::WebProcessProxy::hasAudioCaptureExtension const):
(WebKit::WebProcessProxy::grantAudioCaptureExtension):
(WebKit::WebProcessProxy::revokeAudioCaptureExtension):
* WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
(WebKit::UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager): Deleted.
(WebKit::UserMediaPermissionRequestManager::clear): Deleted.
(WebKit::UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions): Deleted.
(WebKit::UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions): Deleted.
* WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::close):
(WebKit::WebPage::grantUserMediaDeviceSandboxExtensions): Deleted.
(WebKit::WebPage::revokeUserMediaDeviceSandboxExtensions): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::grantUserMediaDeviceSandboxExtensions):
(WebKit::WebProcess::revokeUserMediaDeviceSandboxExtensions):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242142 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
Source/WebKit/UIProcess/UserMediaProcessManager.cpp
Source/WebKit/UIProcess/UserMediaProcessManager.h
Source/WebKit/UIProcess/WebProcessProxy.h
Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKit/WebProcess/WebProcess.cpp
Source/WebKit/WebProcess/WebProcess.h
Source/WebKit/WebProcess/WebProcess.messages.in

index ad1cde2..713acd1 100644 (file)
@@ -1,3 +1,72 @@
+2019-02-27  Youenn Fablet  <youenn@apple.com>
+
+        Remove UserMediaProcessManager processState map
+        https://bugs.webkit.org/show_bug.cgi?id=195056
+
+        Reviewed by Eric Carlson.
+
+        Before the patch, the WebProcessProxy->ProcessState map was storing the list of manager proxies and process state.
+        To improve on this model, this patch does the following:
+        - Move the process state to WebProcessProxy.
+        - Remove the map and replace it by a set of all manager proxies.
+
+        This simplifies the handling.
+        On WebProcess side, instead of storing the sandbox extensions in each WebPage, we handle them in WebProcess directly.
+        This mirrors what is being done in UIProcess and reduces the risk of inconsistencies between the two, the risk being that capture would fail.
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::forEach):
+        (WebKit::UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy):
+        (WebKit::UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy):
+        (WebKit::UserMediaPermissionRequestManagerProxy::captureStateChanged):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * UIProcess/UserMediaProcessManager.cpp:
+        (WebKit::UserMediaProcessManager::muteCaptureMediaStreamsExceptIn):
+        (WebKit::UserMediaProcessManager::willCreateMediaStream):
+        (WebKit::UserMediaProcessManager::endedCaptureSession):
+        (WebKit::UserMediaProcessManager::setCaptureEnabled):
+        (WebKit::UserMediaProcessManager::captureDevicesChanged):
+        (WebKit::ProcessState::ProcessState): Deleted.
+        (WebKit::ProcessState::hasVideoExtension const): Deleted.
+        (WebKit::ProcessState::grantVideoExtension): Deleted.
+        (WebKit::ProcessState::revokeVideoExtension): Deleted.
+        (WebKit::ProcessState::hasAudioExtension const): Deleted.
+        (WebKit::ProcessState::grantAudioExtension): Deleted.
+        (WebKit::ProcessState::revokeAudioExtension): Deleted.
+        (WebKit::stateMap): Deleted.
+        (WebKit::processState): Deleted.
+        (WebKit::ProcessState::addRequestManager): Deleted.
+        (WebKit::ProcessState::removeRequestManager): Deleted.
+        (WebKit::UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy): Deleted.
+        (WebKit::UserMediaProcessManager::removeUserMediaPermissionRequestManagerProxy): Deleted.
+        (WebKit::UserMediaProcessManager::startedCaptureSession): Deleted.
+        * UIProcess/UserMediaProcessManager.h:
+        * UIProcess/WebProcessProxy.h:
+        (WebKit::WebProcessProxy::mediaCaptureSandboxExtensions const):
+        (WebKit::WebProcessProxy::hasVideoCaptureExtension const):
+        (WebKit::WebProcessProxy::grantVideoCaptureExtension):
+        (WebKit::WebProcessProxy::revokeVideoCaptureExtension):
+        (WebKit::WebProcessProxy::hasAudioCaptureExtension const):
+        (WebKit::WebProcessProxy::grantAudioCaptureExtension):
+        (WebKit::WebProcessProxy::revokeAudioCaptureExtension):
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+        (WebKit::UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::clear): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions): Deleted.
+        (WebKit::UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions): Deleted.
+        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::close):
+        (WebKit::WebPage::grantUserMediaDeviceSandboxExtensions): Deleted.
+        (WebKit::WebPage::revokeUserMediaDeviceSandboxExtensions): Deleted.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::grantUserMediaDeviceSandboxExtensions):
+        (WebKit::WebProcess::revokeUserMediaDeviceSandboxExtensions):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2019-02-27  Per Arne Vollan  <pvollan@apple.com>
 
         [macOS] Disable permissive call logging in sandbox
index 31b4671..f40c53f 100644 (file)
@@ -51,20 +51,35 @@ static uint64_t generateRequestID()
 }
 #endif
 
+#if ENABLE(MEDIA_STREAM)
+static HashSet<UserMediaPermissionRequestManagerProxy*>& proxies()
+{
+    static NeverDestroyed<HashSet<UserMediaPermissionRequestManagerProxy*>> set;
+    return set;
+}
+
+void UserMediaPermissionRequestManagerProxy::forEach(const WTF::Function<void(UserMediaPermissionRequestManagerProxy&)>& function)
+{
+    for (auto* proxy : proxies())
+        function(*proxy);
+}
+#endif
+
 UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy(WebPageProxy& page)
     : m_page(page)
     , m_rejectionTimer(RunLoop::main(), this, &UserMediaPermissionRequestManagerProxy::rejectionTimerFired)
     , m_watchdogTimer(RunLoop::main(), this, &UserMediaPermissionRequestManagerProxy::watchdogTimerFired)
 {
 #if ENABLE(MEDIA_STREAM)
-    UserMediaProcessManager::singleton().addUserMediaPermissionRequestManagerProxy(*this);
+    proxies().add(this);
 #endif
 }
 
 UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy()
 {
 #if ENABLE(MEDIA_STREAM)
-    UserMediaProcessManager::singleton().removeUserMediaPermissionRequestManagerProxy(*this);
+    UserMediaProcessManager::singleton().endedCaptureSession(*this);
+    proxies().remove(this);
 #endif
     invalidatePendingRequests();
 }
@@ -592,8 +607,6 @@ void UserMediaPermissionRequestManagerProxy::captureStateChanged(MediaProducer::
 
     if ((wasCapturingAudio && !isCapturingAudio) || (wasCapturingVideo && !isCapturingVideo))
         UserMediaProcessManager::singleton().endedCaptureSession(*this);
-    if ((!wasCapturingAudio && isCapturingAudio) || (!wasCapturingVideo && isCapturingVideo))
-        UserMediaProcessManager::singleton().startedCaptureSession(*this);
 
     if (m_captureState == (newState & activeCaptureMask))
         return;
index a115c43..88bf498 100644 (file)
@@ -47,6 +47,10 @@ public:
 
     WebPageProxy& page() const { return m_page; }
 
+#if ENABLE(MEDIA_STREAM)
+    static void forEach(const WTF::Function<void(UserMediaPermissionRequestManagerProxy&)>&);
+#endif
+
     void invalidatePendingRequests();
 
     void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&&  userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, WebCore::MediaStreamRequest&&);
index addb035..9f83de8 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "Logging.h"
 #include "MediaDeviceSandboxExtensions.h"
-#include "WebPageMessages.h"
 #include "WebPageProxy.h"
+#include "WebProcessMessages.h"
 #include "WebProcessProxy.h"
 #include <WebCore/RealtimeMediaSourceCenter.h>
 #include <wtf/HashMap.h>
@@ -39,66 +39,6 @@ static const ASCIILiteral videoExtensionPath { "com.apple.webkit.camera"_s };
 
 static const Seconds deviceChangeDebounceTimerInterval { 200_ms };
 
-class ProcessState {
-public:
-    ProcessState() { }
-    ProcessState(const ProcessState&) = delete;
-
-    void addRequestManager(UserMediaPermissionRequestManagerProxy&);
-    void removeRequestManager(UserMediaPermissionRequestManagerProxy&);
-    Vector<UserMediaPermissionRequestManagerProxy*>& managers() { return m_managers; }
-
-    enum SandboxExtensionType : uint32_t {
-        None = 0,
-        Video = 1 << 0,
-        Audio = 1 << 1
-    };
-    typedef uint32_t SandboxExtensionsGranted;
-
-    bool hasVideoExtension() const { return m_pageSandboxExtensionsGranted & Video; }
-    void grantVideoExtension()  { m_pageSandboxExtensionsGranted |= Video; }
-    void revokeVideoExtension()  { m_pageSandboxExtensionsGranted &= ~Video; }
-
-    bool hasAudioExtension() const { return m_pageSandboxExtensionsGranted & Audio; }
-    void grantAudioExtension()  { m_pageSandboxExtensionsGranted |= Audio; }
-    void revokeAudioExtension()  { m_pageSandboxExtensionsGranted &= ~Audio; }
-
-private:
-
-    Vector<UserMediaPermissionRequestManagerProxy*> m_managers;
-    SandboxExtensionsGranted m_pageSandboxExtensionsGranted { SandboxExtensionType::None };
-};
-
-static HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>& stateMap()
-{
-    static NeverDestroyed<HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>> map;
-    return map;
-}
-
-static ProcessState& processState(WebProcessProxy& process)
-{
-    auto& state = stateMap().add(&process, nullptr).iterator->value;
-    if (state)
-        return *state;
-
-    state = std::make_unique<ProcessState>();
-    return *state;
-}
-
-void ProcessState::addRequestManager(UserMediaPermissionRequestManagerProxy& proxy)
-{
-    ASSERT(!m_managers.contains(&proxy));
-    m_managers.append(&proxy);
-}
-
-void ProcessState::removeRequestManager(UserMediaPermissionRequestManagerProxy& proxy)
-{
-    ASSERT(m_managers.contains(&proxy));
-    m_managers.removeFirstMatching([&proxy](auto other) {
-        return other == &proxy;
-    });
-}
-
 UserMediaProcessManager& UserMediaProcessManager::singleton()
 {
     static NeverDestroyed<UserMediaProcessManager> manager;
@@ -110,33 +50,13 @@ UserMediaProcessManager::UserMediaProcessManager()
 {
 }
 
-void UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy)
-{
-    processState(proxy.page().process()).addRequestManager(proxy);
-}
-
-void UserMediaProcessManager::removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy)
-{
-    endedCaptureSession(proxy);
-
-    auto& state = processState(proxy.page().process());
-    state.removeRequestManager(proxy);
-    if (state.managers().isEmpty()) {
-        auto it = stateMap().find(&proxy.page().process());
-        stateMap().remove(it);
-    }
-}
-
 void UserMediaProcessManager::muteCaptureMediaStreamsExceptIn(WebPageProxy& pageStartingCapture)
 {
 #if PLATFORM(COCOA)
-    for (auto& state : stateMap()) {
-        for (auto& manager : state.value->managers()) {
-            if (&manager->page() == &pageStartingCapture)
-                continue;
-            manager->page().setMediaStreamCaptureMuted(true);
-        }
-    }
+    UserMediaPermissionRequestManagerProxy::forEach([&pageStartingCapture](auto& proxy) {
+        if (&proxy.page() != &pageStartingCapture)
+            proxy.page().setMediaStreamCaptureMuted(true);
+    });
 #else
     UNUSED_PARAM(pageStartingCapture);
 #endif
@@ -151,53 +71,48 @@ bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa
         return false;
     }
     
-    if (proxy.page().preferences().mockCaptureDevicesEnabled())
-        return true;
-    
 #if ENABLE(SANDBOX_EXTENSIONS) && USE(APPLE_INTERNAL_SDK)
-    auto& processStartingCapture = proxy.page().process();
+    if (!proxy.page().preferences().mockCaptureDevicesEnabled()) {
+        auto& process = proxy.page().process();
+        size_t extensionCount = 0;
 
-    ASSERT(stateMap().contains(&processStartingCapture));
+        if (withAudio && !process.hasAudioCaptureExtension())
+            extensionCount++;
+        else
+            withAudio = false;
 
-    auto& state = processState(processStartingCapture);
-    size_t extensionCount = 0;
+        if (withVideo && !process.hasVideoCaptureExtension())
+            extensionCount++;
+        else
+            withVideo = false;
 
-    if (withAudio && !state.hasAudioExtension())
-        extensionCount++;
-    else
-        withAudio = false;
+        if (extensionCount) {
+            SandboxExtension::HandleArray handles;
+            handles.allocate(extensionCount);
 
-    if (withVideo && !state.hasVideoExtension())
-        extensionCount++;
-    else
-        withVideo = false;
+            Vector<String> ids;
+            ids.reserveCapacity(extensionCount);
 
-    if (extensionCount) {
-        SandboxExtension::HandleArray handles;
-        handles.allocate(extensionCount);
+            if (withAudio && SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount]))
+                ids.append(audioExtensionPath);
 
-        Vector<String> ids;
-        ids.reserveCapacity(extensionCount);
+            if (withVideo && SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount]))
+                ids.append(videoExtensionPath);
 
-        if (withAudio && SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount]))
-            ids.append(audioExtensionPath);
+            if (ids.size() != handles.size()) {
+                WTFLogAlways("Could not create a required sandbox extension, capture will fail!");
+                return false;
+            }
 
-        if (withVideo && SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount]))
-            ids.append(videoExtensionPath);
+            for (const auto& id : ids)
+                RELEASE_LOG(WebRTC, "UserMediaProcessManager::willCreateMediaStream - granting extension %s", id.utf8().data());
 
-        if (ids.size() != handles.size()) {
-            WTFLogAlways("Could not create a required sandbox extension, capture will fail!");
-            return false;
+            if (withAudio)
+                process.grantAudioCaptureExtension();
+            if (withVideo)
+                process.grantVideoCaptureExtension();
+            process.send(Messages::WebProcess::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), proxy.page().pageID());
         }
-
-        for (const auto& id : ids)
-            RELEASE_LOG(WebRTC, "UserMediaProcessManager::willCreateMediaStream - granting extension %s", id.utf8().data());
-
-        if (withAudio)
-            state.grantAudioExtension();
-        if (withVideo)
-            state.grantVideoExtension();
-        processStartingCapture.send(Messages::WebPage::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), proxy.page().pageID());
     }
 #else
     UNUSED_PARAM(proxy);
@@ -210,39 +125,33 @@ bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa
     return true;
 }
 
-void UserMediaProcessManager::startedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy)
-{
-    ASSERT(stateMap().contains(&proxy.page().process()));
-}
-
 void UserMediaProcessManager::endedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy)
 {
 #if ENABLE(SANDBOX_EXTENSIONS)
-    ASSERT(stateMap().contains(&proxy.page().process()));
-
-    auto& state = processState(proxy.page().process());
     bool hasAudioCapture = false;
     bool hasVideoCapture = false;
-    for (auto& manager : state.managers()) {
-        if (manager == &proxy)
-            continue;
-        if (manager->page().hasActiveAudioStream())
+
+    auto& process = proxy.page().process();
+    UserMediaPermissionRequestManagerProxy::forEach([&hasAudioCapture, &hasVideoCapture, &proxy, &process](auto& managerProxy) {
+        if (&proxy == &managerProxy || &process != &managerProxy.page().process())
+            return;
+        if (managerProxy.page().hasActiveAudioStream())
             hasAudioCapture = true;
-        if (manager->page().hasActiveVideoStream())
+        if (managerProxy.page().hasActiveVideoStream())
             hasVideoCapture = true;
-    }
+    });
 
     if (hasAudioCapture && hasVideoCapture)
         return;
 
     Vector<String> params;
-    if (!hasAudioCapture && state.hasAudioExtension()) {
+    if (!hasAudioCapture && process.hasAudioCaptureExtension()) {
         params.append(audioExtensionPath);
-        state.revokeAudioExtension();
+        process.revokeAudioCaptureExtension();
     }
-    if (!hasVideoCapture && state.hasVideoExtension()) {
+    if (!hasVideoCapture && process.hasVideoCaptureExtension()) {
         params.append(videoExtensionPath);
-        state.revokeVideoExtension();
+        process.revokeVideoCaptureExtension();
     }
 
     if (params.isEmpty())
@@ -251,7 +160,7 @@ void UserMediaProcessManager::endedCaptureSession(UserMediaPermissionRequestMana
     for (const auto& id : params)
         RELEASE_LOG(WebRTC, "UserMediaProcessManager::endedCaptureSession - revoking extension %s", id.utf8().data());
 
-    proxy.page().process().send(Messages::WebPage::RevokeUserMediaDeviceSandboxExtensions(params), proxy.page().pageID());
+    process.send(Messages::WebProcess::RevokeUserMediaDeviceSandboxExtensions(params), proxy.page().pageID());
 #endif
 }
 
@@ -265,23 +174,16 @@ void UserMediaProcessManager::setCaptureEnabled(bool enabled)
     if (enabled)
         return;
 
-    for (auto& state : stateMap()) {
-        for (auto& manager : state.value->managers())
-            manager->stopCapture();
-    }
+    UserMediaPermissionRequestManagerProxy::forEach([](auto& proxy) {
+        proxy.stopCapture();
+    });
 }
 
 void UserMediaProcessManager::captureDevicesChanged()
 {
-    auto& map = stateMap();
-    for (auto& state : map) {
-        auto* process = state.key;
-        for (auto& manager : state.value->managers()) {
-            if (map.find(process) == map.end())
-                break;
-            manager->captureDevicesChanged();
-        }
-    }
+    UserMediaPermissionRequestManagerProxy::forEach([](auto& proxy) {
+        proxy.captureDevicesChanged();
+    });
 }
 
 void UserMediaProcessManager::beginMonitoringCaptureDevices()
index ae16ebe..fe87eaa 100644 (file)
@@ -35,13 +35,9 @@ public:
 
     UserMediaProcessManager();
 
-    void addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&);
-    void removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&);
-
     bool willCreateMediaStream(UserMediaPermissionRequestManagerProxy&, bool withAudio, bool withVideo);
     void muteCaptureMediaStreamsExceptIn(WebPageProxy&);
 
-    void startedCaptureSession(UserMediaPermissionRequestManagerProxy&);
     void endedCaptureSession(UserMediaPermissionRequestManagerProxy&);
 
     void setCaptureEnabled(bool);
index ef1de76..91ad456 100644 (file)
@@ -269,6 +269,24 @@ public:
     void sendProcessDidResume() override;
     void didSetAssertionState(AssertionState) override;
 
+#if PLATFORM(COCOA)
+    enum SandboxExtensionType : uint32_t {
+        None = 0,
+        Video = 1 << 0,
+        Audio = 1 << 1
+    };
+
+    typedef uint32_t MediaCaptureSandboxExtensions;
+
+    bool hasVideoCaptureExtension() const { return m_mediaCaptureSandboxExtensions & Video; }
+    void grantVideoCaptureExtension() { m_mediaCaptureSandboxExtensions |= Video; }
+    void revokeVideoCaptureExtension() { m_mediaCaptureSandboxExtensions &= ~Video; }
+
+    bool hasAudioCaptureExtension() const { return m_mediaCaptureSandboxExtensions & Audio; }
+    void grantAudioCaptureExtension() { m_mediaCaptureSandboxExtensions |= Audio; }
+    void revokeAudioCaptureExtension() { m_mediaCaptureSandboxExtensions &= ~Audio; }
+#endif
+
 protected:
     static uint64_t generatePageID();
     WebProcessProxy(WebProcessPool&, WebsiteDataStore&, IsPrewarmed);
@@ -439,6 +457,10 @@ private:
 #if PLATFORM(WATCHOS)
     ProcessThrottler::BackgroundActivityToken m_backgroundActivityTokenForFullscreenFormControls;
 #endif
+
+#if PLATFORM(COCOA)
+    MediaCaptureSandboxExtensions m_mediaCaptureSandboxExtensions { SandboxExtensionType::None };
+#endif
 };
 
 } // namespace WebKit
index c179e8d..6c4db3b 100644 (file)
@@ -51,17 +51,6 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa
 {
 }
 
-UserMediaPermissionRequestManager::~UserMediaPermissionRequestManager()
-{
-    clear();
-}
-
-void UserMediaPermissionRequestManager::clear()
-{
-    for (auto& sandboxExtension : m_userMediaDeviceSandboxExtensions)
-        sandboxExtension.value->revoke();
-}
-
 void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest& request)
 {
     Document* document = request.document();
@@ -209,27 +198,6 @@ void UserMediaPermissionRequestManager::didCompleteMediaDeviceEnumeration(uint64
     request->setDeviceInfo(deviceList, WTFMove(mediaDeviceIdentifierHashSalt), hasPersistentAccess);
 }
 
-void UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&& extensions)
-{
-    for (size_t i = 0; i < extensions.size(); i++) {
-        const auto& extension = extensions[i];
-        extension.second->consume();
-        RELEASE_LOG(WebRTC, "UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions - granted extension %s", extension.first.utf8().data());
-        m_userMediaDeviceSandboxExtensions.add(extension.first, extension.second.copyRef());
-    }
-}
-
-void UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
-{
-    for (const auto& extensionID : extensionIDs) {
-        auto extension = m_userMediaDeviceSandboxExtensions.take(extensionID);
-        if (extension) {
-            extension->revoke();
-            RELEASE_LOG(WebRTC, "UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions - revoked extension %s", extensionID.utf8().data());
-        }
-    }
-}
-
 UserMediaClient::DeviceChangeObserverToken UserMediaPermissionRequestManager::addDeviceChangeObserver(WTF::Function<void()>&& observer)
 {
     auto identifier = WebCore::UserMediaClient::DeviceChangeObserverToken::generate();
index 851b7ee..b0c2c35 100644 (file)
@@ -21,7 +21,6 @@
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "MediaDeviceSandboxExtensions.h"
 #include "SandboxExtension.h"
 #include <WebCore/MediaCanStartListener.h>
 #include <WebCore/MediaConstraints.h>
@@ -39,7 +38,7 @@ class WebPage;
 class UserMediaPermissionRequestManager : public CanMakeWeakPtr<UserMediaPermissionRequestManager>, private WebCore::MediaCanStartListener {
 public:
     explicit UserMediaPermissionRequestManager(WebPage&);
-    ~UserMediaPermissionRequestManager();
+    ~UserMediaPermissionRequestManager() = default;
 
     void startUserMediaRequest(WebCore::UserMediaRequest&);
     void cancelUserMediaRequest(WebCore::UserMediaRequest&);
@@ -50,14 +49,10 @@ public:
     void cancelMediaDevicesEnumeration(WebCore::MediaDevicesEnumerationRequest&);
     void didCompleteMediaDeviceEnumeration(uint64_t, const Vector<WebCore::CaptureDevice>& deviceList, String&& deviceIdentifierHashSalt, bool originHasPersistentAccess);
 
-    void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&);
-    void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
-
     WebCore::UserMediaClient::DeviceChangeObserverToken addDeviceChangeObserver(WTF::Function<void()>&&);
     void removeDeviceChangeObserver(WebCore::UserMediaClient::DeviceChangeObserverToken);
 
     void captureDevicesChanged();
-    void clear();
 
 private:
     void sendUserMediaRequest(WebCore::UserMediaRequest&);
@@ -76,8 +71,6 @@ private:
     HashMap<uint64_t, RefPtr<WebCore::MediaDevicesEnumerationRequest>> m_idToMediaDevicesEnumerationRequestMap;
     HashMap<RefPtr<WebCore::MediaDevicesEnumerationRequest>, uint64_t> m_mediaDevicesEnumerationRequestToIDMap;
 
-    HashMap<String, RefPtr<SandboxExtension>> m_userMediaDeviceSandboxExtensions;
-
     HashMap<WebCore::UserMediaClient::DeviceChangeObserverToken, WTF::Function<void()>> m_deviceChangeObserverMap;
     bool m_monitoringDeviceChange { false };
 };
index 8b0fe2c..d5d766b 100644 (file)
@@ -1255,10 +1255,6 @@ void WebPage::close()
 
     m_page->inspectorController().disconnectAllFrontends();
 
-#if ENABLE(MEDIA_STREAM)
-    m_userMediaPermissionRequestManager->clear();
-#endif
-
 #if ENABLE(FULLSCREEN_API)
     m_fullScreenManager = nullptr;
 #endif
@@ -4082,17 +4078,6 @@ void WebPage::captureDevicesChanged()
     m_userMediaPermissionRequestManager->captureDevicesChanged();
 }
 
-#if ENABLE(SANDBOX_EXTENSIONS)
-void WebPage::grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&& extensions)
-{
-    m_userMediaPermissionRequestManager->grantUserMediaDeviceSandboxExtensions(WTFMove(extensions));
-}
-
-void WebPage::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
-{
-    m_userMediaPermissionRequestManager->revokeUserMediaDeviceSandboxExtensions(extensionIDs);
-}
-#endif
 #endif
 
 #if !PLATFORM(IOS_FAMILY)
index 0c04b2e..2f6d79d 100644 (file)
@@ -1396,11 +1396,6 @@ private:
     void didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<WebCore::CaptureDevice>& devices, String&& deviceIdentifierHashSalt, bool originHasPersistentAccess);
 #endif
 
-#if ENABLE(MEDIA_STREAM) && ENABLE(SANDBOX_EXTENSIONS)
-    void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&);
-    void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
-#endif
-
 #if ENABLE(WEB_RTC)
     void disableICECandidateFiltering();
     void enableICECandidateFiltering();
index 019f6b0..64950a9 100644 (file)
@@ -346,10 +346,6 @@ messages -> WebPage LegacyReceiver {
     UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
     DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector<WebCore::CaptureDevice> devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
     CaptureDevicesChanged()
-#if ENABLE(SANDBOX_EXTENSIONS)
-    GrantUserMediaDeviceSandboxExtensions(WebKit::MediaDeviceSandboxExtensions sandboxExtensions)
-    RevokeUserMediaDeviceSandboxExtensions(Vector<String> sandboxExtensionIDs)
-#endif
 #endif
 
 #if ENABLE(WEB_RTC)
index aaf6bf2..133fb48 100644 (file)
@@ -1812,6 +1812,30 @@ void WebProcess::resetMockMediaDevices()
 {
     MockRealtimeMediaSourceCenter::resetDevices();
 }
+
+#if ENABLE(SANDBOX_EXTENSIONS)
+void WebProcess::grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&& extensions)
+{
+    for (size_t i = 0; i < extensions.size(); i++) {
+        const auto& extension = extensions[i];
+        extension.second->consume();
+        RELEASE_LOG(WebRTC, "UserMediaPermissionRequestManager::grantUserMediaDeviceSandboxExtensions - granted extension %s", extension.first.utf8().data());
+        m_mediaCaptureSandboxExtensions.add(extension.first, extension.second.copyRef());
+    }
+}
+
+void WebProcess::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
+{
+    for (const auto& extensionID : extensionIDs) {
+        auto extension = m_mediaCaptureSandboxExtensions.take(extensionID);
+        ASSERT(extension);
+        if (extension) {
+            extension->revoke();
+            RELEASE_LOG(WebRTC, "UserMediaPermissionRequestManager::revokeUserMediaDeviceSandboxExtensions - revoked extension %s", extensionID.utf8().data());
+        }
+    }
+}
+#endif
 #endif
 
 #if ENABLE(VIDEO)
index 04d3672..1cd96da 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "AuxiliaryProcess.h"
 #include "CacheModel.h"
+#if ENABLE(MEDIA_STREAM)
+#include "MediaDeviceSandboxExtensions.h"
+#endif
 #include "PluginProcessConnectionManager.h"
 #include "ResourceCachesToClear.h"
 #include "SandboxExtension.h"
@@ -374,6 +377,11 @@ private:
     void clearMockMediaDevices();
     void removeMockMediaDevice(const String& persistentId);
     void resetMockMediaDevices();
+#if ENABLE(SANDBOX_EXTENSIONS)
+    void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&);
+    void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
+#endif
+
 #endif
 
     void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
@@ -486,6 +494,10 @@ private:
 #endif
     bool m_hasSuspendedPageProxy { false };
     bool m_isSuspending { false };
+
+#if ENABLE(MEDIA_STREAM) && ENABLE(SANDBOX_EXTENSIONS)
+    HashMap<String, RefPtr<SandboxExtension>> m_mediaCaptureSandboxExtensions;
+#endif
 };
 
 } // namespace WebKit
index 518e4fb..44fdb9d 100644 (file)
@@ -145,6 +145,11 @@ messages -> WebProcess LegacyReceiver {
     ClearMockMediaDevices();
     RemoveMockMediaDevice(String persistentId);
     ResetMockMediaDevices();
+
+#if ENABLE(SANDBOX_EXTENSIONS)
+    GrantUserMediaDeviceSandboxExtensions(WebKit::MediaDeviceSandboxExtensions sandboxExtensions)
+    RevokeUserMediaDeviceSandboxExtensions(Vector<String> sandboxExtensionIDs)
+#endif
 #endif
 
     ClearCurrentModifierStateForTesting()