Title: [284275] branches/safari-612-branch
Revision
284275
Author
[email protected]
Date
2021-10-15 15:16:20 -0700 (Fri, 15 Oct 2021)

Log Message

Cherry-pick r283033. rdar://problem/83953190

    [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
    https://bugs.webkit.org/show_bug.cgi?id=230538
    <rdar://problem/83355705>

    Reviewed by Eric Carlson.

    Source/WebCore:

    Add support for interrupting mock cameras.
    Update internals to handle the case of out of main thread videoSampleAvailable calls.

    Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
    This ensures we can restart capture in case a track is muted without the page being muted itself.

    When a source is muted and is in producing data state, it is interrupted.
    When setMuted(false) is called, we need to uninterrupt.
    To do so, we do a stop/start cycle

    Test: fast/mediastream/media-stream-video-track-interrupted.html

    * page/Page.cpp:
    (WebCore::Page::setMuted):
    * platform/mediastream/RealtimeMediaSource.cpp:
    (WebCore::RealtimeMediaSource::setMuted):
    * platform/mock/MockRealtimeMediaSourceCenter.cpp:
    (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
    * platform/mock/MockRealtimeMediaSourceCenter.h:
    * platform/mock/MockRealtimeVideoSource.cpp:
    (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
    (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
    (WebCore::MockRealtimeVideoSource::setIsInterrupted):
    * platform/mock/MockRealtimeVideoSource.h:
    * testing/Internals.cpp:
    (WebCore::Internals::videoSampleAvailable):
    * testing/Internals.h:

    Source/WebKit:

    Add support for mock capture interruption.
    When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
    In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
    It is important to not stop the source so that it can continue receiving interruption notifications.

    * GPUProcess/GPUProcess.cpp:
    (WebKit::GPUProcess::setMockCameraIsInterrupted):
    * GPUProcess/GPUProcess.h:
    * GPUProcess/GPUProcess.messages.in:
    * UIProcess/API/C/WKPage.cpp:
    (WKPageIsMockRealtimeMediaSourceCenterEnabled):
    (WKPageSetMockCameraIsInterrupted):
    * UIProcess/API/C/WKPagePrivate.h:
    * UIProcess/GPU/GPUProcessProxy.cpp:
    (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
    * UIProcess/GPU/GPUProcessProxy.h:
    * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
    * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
    * WebProcess/cocoa/UserMediaCaptureManager.cpp:
    (WebKit::UserMediaCaptureManager::sourceMutedChanged):

    Tools:

    Add mock API to mock camera interruption.

    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
    (WTR::TestRunner::setMockCameraIsInterrupted):
    * WebKitTestRunner/InjectedBundle/TestRunner.h:
    * WebKitTestRunner/TestController.cpp:
    (WTR::TestController::setMockCameraIsInterrupted):
    * WebKitTestRunner/TestController.h:
    * WebKitTestRunner/TestInvocation.cpp:
    (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

    LayoutTests:

    * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
    * fast/mediastream/media-stream-video-track-interrupted.html: Added.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-612-branch/LayoutTests/ChangeLog (284274 => 284275)


--- branches/safari-612-branch/LayoutTests/ChangeLog	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/LayoutTests/ChangeLog	2021-10-15 22:16:20 UTC (rev 284275)
@@ -1,3 +1,99 @@
+2021-10-15  Russell Epstein  <[email protected]>
+
+        Cherry-pick r283033. rdar://problem/83953190
+
+    [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+    https://bugs.webkit.org/show_bug.cgi?id=230538
+    <rdar://problem/83355705>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Add support for interrupting mock cameras.
+    Update internals to handle the case of out of main thread videoSampleAvailable calls.
+    
+    Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
+    This ensures we can restart capture in case a track is muted without the page being muted itself.
+    
+    When a source is muted and is in producing data state, it is interrupted.
+    When setMuted(false) is called, we need to uninterrupt.
+    To do so, we do a stop/start cycle
+    
+    Test: fast/mediastream/media-stream-video-track-interrupted.html
+    
+    * page/Page.cpp:
+    (WebCore::Page::setMuted):
+    * platform/mediastream/RealtimeMediaSource.cpp:
+    (WebCore::RealtimeMediaSource::setMuted):
+    * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+    (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
+    * platform/mock/MockRealtimeMediaSourceCenter.h:
+    * platform/mock/MockRealtimeVideoSource.cpp:
+    (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::setIsInterrupted):
+    * platform/mock/MockRealtimeVideoSource.h:
+    * testing/Internals.cpp:
+    (WebCore::Internals::videoSampleAvailable):
+    * testing/Internals.h:
+    
+    Source/WebKit:
+    
+    Add support for mock capture interruption.
+    When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
+    In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
+    It is important to not stop the source so that it can continue receiving interruption notifications.
+    
+    * GPUProcess/GPUProcess.cpp:
+    (WebKit::GPUProcess::setMockCameraIsInterrupted):
+    * GPUProcess/GPUProcess.h:
+    * GPUProcess/GPUProcess.messages.in:
+    * UIProcess/API/C/WKPage.cpp:
+    (WKPageIsMockRealtimeMediaSourceCenterEnabled):
+    (WKPageSetMockCameraIsInterrupted):
+    * UIProcess/API/C/WKPagePrivate.h:
+    * UIProcess/GPU/GPUProcessProxy.cpp:
+    (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
+    * UIProcess/GPU/GPUProcessProxy.h:
+    * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+    * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+    * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+    (WebKit::UserMediaCaptureManager::sourceMutedChanged):
+    
+    Tools:
+    
+    Add mock API to mock camera interruption.
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::setMockCameraIsInterrupted):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestController.cpp:
+    (WTR::TestController::setMockCameraIsInterrupted):
+    * WebKitTestRunner/TestController.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+    
+    LayoutTests:
+    
+    * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
+    * fast/mediastream/media-stream-video-track-interrupted.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283033 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-24  Youenn Fablet  <[email protected]>
+
+            [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+            https://bugs.webkit.org/show_bug.cgi?id=230538
+            <rdar://problem/83355705>
+
+            Reviewed by Eric Carlson.
+
+            * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
+            * fast/mediastream/media-stream-video-track-interrupted.html: Added.
+
 2021-10-12  Alan Coon  <[email protected]>
 
         Apply patch. rdar://problem/84113071

Added: branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted-expected.txt (0 => 284275)


--- branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted-expected.txt	                        (rev 0)
+++ branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted-expected.txt	2021-10-15 22:16:20 UTC (rev 284275)
@@ -0,0 +1,4 @@
+
+PASS Interrupt/resume video track
+PASS Interrupt video track then uninterrupt it using page unmuting
+

Added: branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted.html (0 => 284275)


--- branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted.html	                        (rev 0)
+++ branches/safari-612-branch/LayoutTests/fast/mediastream/media-stream-video-track-interrupted.html	2021-10-15 22:16:20 UTC (rev 284275)
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Capture source interruption.</title>
+    <script src=""
+    <script src=""
+ </head>
+<body>
+    <script>
+    promise_test(async (test) => {
+        const stream = await navigator.mediaDevices.getUserMedia({video: true});
+        const track = stream.getVideoTracks()[0];
+        if (!window.testRunner)
+            return;
+
+        let promise = new Promise((resolve, reject) => { track._onmute_ = resolve; setTimeout(() => reject("no mute"), 5000) });
+        testRunner.setMockCameraIsInterrupted(true);
+        await promise;
+
+        assert_true(track.muted, "track is muted");
+
+        promise = new Promise((resolve, reject) => { track._onunmute_ = resolve; setTimeout(() => reject("no unmute"), 5000) });
+        testRunner.setMockCameraIsInterrupted(false);
+        await promise;
+
+        assert_false(track.muted, "track is not muted");
+
+        track.stop();
+    }, "Interrupt/resume video track");
+
+    promise_test(async (test) => {
+        const stream = await navigator.mediaDevices.getUserMedia({video: true});
+        const track = stream.getVideoTracks()[0];
+        if (!window.testRunner || !window.internals)
+            return;
+        internals.observeMediaStreamTrack(track);
+
+        // video frames should flow.
+        let current = internals.trackVideoSampleCount;
+        let counter = 0;
+        while (internals.trackVideoSampleCount === current && ++counter < 50)
+            await new Promise(resolve => setTimeout(resolve, 50));
+        assert_less_than(counter, 50, "first live check");
+
+        // getting an interruption, track should be muted.
+        let promise = new Promise((resolve, reject) => { track._onmute_ = resolve; setTimeout(() => reject("no mute"), 5000) });
+        testRunner.setMockCameraIsInterrupted(true);
+        await promise;
+
+        assert_true(track.muted, "track is muted");
+
+        // video frames should not flow.
+        counter = 0;
+        while (internals.trackVideoSampleCount !== current && ++counter < 50) {
+            current = internals.trackVideoSampleCount;
+            await new Promise(resolve => setTimeout(resolve, 200));
+        }
+        assert_less_than(counter, 50, "first muted check");
+
+        // Unmuting page should restart capture.
+        promise = new Promise((resolve, reject) => { track._onunmute_ = resolve; setTimeout(() => reject("no unmute"), 5000) });
+        internals.setPageMuted('');
+        await promise;
+
+        assert_false(track.muted, "track is not muted");
+
+        current = internals.trackVideoSampleCount;
+        counter = 0;
+        while (internals.trackVideoSampleCount === current && ++counter < 50)
+            await new Promise(resolve => setTimeout(resolve, 50));
+        assert_less_than(counter, 50, "second live check");
+
+        track.stop();
+    }, "Interrupt video track then uninterrupt it using page unmuting");
+    </script>
+</body>
+</html>

Modified: branches/safari-612-branch/Source/WebCore/ChangeLog (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/ChangeLog	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/ChangeLog	2021-10-15 22:16:20 UTC (rev 284275)
@@ -1,3 +1,124 @@
+2021-10-15  Russell Epstein  <[email protected]>
+
+        Cherry-pick r283033. rdar://problem/83953190
+
+    [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+    https://bugs.webkit.org/show_bug.cgi?id=230538
+    <rdar://problem/83355705>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Add support for interrupting mock cameras.
+    Update internals to handle the case of out of main thread videoSampleAvailable calls.
+    
+    Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
+    This ensures we can restart capture in case a track is muted without the page being muted itself.
+    
+    When a source is muted and is in producing data state, it is interrupted.
+    When setMuted(false) is called, we need to uninterrupt.
+    To do so, we do a stop/start cycle
+    
+    Test: fast/mediastream/media-stream-video-track-interrupted.html
+    
+    * page/Page.cpp:
+    (WebCore::Page::setMuted):
+    * platform/mediastream/RealtimeMediaSource.cpp:
+    (WebCore::RealtimeMediaSource::setMuted):
+    * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+    (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
+    * platform/mock/MockRealtimeMediaSourceCenter.h:
+    * platform/mock/MockRealtimeVideoSource.cpp:
+    (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::setIsInterrupted):
+    * platform/mock/MockRealtimeVideoSource.h:
+    * testing/Internals.cpp:
+    (WebCore::Internals::videoSampleAvailable):
+    * testing/Internals.h:
+    
+    Source/WebKit:
+    
+    Add support for mock capture interruption.
+    When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
+    In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
+    It is important to not stop the source so that it can continue receiving interruption notifications.
+    
+    * GPUProcess/GPUProcess.cpp:
+    (WebKit::GPUProcess::setMockCameraIsInterrupted):
+    * GPUProcess/GPUProcess.h:
+    * GPUProcess/GPUProcess.messages.in:
+    * UIProcess/API/C/WKPage.cpp:
+    (WKPageIsMockRealtimeMediaSourceCenterEnabled):
+    (WKPageSetMockCameraIsInterrupted):
+    * UIProcess/API/C/WKPagePrivate.h:
+    * UIProcess/GPU/GPUProcessProxy.cpp:
+    (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
+    * UIProcess/GPU/GPUProcessProxy.h:
+    * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+    * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+    * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+    (WebKit::UserMediaCaptureManager::sourceMutedChanged):
+    
+    Tools:
+    
+    Add mock API to mock camera interruption.
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::setMockCameraIsInterrupted):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestController.cpp:
+    (WTR::TestController::setMockCameraIsInterrupted):
+    * WebKitTestRunner/TestController.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+    
+    LayoutTests:
+    
+    * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
+    * fast/mediastream/media-stream-video-track-interrupted.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283033 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-24  Youenn Fablet  <[email protected]>
+
+            [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+            https://bugs.webkit.org/show_bug.cgi?id=230538
+            <rdar://problem/83355705>
+
+            Reviewed by Eric Carlson.
+
+            Add support for interrupting mock cameras.
+            Update internals to handle the case of out of main thread videoSampleAvailable calls.
+
+            Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
+            This ensures we can restart capture in case a track is muted without the page being muted itself.
+
+            When a source is muted and is in producing data state, it is interrupted.
+            When setMuted(false) is called, we need to uninterrupt.
+            To do so, we do a stop/start cycle
+
+            Test: fast/mediastream/media-stream-video-track-interrupted.html
+
+            * page/Page.cpp:
+            (WebCore::Page::setMuted):
+            * platform/mediastream/RealtimeMediaSource.cpp:
+            (WebCore::RealtimeMediaSource::setMuted):
+            * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+            (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
+            * platform/mock/MockRealtimeMediaSourceCenter.h:
+            * platform/mock/MockRealtimeVideoSource.cpp:
+            (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+            (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
+            (WebCore::MockRealtimeVideoSource::setIsInterrupted):
+            * platform/mock/MockRealtimeVideoSource.h:
+            * testing/Internals.cpp:
+            (WebCore::Internals::videoSampleAvailable):
+            * testing/Internals.h:
+
 2021-10-12  Alan Coon  <[email protected]>
 
         Apply patch. rdar://problem/83953336

Modified: branches/safari-612-branch/Source/WebCore/page/Page.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/page/Page.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/page/Page.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -2203,9 +2203,6 @@
 
 void Page::setMuted(MediaProducer::MutedStateFlags muted)
 {
-    if (m_mutedState == muted)
-        return;
-
     m_mutedState = muted;
 
     forEachDocument([] (Document& document) {

Modified: branches/safari-612-branch/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -107,8 +107,11 @@
     // Changed m_muted before calling start/stop so muted() will reflect the correct state.
     bool changed = m_muted != muted;
 
-    if (changed)
-        ALWAYS_LOG_IF(m_logger, LOGIDENTIFIER, muted);
+    ALWAYS_LOG_IF(m_logger && changed, LOGIDENTIFIER, muted);
+    if (changed && !muted && m_isProducingData) {
+        // Let's uninterrupt by doing a stop/start cycle.
+        stop();
+    }
 
     m_muted = muted;
     if (muted)

Modified: branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -295,6 +295,11 @@
     RealtimeMediaSourceCenter::singleton().captureDevicesChanged();
 }
 
+void MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted(bool isInterrupted)
+{
+    MockRealtimeVideoSource::setIsInterrupted(isInterrupted);
+}
+
 void MockRealtimeMediaSourceCenter::setDevices(Vector<MockMediaDevice>&& newMockDevices)
 {
     microphoneDevices().clear();

Modified: branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -47,6 +47,7 @@
     WEBCORE_EXPORT static void addDevice(const MockMediaDevice&);
     WEBCORE_EXPORT static void removeDevice(const String& persistentId);
     WEBCORE_EXPORT static void resetDevices();
+    WEBCORE_EXPORT static void setMockCameraIsInterrupted(bool);
 
     void setMockAudioCaptureEnabled(bool isEnabled) { m_isMockAudioCaptureEnabled = isEnabled; }
     void setMockVideoCaptureEnabled(bool isEnabled) { m_isMockVideoCaptureEnabled = isEnabled; }

Modified: branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -67,10 +67,19 @@
 }
 #endif
 
+static HashSet<MockRealtimeVideoSource*>& allMockRealtimeVideoSource()
+{
+    static NeverDestroyed<HashSet<MockRealtimeVideoSource*>> videoSources;
+    return videoSources;
+}
+
 MockRealtimeVideoSource::MockRealtimeVideoSource(String&& deviceID, String&& name, String&& hashSalt)
     : RealtimeVideoCaptureSource(WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt))
     , m_emitFrameTimer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame)
 {
+    ASSERT(isMainThread());
+    allMockRealtimeVideoSource().add(this);
+
     auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(persistentID());
     ASSERT(device);
     m_device = *device;
@@ -93,6 +102,12 @@
     m_fillColor = properties.fillColor;
 }
 
+MockRealtimeVideoSource::~MockRealtimeVideoSource()
+{
+    ASSERT(isMainThread());
+    allMockRealtimeVideoSource().remove(this);
+}
+
 bool MockRealtimeVideoSource::supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> rate)
 {
     // FIXME: consider splitting mock display into another class so we don't don't have to do this silly dance
@@ -514,6 +529,19 @@
     orientationChanged(notifier.orientation());
 }
 
+void MockRealtimeVideoSource::setIsInterrupted(bool isInterrupted)
+{
+    for (auto* source : allMockRealtimeVideoSource()) {
+        if (!source->isProducingData())
+            continue;
+        if (isInterrupted)
+            source->m_emitFrameTimer.stop();
+        else
+            source->startCaptureTimer();
+        source->notifyMutedChange(isInterrupted);
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/platform/mock/MockRealtimeVideoSource.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -49,7 +49,10 @@
 class MockRealtimeVideoSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer {
 public:
     static CaptureSourceOrError create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints*);
+    ~MockRealtimeVideoSource();
 
+    static void setIsInterrupted(bool);
+
     ImageBuffer* imageBuffer() const;
 
 protected:

Modified: branches/safari-612-branch/Source/WebCore/testing/Internals.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/testing/Internals.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/testing/Internals.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -5434,24 +5434,28 @@
 
 void Internals::videoSampleAvailable(MediaSample& sample)
 {
-    m_trackVideoSampleCount++;
-    if (!m_nextTrackFramePromise)
-        return;
+    callOnMainThread([this, weakThis = makeWeakPtr(this), sample = Ref { sample }] {
+        if (!weakThis)
+            return;
+        m_trackVideoSampleCount++;
+        if (!m_nextTrackFramePromise)
+            return;
 
-    auto& videoSettings = m_trackSource->settings();
-    if (!videoSettings.width() || !videoSettings.height())
-        return;
-    
-    auto rgba = sample.getRGBAImageData();
-    if (!rgba)
-        return;
-    
-    auto imageData = ImageData::create(rgba.releaseNonNull(), videoSettings.width(), videoSettings.height(), { { PredefinedColorSpace::SRGB } });
-    if (!imageData.hasException())
-        m_nextTrackFramePromise->resolve(imageData.releaseReturnValue());
-    else
-        m_nextTrackFramePromise->reject(imageData.exception().code());
-    m_nextTrackFramePromise = nullptr;
+        auto& videoSettings = m_trackSource->settings();
+        if (!videoSettings.width() || !videoSettings.height())
+            return;
+
+        auto rgba = sample->getRGBAImageData();
+        if (!rgba)
+            return;
+
+        auto imageData = ImageData::create(rgba.releaseNonNull(), videoSettings.width(), videoSettings.height(), { { PredefinedColorSpace::SRGB } });
+        if (!imageData.hasException())
+            m_nextTrackFramePromise->resolve(imageData.releaseReturnValue());
+        else
+            m_nextTrackFramePromise->reject(imageData.exception().code());
+        m_nextTrackFramePromise = nullptr;
+    });
 }
 
 void Internals::delayMediaStreamTrackSamples(MediaStreamTrack& track, float delay)

Modified: branches/safari-612-branch/Source/WebCore/testing/Internals.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebCore/testing/Internals.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebCore/testing/Internals.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -148,7 +148,7 @@
 
 class Internals final : public RefCounted<Internals>, private ContextDestructionObserver
 #if ENABLE(MEDIA_STREAM)
-    , private RealtimeMediaSource::Observer
+    , public RealtimeMediaSource::Observer
     , private RealtimeMediaSource::AudioSampleObserver
     , private RealtimeMediaSource::VideoSampleObserver
 #endif

Modified: branches/safari-612-branch/Source/WebKit/ChangeLog (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/ChangeLog	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/ChangeLog	2021-10-15 22:16:20 UTC (rev 284275)
@@ -1,3 +1,117 @@
+2021-10-15  Russell Epstein  <[email protected]>
+
+        Cherry-pick r283033. rdar://problem/83953190
+
+    [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+    https://bugs.webkit.org/show_bug.cgi?id=230538
+    <rdar://problem/83355705>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Add support for interrupting mock cameras.
+    Update internals to handle the case of out of main thread videoSampleAvailable calls.
+    
+    Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
+    This ensures we can restart capture in case a track is muted without the page being muted itself.
+    
+    When a source is muted and is in producing data state, it is interrupted.
+    When setMuted(false) is called, we need to uninterrupt.
+    To do so, we do a stop/start cycle
+    
+    Test: fast/mediastream/media-stream-video-track-interrupted.html
+    
+    * page/Page.cpp:
+    (WebCore::Page::setMuted):
+    * platform/mediastream/RealtimeMediaSource.cpp:
+    (WebCore::RealtimeMediaSource::setMuted):
+    * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+    (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
+    * platform/mock/MockRealtimeMediaSourceCenter.h:
+    * platform/mock/MockRealtimeVideoSource.cpp:
+    (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::setIsInterrupted):
+    * platform/mock/MockRealtimeVideoSource.h:
+    * testing/Internals.cpp:
+    (WebCore::Internals::videoSampleAvailable):
+    * testing/Internals.h:
+    
+    Source/WebKit:
+    
+    Add support for mock capture interruption.
+    When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
+    In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
+    It is important to not stop the source so that it can continue receiving interruption notifications.
+    
+    * GPUProcess/GPUProcess.cpp:
+    (WebKit::GPUProcess::setMockCameraIsInterrupted):
+    * GPUProcess/GPUProcess.h:
+    * GPUProcess/GPUProcess.messages.in:
+    * UIProcess/API/C/WKPage.cpp:
+    (WKPageIsMockRealtimeMediaSourceCenterEnabled):
+    (WKPageSetMockCameraIsInterrupted):
+    * UIProcess/API/C/WKPagePrivate.h:
+    * UIProcess/GPU/GPUProcessProxy.cpp:
+    (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
+    * UIProcess/GPU/GPUProcessProxy.h:
+    * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+    * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+    * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+    (WebKit::UserMediaCaptureManager::sourceMutedChanged):
+    
+    Tools:
+    
+    Add mock API to mock camera interruption.
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::setMockCameraIsInterrupted):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestController.cpp:
+    (WTR::TestController::setMockCameraIsInterrupted):
+    * WebKitTestRunner/TestController.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+    
+    LayoutTests:
+    
+    * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
+    * fast/mediastream/media-stream-video-track-interrupted.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283033 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-24  Youenn Fablet  <[email protected]>
+
+            [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+            https://bugs.webkit.org/show_bug.cgi?id=230538
+            <rdar://problem/83355705>
+
+            Reviewed by Eric Carlson.
+
+            Add support for mock capture interruption.
+            When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
+            In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
+            It is important to not stop the source so that it can continue receiving interruption notifications.
+
+            * GPUProcess/GPUProcess.cpp:
+            (WebKit::GPUProcess::setMockCameraIsInterrupted):
+            * GPUProcess/GPUProcess.h:
+            * GPUProcess/GPUProcess.messages.in:
+            * UIProcess/API/C/WKPage.cpp:
+            (WKPageIsMockRealtimeMediaSourceCenterEnabled):
+            (WKPageSetMockCameraIsInterrupted):
+            * UIProcess/API/C/WKPagePrivate.h:
+            * UIProcess/GPU/GPUProcessProxy.cpp:
+            (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
+            * UIProcess/GPU/GPUProcessProxy.h:
+            * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+            * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+            * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+            (WebKit::UserMediaCaptureManager::sourceMutedChanged):
+
 2021-10-11  Russell Epstein  <[email protected]>
 
         Cherry-pick r283846. rdar://problem/84117092

Modified: branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -348,6 +348,12 @@
 {
     MockRealtimeMediaSourceCenter::resetDevices();
 }
+
+void GPUProcess::setMockCameraIsInterrupted(bool isInterrupted)
+{
+    MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted(isInterrupted);
+}
+
 #endif
 
 #if PLATFORM(MAC)

Modified: branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -132,6 +132,7 @@
     void clearMockMediaDevices();
     void removeMockMediaDevice(const String& persistentId);
     void resetMockMediaDevices();
+    void setMockCameraIsInterrupted(bool);
     bool setCaptureAttributionString(const String&);
 #endif
 #if PLATFORM(MAC)

Modified: branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.messages.in (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.messages.in	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/GPUProcess/GPUProcess.messages.in	2021-10-15 22:16:20 UTC (rev 284275)
@@ -43,6 +43,7 @@
     ClearMockMediaDevices();
     RemoveMockMediaDevice(String persistentId);
     ResetMockMediaDevices();
+    SetMockCameraIsInterrupted(bool isInterrupted);
 #endif
 #if PLATFORM(MAC)
     DisplayConfigurationChanged(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags)

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPage.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -3154,7 +3154,7 @@
 #endif
 }
 
-WK_EXPORT bool WKPageIsMockRealtimeMediaSourceCenterEnabled(WKPageRef)
+bool WKPageIsMockRealtimeMediaSourceCenterEnabled(WKPageRef)
 {
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
     return MockRealtimeMediaSourceCenter::mockRealtimeMediaSourceCenterEnabled();
@@ -3163,6 +3163,15 @@
 #endif
 }
 
+void WKPageSetMockCameraIsInterrupted(WKPageRef pageRef, bool isInterrupted)
+{
+    CRASH_IF_SUSPENDED;
+#if ENABLE(MEDIA_STREAM) && ENABLE(GPU_PROCESS)
+    auto& gpuProcess = toImpl(pageRef)->process().processPool().ensureGPUProcess();
+    gpuProcess.setMockCameraIsInterrupted(isInterrupted);
+#endif
+}
+
 void WKPageLoadedSubresourceDomains(WKPageRef pageRef, WKPageLoadedSubresourceDomainsFunction callback, void* callbackContext)
 {
     CRASH_IF_SUSPENDED;

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPagePrivate.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -197,6 +197,7 @@
 
 WK_EXPORT void WKPageSetMockCameraOrientation(WKPageRef page, uint64_t orientation);
 WK_EXPORT bool WKPageIsMockRealtimeMediaSourceCenterEnabled(WKPageRef page);
+WK_EXPORT void WKPageSetMockCameraIsInterrupted(WKPageRef page, bool isInterrupted);
 
 typedef void (*WKPageLoadedSubresourceDomainsFunction)(WKArrayRef domains, void* functionContext);
 WK_EXPORT void WKPageLoadedSubresourceDomains(WKPageRef page, WKPageLoadedSubresourceDomainsFunction callback, void* callbackContext);

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -310,6 +310,11 @@
 {
     send(Messages::GPUProcess::ResetMockMediaDevices { }, 0);
 }
+
+void GPUProcessProxy::setMockCameraIsInterrupted(bool isInterrupted)
+{
+    send(Messages::GPUProcess::SetMockCameraIsInterrupted { isInterrupted }, 0);
+}
 #endif
 
 void GPUProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)

Modified: branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -82,6 +82,7 @@
     void clearMockMediaDevices();
     void removeMockMediaDevice(const String&);
     void resetMockMediaDevices();
+    void setMockCameraIsInterrupted(bool);
 #endif
 
     void removeSession(PAL::SessionID);

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -69,6 +69,7 @@
     void captureFailed() final;
 
     void remoteAudioSamplesAvailable(const MediaTime&, const WebCore::PlatformAudioData&, const WebCore::AudioStreamDescription&, size_t);
+    void sourceMutedChanged(bool value) { notifyMutedChange(value); }
 
 private:
     RemoteRealtimeAudioSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, String&& name, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess);

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -67,6 +67,7 @@
     void captureFailed() final;
 
     void videoSampleAvailable(WebCore::MediaSample&, WebCore::IntSize);
+    void sourceMutedChanged(bool value) { notifyMutedChange(value); }
 
 private:
     RemoteRealtimeVideoSource(WebCore::RealtimeMediaSourceIdentifier, const WebCore::CaptureDevice&, const WebCore::MediaConstraints*, String&& name, String&& hashSalt, UserMediaCaptureManager&, bool shouldCaptureInGPUProcess);

Modified: branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp (284274 => 284275)


--- branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -137,9 +137,9 @@
 void UserMediaCaptureManager::sourceMutedChanged(RealtimeMediaSourceIdentifier id, bool muted)
 {
     if (auto source = m_audioSources.get(id))
-        source->setMuted(muted);
+        source->sourceMutedChanged(muted);
     else if (auto source = m_videoSources.get(id))
-        source->setMuted(muted);
+        source->sourceMutedChanged(muted);
 }
 
 void UserMediaCaptureManager::sourceSettingsChanged(RealtimeMediaSourceIdentifier id, RealtimeMediaSourceSettings&& settings)

Modified: branches/safari-612-branch/Tools/ChangeLog (284274 => 284275)


--- branches/safari-612-branch/Tools/ChangeLog	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/ChangeLog	2021-10-15 22:16:20 UTC (rev 284275)
@@ -1,3 +1,108 @@
+2021-10-15  Russell Epstein  <[email protected]>
+
+        Cherry-pick r283033. rdar://problem/83953190
+
+    [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+    https://bugs.webkit.org/show_bug.cgi?id=230538
+    <rdar://problem/83355705>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Add support for interrupting mock cameras.
+    Update internals to handle the case of out of main thread videoSampleAvailable calls.
+    
+    Update Page::setMuted to trigger setMuted logic even if Page muted state did not change.
+    This ensures we can restart capture in case a track is muted without the page being muted itself.
+    
+    When a source is muted and is in producing data state, it is interrupted.
+    When setMuted(false) is called, we need to uninterrupt.
+    To do so, we do a stop/start cycle
+    
+    Test: fast/mediastream/media-stream-video-track-interrupted.html
+    
+    * page/Page.cpp:
+    (WebCore::Page::setMuted):
+    * platform/mediastream/RealtimeMediaSource.cpp:
+    (WebCore::RealtimeMediaSource::setMuted):
+    * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+    (WebCore::MockRealtimeMediaSourceCenter::setMockCameraIsInterrupted):
+    * platform/mock/MockRealtimeMediaSourceCenter.h:
+    * platform/mock/MockRealtimeVideoSource.cpp:
+    (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource):
+    (WebCore::MockRealtimeVideoSource::setIsInterrupted):
+    * platform/mock/MockRealtimeVideoSource.h:
+    * testing/Internals.cpp:
+    (WebCore::Internals::videoSampleAvailable):
+    * testing/Internals.h:
+    
+    Source/WebKit:
+    
+    Add support for mock capture interruption.
+    When receiving a notification that GPUProcess source is muted, we consider it is interrupted.
+    In that case, we notify the source is muted instead of calling setMuted (which would set the source as muted AND stop producing data).
+    It is important to not stop the source so that it can continue receiving interruption notifications.
+    
+    * GPUProcess/GPUProcess.cpp:
+    (WebKit::GPUProcess::setMockCameraIsInterrupted):
+    * GPUProcess/GPUProcess.h:
+    * GPUProcess/GPUProcess.messages.in:
+    * UIProcess/API/C/WKPage.cpp:
+    (WKPageIsMockRealtimeMediaSourceCenterEnabled):
+    (WKPageSetMockCameraIsInterrupted):
+    * UIProcess/API/C/WKPagePrivate.h:
+    * UIProcess/GPU/GPUProcessProxy.cpp:
+    (WebKit::GPUProcessProxy::setMockCameraIsInterrupted):
+    * UIProcess/GPU/GPUProcessProxy.h:
+    * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+    * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+    * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+    (WebKit::UserMediaCaptureManager::sourceMutedChanged):
+    
+    Tools:
+    
+    Add mock API to mock camera interruption.
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::setMockCameraIsInterrupted):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestController.cpp:
+    (WTR::TestController::setMockCameraIsInterrupted):
+    * WebKitTestRunner/TestController.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+    
+    LayoutTests:
+    
+    * fast/mediastream/media-stream-video-track-interrupted-expected.txt: Added.
+    * fast/mediastream/media-stream-video-track-interrupted.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283033 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-24  Youenn Fablet  <[email protected]>
+
+            [IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
+            https://bugs.webkit.org/show_bug.cgi?id=230538
+            <rdar://problem/83355705>
+
+            Reviewed by Eric Carlson.
+
+            Add mock API to mock camera interruption.
+
+            * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+            * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+            (WTR::TestRunner::setMockCameraIsInterrupted):
+            * WebKitTestRunner/InjectedBundle/TestRunner.h:
+            * WebKitTestRunner/TestController.cpp:
+            (WTR::TestController::setMockCameraIsInterrupted):
+            * WebKitTestRunner/TestController.h:
+            * WebKitTestRunner/TestInvocation.cpp:
+            (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2021-10-12  Alan Coon  <[email protected]>
 
         Apply patch. rdar://problem/84130892

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-10-15 22:16:20 UTC (rev 284275)
@@ -388,6 +388,7 @@
     undefined resetMockMediaDevices();
     undefined setMockCameraOrientation(unsigned long orientation);
     boolean isMockRealtimeMediaSourceCenterEnabled();
+    undefined setMockCameraIsInterrupted(boolean isInterrupted);
 
     boolean hasAppBoundSession();
     undefined clearAppBoundSession();

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -1824,6 +1824,11 @@
     return postSynchronousMessageReturningBoolean("IsMockRealtimeMediaSourceCenterEnabled");
 }
 
+void TestRunner::setMockCameraIsInterrupted(bool isInterrupted)
+{
+    postSynchronousMessage("SetMockCameraIsInterrupted", isInterrupted);
+}
+
 #if ENABLE(GAMEPAD)
 
 void TestRunner::connectMockGamepad(unsigned index)

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -502,6 +502,7 @@
     void resetMockMediaDevices();
     void setMockCameraOrientation(unsigned);
     bool isMockRealtimeMediaSourceCenterEnabled();
+    void setMockCameraIsInterrupted(bool);
 
     bool hasAppBoundSession();
     void clearAppBoundSession();

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/TestController.cpp (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/TestController.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/TestController.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -3493,6 +3493,11 @@
     return WKPageIsMockRealtimeMediaSourceCenterEnabled(m_mainWebView->page());
 }
 
+void TestController::setMockCameraIsInterrupted(bool isInterrupted)
+{
+    WKPageSetMockCameraIsInterrupted(m_mainWebView->page(), isInterrupted);
+}
+
 struct InAppBrowserPrivacyCallbackContext {
     explicit InAppBrowserPrivacyCallbackContext(TestController& controller)
         : testController(controller)

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/TestController.h (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/TestController.h	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/TestController.h	2021-10-15 22:16:20 UTC (rev 284275)
@@ -307,6 +307,7 @@
     void resetMockMediaDevices();
     void setMockCameraOrientation(uint64_t);
     bool isMockRealtimeMediaSourceCenterEnabled() const;
+    void setMockCameraIsInterrupted(bool);
     bool hasAppBoundSession();
 
     void injectUserScript(WKStringRef);

Modified: branches/safari-612-branch/Tools/WebKitTestRunner/TestInvocation.cpp (284274 => 284275)


--- branches/safari-612-branch/Tools/WebKitTestRunner/TestInvocation.cpp	2021-10-15 21:45:12 UTC (rev 284274)
+++ branches/safari-612-branch/Tools/WebKitTestRunner/TestInvocation.cpp	2021-10-15 22:16:20 UTC (rev 284275)
@@ -962,6 +962,11 @@
     if (WKStringIsEqualToUTF8CString(messageName, "IsMockRealtimeMediaSourceCenterEnabled"))
         return adoptWK(WKBooleanCreate(TestController::singleton().isMockRealtimeMediaSourceCenterEnabled()));
     
+    if (WKStringIsEqualToUTF8CString(messageName, "SetMockCameraIsInterrupted")) {
+        TestController::singleton().setMockCameraIsInterrupted(booleanValue(messageBody));
+        return nullptr;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "HasAppBoundSession"))
         return adoptWK(WKBooleanCreate(TestController::singleton().hasAppBoundSession()));
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to