Make to clear sources from UserMediaCaptureManagerProxy and UserMediaCaptureManager...
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Feb 2019 19:20:15 +0000 (19:20 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Feb 2019 19:20:15 +0000 (19:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194312

Reviewed by Eric Carlson.

Source/WebCore:

Add a way for sources to know when they are ended, i.e. that they will never be started again.
No observable change of behavior.

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::requestStop):
* platform/mediastream/RealtimeMediaSource.h:

Source/WebKit:

Sources in UserMediaCaptureManager and Proxy are never removed once added to their HashMap.
Use the 'ended' mechanism to do the clean-up on WebProcess side.
As part of this clean-up, send IPC to UIProcess to do clean-up on proxy side.
On WebProcess crash case, clean-up the proxy as well.

* UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp:
(WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints):
(WebKit::UserMediaCaptureManagerProxy::end):
(WebKit::UserMediaCaptureManagerProxy::clear):
* UIProcess/Cocoa/UserMediaCaptureManagerProxy.h:
* UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch):
* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::sourceEnded):
* WebProcess/cocoa/UserMediaCaptureManager.h:

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

Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSource.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp
Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h
Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp
Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h

index 59506e9..6922c00 100644 (file)
@@ -1,3 +1,17 @@
+2019-02-07  Youenn Fablet  <youenn@apple.com>
+
+        Make to clear sources from UserMediaCaptureManagerProxy and UserMediaCaptureManager when no longer needed
+        https://bugs.webkit.org/show_bug.cgi?id=194312
+
+        Reviewed by Eric Carlson.
+
+        Add a way for sources to know when they are ended, i.e. that they will never be started again.
+        No observable change of behavior.
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::requestStop):
+        * platform/mediastream/RealtimeMediaSource.h:
+
 2019-02-07  Jer Noble  <jer.noble@apple.com>
 
         HTMLMediaElement registers wrong ScriptExecutionContext with its ActiveDOMObject parent class
index 95fa95e..09d0db9 100644 (file)
@@ -137,7 +137,7 @@ void MediaStreamTrackPrivate::endTrack()
     m_isEnded = true;
     updateReadyState();
 
-    m_source->requestStop(this);
+    m_source->requestToEnd(*this);
 
     forEachObserver([this](auto& observer) {
         observer.trackEnded(*this);
index 96cf5d9..7f39db2 100644 (file)
@@ -172,7 +172,7 @@ void RealtimeMediaSource::audioSamplesAvailable(const MediaTime& time, const Pla
 
 void RealtimeMediaSource::start()
 {
-    if (m_isProducingData)
+    if (m_isProducingData || m_isEnded)
         return;
 
     m_isProducingData = true;
@@ -195,7 +195,7 @@ void RealtimeMediaSource::stop()
     stopProducingData();
 }
 
-void RealtimeMediaSource::requestStop(Observer* callingObserver)
+void RealtimeMediaSource::requestToEnd(Observer& callingObserver)
 {
     if (!m_isProducingData)
         return;
@@ -208,10 +208,14 @@ void RealtimeMediaSource::requestStop(Observer* callingObserver)
     if (hasObserverPreventingStopping)
         return;
 
+    auto protectedThis = makeRef(*this);
+
     stop();
+    m_isEnded = true;
+    hasEnded();
 
     forEachObserver([callingObserver](auto& observer) {
-        if (&observer != callingObserver)
+        if (&observer != &callingObserver)
             observer.sourceStopped();
     });
 }
index 8e462c7..79a79e1 100644 (file)
@@ -100,7 +100,7 @@ public:
     bool isProducingData() const { return m_isProducingData; }
     void start();
     void stop();
-    void requestStop(Observer* callingObserver = nullptr);
+    void requestToEnd(Observer& callingObserver);
 
     bool muted() const { return m_muted; }
     void setMuted(bool);
@@ -211,6 +211,8 @@ private:
     virtual void stopProducingData() { }
     virtual void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) { }
 
+    virtual void hasEnded() { }
+
     void forEachObserver(const WTF::Function<void(Observer&)>&) const;
 
     bool m_muted { false };
@@ -238,6 +240,7 @@ private:
     bool m_interrupted { false };
     bool m_captureDidFailed { false };
     bool m_isRemote { false };
+    bool m_isEnded { false };
 };
 
 struct CaptureSourceOrError {
index 89af986..d0c8036 100644 (file)
@@ -1,3 +1,27 @@
+2019-02-07  Youenn Fablet  <youenn@apple.com>
+
+        Make to clear sources from UserMediaCaptureManagerProxy and UserMediaCaptureManager when no longer needed
+        https://bugs.webkit.org/show_bug.cgi?id=194312
+
+        Reviewed by Eric Carlson.
+
+        Sources in UserMediaCaptureManager and Proxy are never removed once added to their HashMap.
+        Use the 'ended' mechanism to do the clean-up on WebProcess side.
+        As part of this clean-up, send IPC to UIProcess to do clean-up on proxy side.
+        On WebProcess crash case, clean-up the proxy as well.
+
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp:
+        (WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints):
+        (WebKit::UserMediaCaptureManagerProxy::end):
+        (WebKit::UserMediaCaptureManagerProxy::clear):
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.h:
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch):
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::sourceEnded):
+        * WebProcess/cocoa/UserMediaCaptureManager.h:
+
 2019-02-07  Alex Christensen  <achristensen@webkit.org>
 
         Print backgrounds preference should be honored instead of WKWebViewConfiguration value
index 056d5c3..c4540e7 100644 (file)
@@ -161,7 +161,8 @@ void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstrai
         auto source = sourceOrError.source();
         source->setIsRemote(true);
         settings = source->settings();
-        m_proxies.set(id, std::make_unique<SourceProxy>(id, *this, WTFMove(source)));
+        ASSERT(!m_proxies.contains(id));
+        m_proxies.add(id, std::make_unique<SourceProxy>(id, *this, WTFMove(source)));
     } else
         invalidConstraints = WTFMove(sourceOrError.errorMessage);
 }
@@ -180,6 +181,11 @@ void UserMediaCaptureManagerProxy::stopProducingData(uint64_t id)
         iter->value->source().stop();
 }
 
+void UserMediaCaptureManagerProxy::end(uint64_t id)
+{
+    m_proxies.remove(id);
+}
+
 void UserMediaCaptureManagerProxy::capabilities(uint64_t id, WebCore::RealtimeMediaSourceCapabilities& capabilities)
 {
     auto iter = m_proxies.find(id);
@@ -208,6 +214,11 @@ void UserMediaCaptureManagerProxy::applyConstraints(uint64_t id, const WebCore::
         m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsFailed(id, result.value().first, result.value().second), 0);
 }
 
+void UserMediaCaptureManagerProxy::clear()
+{
+    m_proxies.clear();
+}
+
 }
 
 #endif
index 3bf921f..a52fea2 100644 (file)
@@ -40,10 +40,11 @@ class WebProcessProxy;
 
 class UserMediaCaptureManagerProxy : private IPC::MessageReceiver {
 public:
-    UserMediaCaptureManagerProxy(WebProcessProxy&);
+    explicit UserMediaCaptureManagerProxy(WebProcessProxy&);
     ~UserMediaCaptureManagerProxy();
 
     WebProcessProxy& process() const { return m_process; }
+    void clear();
 
 private:
     // IPC::MessageReceiver
@@ -53,6 +54,7 @@ private:
     void createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const WebCore::CaptureDevice& deviceID, String&&, const WebCore::MediaConstraints&, bool& succeeded, String& invalidConstraints, WebCore::RealtimeMediaSourceSettings&);
     void startProducingData(uint64_t);
     void stopProducingData(uint64_t);
+    void end(uint64_t);
     void capabilities(uint64_t, WebCore::RealtimeMediaSourceCapabilities&);
     void setMuted(uint64_t, bool);
     void applyConstraints(uint64_t, const WebCore::MediaConstraints&);
index 20db176..2a26de7 100644 (file)
@@ -27,6 +27,7 @@ messages -> UserMediaCaptureManagerProxy {
 CreateMediaSourceForCaptureDeviceWithConstraints(uint64_t id, WebCore::CaptureDevice device, String hashSalt, struct WebCore::MediaConstraints constraints) -> (bool success, String invalidConstraints, WebCore::RealtimeMediaSourceSettings settings) LegacySync
     StartProducingData(uint64_t id)
     StopProducingData(uint64_t id)
+    End(uint64_t id)
     Capabilities(uint64_t id) -> (WebCore::RealtimeMediaSourceCapabilities capabilities) LegacySync
     SetMuted(uint64_t id, bool muted)
     ApplyConstraints(uint64_t id, struct WebCore::MediaConstraints constraints)
index b769d53..ace34d5 100644 (file)
@@ -571,6 +571,10 @@ void WebProcessProxy::processDidTerminateOrFailedToLaunch()
     // to be deleted before we can finish our work.
     Ref<WebProcessProxy> protect(*this);
 
+#if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
+    m_userMediaCaptureManagerProxy->clear();
+#endif
+
     if (auto* webConnection = this->webConnection())
         webConnection->didClose();
 
index 45b901e..34bd80d 100644 (file)
@@ -185,6 +185,7 @@ private:
     // RealtimeMediaSource
     void beginConfiguration() final { }
     void commitConfiguration() final { }
+    void hasEnded() final { m_manager.sourceEnded(m_id); }
 
     void applyConstraints(const WebCore::MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) final {
         m_manager.applyConstraints(m_id, constraints);
@@ -345,6 +346,11 @@ void UserMediaCaptureManager::applyConstraints(uint64_t id, const WebCore::Media
     m_process.send(Messages::UserMediaCaptureManagerProxy::ApplyConstraints(id, constraints), 0);
 }
 
+void UserMediaCaptureManager::sourceEnded(uint64_t id)
+{
+    m_process.send(Messages::UserMediaCaptureManagerProxy::End(id), 0);
+}
+
 void UserMediaCaptureManager::applyConstraintsSucceeded(uint64_t id, const WebCore::RealtimeMediaSourceSettings& settings)
 {
     ASSERT(m_sources.contains(id));
index ad1be7c..83404fa 100644 (file)
@@ -85,6 +85,7 @@ private:
     // Messages::UserMediaCaptureManager
     void captureFailed(uint64_t id);
     void sourceStopped(uint64_t id);
+    void sourceEnded(uint64_t id);
     void sourceMutedChanged(uint64_t id, bool muted);
     void sourceSettingsChanged(uint64_t id, const WebCore::RealtimeMediaSourceSettings&);
     void storageChanged(uint64_t id, const SharedMemory::Handle&, const WebCore::CAAudioStreamDescription&, uint64_t numberOfFrames);