Title: [275956] trunk/Source
Revision
275956
Author
drou...@apple.com
Date
2021-04-14 12:42:50 -0700 (Wed, 14 Apr 2021)

Log Message

[iOS] limit how often `WebAVPlayerController` notifies the `PlaybackSessionModel` about changes to playback speed
https://bugs.webkit.org/show_bug.cgi?id=224515
<rdar://problem/75901463>

Reviewed by Eric Carlson.

This change will cause `HTMLMediaElement::setPlaybackRate` to not send IPC back and forth
between the WebProcess and UIProcess, as a modification to the `WebAVPlayerController` in
the UIProcess would notify its `PlaybackSessionModel` "delegate", which would in turn make
it's way back to the related `HTMLMediaElement::setPlaybackRate` in the WebProcess.

Source/WebCore:

* platform/ios/WebAVPlayerController.mm:
(-[WebAVPlayerController init]):
(-[WebAVPlayerController dealloc]):
(-[WebAVPlayerController defaultPlaybackRate]): Added.
(-[WebAVPlayerController setDefaultPlaybackRate:]): Added.
(-[WebAVPlayerController rate]): Added.
(-[WebAVPlayerController setRate:]): Added.
(-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):
Instead of relying on ObjC KVO on `self` to handle changes to `defaultPlaybackRate` (and
`rate`), create an actual `setDefaultPlaybackRate:` so that we can handle cases where the
value is the same. Limit when we notify the `PlaybackSessionModel` to only when it has a
different value.

* platform/cocoa/PlaybackSessionModel.h:
* platform/cocoa/PlaybackSessionModelMediaElement.h:
* platform/cocoa/PlaybackSessionModelMediaElement.mm:
(WebCore::PlaybackSessionModelMediaElement::setPlaybackRate): Added.
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(VideoFullscreenControllerContext::setPlaybackRate): Added.
Add support for handling when the `rate` of the `AVPlayerController` changes too.

Source/WebKit:

* UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
(WebKit::PlaybackSessionModelContext::setPlaybackRate): Added.
(WebKit::PlaybackSessionManagerProxy::setPlaybackRate): Added.
* WebProcess/cocoa/PlaybackSessionManager.messages.in:
* WebProcess/cocoa/PlaybackSessionManager.h:
* WebProcess/cocoa/PlaybackSessionManager.mm:
(WebKit::PlaybackSessionManager::setPlaybackRate): Added.
Add support for handling when the `rate` of the `AVPlayerController` changes too.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (275955 => 275956)


--- trunk/Source/WebCore/ChangeLog	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/ChangeLog	2021-04-14 19:42:50 UTC (rev 275956)
@@ -1,3 +1,37 @@
+2021-04-14  Devin Rousso  <drou...@apple.com>
+
+        [iOS] limit how often `WebAVPlayerController` notifies the `PlaybackSessionModel` about changes to playback speed
+        https://bugs.webkit.org/show_bug.cgi?id=224515
+        <rdar://problem/75901463>
+
+        Reviewed by Eric Carlson.
+
+        This change will cause `HTMLMediaElement::setPlaybackRate` to not send IPC back and forth
+        between the WebProcess and UIProcess, as a modification to the `WebAVPlayerController` in
+        the UIProcess would notify its `PlaybackSessionModel` "delegate", which would in turn make
+        it's way back to the related `HTMLMediaElement::setPlaybackRate` in the WebProcess.
+
+        * platform/ios/WebAVPlayerController.mm:
+        (-[WebAVPlayerController init]):
+        (-[WebAVPlayerController dealloc]):
+        (-[WebAVPlayerController defaultPlaybackRate]): Added.
+        (-[WebAVPlayerController setDefaultPlaybackRate:]): Added.
+        (-[WebAVPlayerController rate]): Added.
+        (-[WebAVPlayerController setRate:]): Added.
+        (-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):
+        Instead of relying on ObjC KVO on `self` to handle changes to `defaultPlaybackRate` (and
+        `rate`), create an actual `setDefaultPlaybackRate:` so that we can handle cases where the
+        value is the same. Limit when we notify the `PlaybackSessionModel` to only when it has a
+        different value.
+
+        * platform/cocoa/PlaybackSessionModel.h:
+        * platform/cocoa/PlaybackSessionModelMediaElement.h:
+        * platform/cocoa/PlaybackSessionModelMediaElement.mm:
+        (WebCore::PlaybackSessionModelMediaElement::setPlaybackRate): Added.
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (VideoFullscreenControllerContext::setPlaybackRate): Added.
+        Add support for handling when the `rate` of the `AVPlayerController` changes too.
+
 2021-04-14  Kate Cheney  <katherine_che...@apple.com>
 
         Service worker soft-update loads not being marked app-bound

Modified: trunk/Source/WebCore/platform/cocoa/PlaybackSessionModel.h (275955 => 275956)


--- trunk/Source/WebCore/platform/cocoa/PlaybackSessionModel.h	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/platform/cocoa/PlaybackSessionModel.h	2021-04-14 19:42:50 UTC (rev 275956)
@@ -56,6 +56,7 @@
     virtual void beginScanningBackward() = 0;
     virtual void endScanning() = 0;
     virtual void setDefaultPlaybackRate(float) = 0;
+    virtual void setPlaybackRate(float) = 0;
     virtual void selectAudioMediaOption(uint64_t index) = 0;
     virtual void selectLegibleMediaOption(uint64_t index) = 0;
     virtual void togglePictureInPicture() = 0;

Modified: trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h (275955 => 275956)


--- trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h	2021-04-14 19:42:50 UTC (rev 275956)
@@ -69,6 +69,7 @@
     WEBCORE_EXPORT void beginScanningBackward() final;
     WEBCORE_EXPORT void endScanning() final;
     WEBCORE_EXPORT void setDefaultPlaybackRate(float) final;
+    WEBCORE_EXPORT void setPlaybackRate(float) final;
     WEBCORE_EXPORT void selectAudioMediaOption(uint64_t index) final;
     WEBCORE_EXPORT void selectLegibleMediaOption(uint64_t index) final;
     WEBCORE_EXPORT void togglePictureInPicture() final;

Modified: trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm (275955 => 275956)


--- trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm	2021-04-14 19:42:50 UTC (rev 275956)
@@ -308,6 +308,12 @@
         m_mediaElement->setDefaultPlaybackRate(defaultPlaybackRate);
 }
 
+void PlaybackSessionModelMediaElement::setPlaybackRate(float playbackRate)
+{
+    if (m_mediaElement)
+        m_mediaElement->setPlaybackRate(playbackRate);
+}
+
 void PlaybackSessionModelMediaElement::selectAudioMediaOption(uint64_t selectedAudioIndex)
 {
     if (!m_mediaElement)

Modified: trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm (275955 => 275956)


--- trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm	2021-04-14 19:42:50 UTC (rev 275956)
@@ -49,7 +49,6 @@
 static void * WebAVPlayerControllerSeekableTimeRangesObserverContext = &WebAVPlayerControllerSeekableTimeRangesObserverContext;
 static void * WebAVPlayerControllerHasLiveStreamingContentObserverContext = &WebAVPlayerControllerHasLiveStreamingContentObserverContext;
 static void * WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext = &WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext;
-static void * WebAVPlayerControllerDefaultPlaybackRateObserverContext = &WebAVPlayerControllerDefaultPlaybackRateObserverContext;
 
 static double WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta = 3.0; // Minimum delta of time required to change the duration of the seekable time range.
 static double WebAVPlayerControllerLiveStreamMinimumTargetDuration = 1.0; // Minimum segment duration to be considered valid.
@@ -56,6 +55,8 @@
 static double WebAVPlayerControllerLiveStreamSeekableTimeRangeMinimumDuration = 30.0;
 
 @implementation WebAVPlayerController {
+    double _defaultPlaybackRate;
+    double _rate;
     BOOL _liveStreamEventModePossible;
     BOOL _isScrubbing;
     BOOL _allowsPictureInPicture;
@@ -76,7 +77,6 @@
     [self addObserver:self forKeyPath:@"seekableTimeRanges" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
     [self addObserver:self forKeyPath:@"hasLiveStreamingContent" options:NSKeyValueObservingOptionInitial context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
     [self addObserver:self forKeyPath:@"playingOnSecondScreen" options:NSKeyValueObservingOptionNew context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];
-    [self addObserver:self forKeyPath:@"defaultPlaybackRate" options:NSKeyValueObservingOptionNew context:WebAVPlayerControllerDefaultPlaybackRateObserverContext];
 
     return self;
 }
@@ -86,7 +86,6 @@
     [self removeObserver:self forKeyPath:@"seekableTimeRanges" context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
     [self removeObserver:self forKeyPath:@"hasLiveStreamingContent" context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
     [self removeObserver:self forKeyPath:@"playingOnSecondScreen" context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];
-    [self removeObserver:self forKeyPath:@"defaultPlaybackRate" context:WebAVPlayerControllerDefaultPlaybackRateObserverContext];
 
     [_playerControllerProxy release];
     [_loadedTimeRanges release];
@@ -159,6 +158,48 @@
         self.delegate->pause();
 }
 
+- (double)defaultPlaybackRate
+{
+    return _defaultPlaybackRate;
+}
+
+- (void)setDefaultPlaybackRate:(double)defaultPlaybackRate
+{
+    if (defaultPlaybackRate == _defaultPlaybackRate)
+        return;
+
+    _defaultPlaybackRate = defaultPlaybackRate;
+
+    if (self.delegate && self.delegate->defaultPlaybackRate() != _defaultPlaybackRate)
+        self.delegate->setDefaultPlaybackRate(_defaultPlaybackRate);
+
+    if ([self isPlaying])
+        [self setRate:_defaultPlaybackRate];
+}
+
+- (double)rate
+{
+    return _rate;
+}
+
+- (void)setRate:(double)rate
+{
+    if (rate == _rate)
+        return;
+
+    _rate = rate;
+
+    // AVKit doesn't have a separate variable for "paused", instead representing it by a `rate` of
+    // `0`. Unfortunately, `HTMLMediaElement::play` doesn't call `HTMLMediaElement::setPlaybackRate`
+    // so if we propagate a `rate` of `0` along to the `HTMLMediaElement` then any attempt to
+    // `HTMLMediaElement::play` will effectively be a no-op since the `playbackRate` will be `0`.
+    if (!_rate)
+        return;
+
+    if (self.delegate && self.delegate->playbackRate() != _rate)
+        self.delegate->setPlaybackRate(_rate);
+}
+
 + (NSSet *)keyPathsForValuesAffectingPlaying
 {
     return [NSSet setWithObject:@"rate"];
@@ -605,12 +646,6 @@
         return;
     }
 
-    if (WebAVPlayerControllerDefaultPlaybackRateObserverContext == context) {
-        if (auto* delegate = self.delegate)
-            delegate->setDefaultPlaybackRate(_defaultPlaybackRate);
-        return;
-    }
-
     ASSERT_NOT_REACHED();
 }
 

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (275955 => 275956)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2021-04-14 19:42:50 UTC (rev 275956)
@@ -150,6 +150,7 @@
     void beginScanningBackward() override;
     void endScanning() override;
     void setDefaultPlaybackRate(float) override;
+    void setPlaybackRate(float) override;
     void selectAudioMediaOption(uint64_t) override;
     void selectLegibleMediaOption(uint64_t) override;
     double duration() const override;
@@ -849,6 +850,15 @@
     });
 }
 
+void VideoFullscreenControllerContext::setPlaybackRate(float playbackRate)
+{
+    ASSERT(isUIThread());
+    WebThreadRun([protectedThis = makeRefPtr(this), this, playbackRate] {
+        if (m_playbackModel)
+            m_playbackModel->setPlaybackRate(playbackRate);
+    });
+}
+
 void VideoFullscreenControllerContext::selectAudioMediaOption(uint64_t index)
 {
     ASSERT(isUIThread());

Modified: trunk/Source/WebKit/ChangeLog (275955 => 275956)


--- trunk/Source/WebKit/ChangeLog	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/ChangeLog	2021-04-14 19:42:50 UTC (rev 275956)
@@ -1,3 +1,26 @@
+2021-04-14  Devin Rousso  <drou...@apple.com>
+
+        [iOS] limit how often `WebAVPlayerController` notifies the `PlaybackSessionModel` about changes to playback speed
+        https://bugs.webkit.org/show_bug.cgi?id=224515
+        <rdar://problem/75901463>
+
+        Reviewed by Eric Carlson.
+
+        This change will cause `HTMLMediaElement::setPlaybackRate` to not send IPC back and forth
+        between the WebProcess and UIProcess, as a modification to the `WebAVPlayerController` in
+        the UIProcess would notify its `PlaybackSessionModel` "delegate", which would in turn make
+        it's way back to the related `HTMLMediaElement::setPlaybackRate` in the WebProcess.
+
+        * UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
+        * UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
+        (WebKit::PlaybackSessionModelContext::setPlaybackRate): Added.
+        (WebKit::PlaybackSessionManagerProxy::setPlaybackRate): Added.
+        * WebProcess/cocoa/PlaybackSessionManager.messages.in:
+        * WebProcess/cocoa/PlaybackSessionManager.h:
+        * WebProcess/cocoa/PlaybackSessionManager.mm:
+        (WebKit::PlaybackSessionManager::setPlaybackRate): Added.
+        Add support for handling when the `rate` of the `AVPlayerController` changes too.
+
 2021-04-14  Kate Cheney  <katherine_che...@apple.com>
 
         Service worker soft-update loads not being marked app-bound

Modified: trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h (275955 => 275956)


--- trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h	2021-04-14 19:42:50 UTC (rev 275956)
@@ -112,6 +112,7 @@
     void beginScanningBackward() final;
     void endScanning() final;
     void setDefaultPlaybackRate(float) final;
+    void setPlaybackRate(float) final;
     void selectAudioMediaOption(uint64_t) final;
     void selectLegibleMediaOption(uint64_t) final;
     void togglePictureInPicture() final;
@@ -238,6 +239,7 @@
     void beginScanningBackward(PlaybackSessionContextIdentifier);
     void endScanning(PlaybackSessionContextIdentifier);
     void setDefaultPlaybackRate(PlaybackSessionContextIdentifier, float);
+    void setPlaybackRate(PlaybackSessionContextIdentifier, float);
     void selectAudioMediaOption(PlaybackSessionContextIdentifier, uint64_t index);
     void selectLegibleMediaOption(PlaybackSessionContextIdentifier, uint64_t index);
     void togglePictureInPicture(PlaybackSessionContextIdentifier);

Modified: trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm (275955 => 275956)


--- trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm	2021-04-14 19:42:50 UTC (rev 275956)
@@ -127,6 +127,12 @@
         m_manager->setDefaultPlaybackRate(m_contextId, defaultPlaybackRate);
 }
 
+void PlaybackSessionModelContext::setPlaybackRate(float playbackRate)
+{
+    if (m_manager)
+        m_manager->setPlaybackRate(m_contextId, playbackRate);
+}
+
 void PlaybackSessionModelContext::selectAudioMediaOption(uint64_t optionId)
 {
     if (m_manager)
@@ -562,6 +568,11 @@
     m_page->send(Messages::PlaybackSessionManager::SetDefaultPlaybackRate(contextId, defaultPlaybackRate));
 }
 
+void PlaybackSessionManagerProxy::setPlaybackRate(PlaybackSessionContextIdentifier contextId, float playbackRate)
+{
+    m_page->send(Messages::PlaybackSessionManager::SetPlaybackRate(contextId, playbackRate));
+}
+
 void PlaybackSessionManagerProxy::selectAudioMediaOption(PlaybackSessionContextIdentifier contextId, uint64_t index)
 {
     m_page->send(Messages::PlaybackSessionManager::SelectAudioMediaOption(contextId, index));

Modified: trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h (275955 => 275956)


--- trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h	2021-04-14 19:42:50 UTC (rev 275956)
@@ -155,6 +155,7 @@
     void beginScanningBackward(PlaybackSessionContextIdentifier);
     void endScanning(PlaybackSessionContextIdentifier);
     void setDefaultPlaybackRate(PlaybackSessionContextIdentifier, float);
+    void setPlaybackRate(PlaybackSessionContextIdentifier, float);
     void selectAudioMediaOption(PlaybackSessionContextIdentifier, uint64_t index);
     void selectLegibleMediaOption(PlaybackSessionContextIdentifier, uint64_t index);
     void handleControlledElementIDRequest(PlaybackSessionContextIdentifier);

Modified: trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.messages.in (275955 => 275956)


--- trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.messages.in	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.messages.in	2021-04-14 19:42:50 UTC (rev 275956)
@@ -34,6 +34,7 @@
     BeginScanningBackward(WebKit::PlaybackSessionContextIdentifier contextId)
     EndScanning(WebKit::PlaybackSessionContextIdentifier contextId)
     SetDefaultPlaybackRate(WebKit::PlaybackSessionContextIdentifier contextId, float defaultPlaybackRate)
+    SetPlaybackRate(WebKit::PlaybackSessionContextIdentifier contextId, float playbackRate)
     SelectAudioMediaOption(WebKit::PlaybackSessionContextIdentifier contextId, uint64_t index)
     SelectLegibleMediaOption(WebKit::PlaybackSessionContextIdentifier contextId, uint64_t index)
     HandleControlledElementIDRequest(WebKit::PlaybackSessionContextIdentifier contextId)

Modified: trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm (275955 => 275956)


--- trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm	2021-04-14 18:47:56 UTC (rev 275955)
+++ trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm	2021-04-14 19:42:50 UTC (rev 275956)
@@ -475,6 +475,12 @@
     ensureModel(contextId).setDefaultPlaybackRate(defaultPlaybackRate);
 }
 
+void PlaybackSessionManager::setPlaybackRate(PlaybackSessionContextIdentifier contextId, float playbackRate)
+{
+    UserGestureIndicator indicator(ProcessingUserGesture);
+    ensureModel(contextId).setPlaybackRate(playbackRate);
+}
+
 void PlaybackSessionManager::selectAudioMediaOption(PlaybackSessionContextIdentifier contextId, uint64_t index)
 {
     UserGestureIndicator indicator(ProcessingUserGesture);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to