Media controls playhead does not animate smoothly while playing
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Sep 2016 01:38:52 +0000 (01:38 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Sep 2016 01:38:52 +0000 (01:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162399
<rdar://problem/28115680>

Reviewed by Beth Dakin.

Source/WebCore:

The media controls playhead currently does not animate smoothly during playback because we don't specify a
playback rate when updating the WebPlaybackControlsManager's timing value. However, simply setting this timing
value to the current playback rate (as known to the UI process) results in the UI process receiving multiple
updates from the web process where the current time is equal (or even less than) the time at which media began
to play, which results in the playhead seeking backwards to the start time multiple times when playing or
resuming media.

To address this, in WebCore, we inform the playback session model of the media time when playback begins (i.e.
a `playing` or `play` event is fired). This message precedes both the "rate changed" and "current time changed"
messages.

Unit tests to be added in a future patch.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::notifyAboutPlaying):
(WebCore::HTMLMediaElement::setReadyState):
(WebCore::HTMLMediaElement::playInternal):
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::playbackStartedTime):
* platform/cocoa/WebPlaybackSessionModel.h:
(WebCore::WebPlaybackSessionModelClient::playbackStartedTimeChanged):
(WebCore::WebPlaybackSessionModelClient::bufferedTimeChanged): Deleted.
* platform/cocoa/WebPlaybackSessionModelMediaElement.h:
* platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
(WebPlaybackSessionModelMediaElement::updateForEventName):
(WebPlaybackSessionModelMediaElement::playbackStartedTime):
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
* platform/mac/WebPlaybackSessionInterfaceMac.h:
* platform/mac/WebPlaybackSessionInterfaceMac.mm:
(WebCore::WebPlaybackSessionInterfaceMac::currentTimeChanged):
(WebCore::WebPlaybackSessionInterfaceMac::rateChanged):
(WebCore::WebPlaybackSessionInterfaceMac::beginScrubbing):
(WebCore::WebPlaybackSessionInterfaceMac::endScrubbing):
(WebCore::WebPlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming):

Source/WebKit2:

See WebCore ChangeLog for more details.

In the UI process, we update the WebPlaybackSessionManager's timing value when the rate or current time changes.
Each AVValueTiming is generated from the current time, system anchor time, and playback rate. The behavior of
the first two properties is unaffected. However, the rate used to update the timing value is the effective
playback rate, which is equal to the playback rate unless we are (1) not playing, (2) interacting with the media
controls in such a way that the media is essentially not playing, or (3) the current time precedes the playback
start time, accounting for playback direction. In these cases, our effective playback rate is 0, which means
that we do not animate the playhead.

* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
(WebKit::WebPlaybackSessionModelContext::beginScrubbing):
(WebKit::WebPlaybackSessionModelContext::endScrubbing):
(WebKit::WebPlaybackSessionModelContext::setPlaybackStartedTime):
(WebKit::WebPlaybackSessionModelContext::setCurrentTime):
(WebKit::WebPlaybackSessionManagerProxy::setPlaybackStartedTime):
* WebProcess/cocoa/WebPlaybackSessionManager.h:
* WebProcess/cocoa/WebPlaybackSessionManager.mm:
(WebKit::WebPlaybackSessionInterfaceContext::playbackStartedTimeChanged):
(WebKit::WebPlaybackSessionManager::playbackStartedTimeChanged):

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/platform/cocoa/WebPlaybackSessionModel.h
Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.h
Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm
Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm
Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.h
Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.mm
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h
Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in
Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm
Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h
Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm

index 307005b..02234ee 100644 (file)
@@ -1,3 +1,46 @@
+2016-09-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Media controls playhead does not animate smoothly while playing
+        https://bugs.webkit.org/show_bug.cgi?id=162399
+        <rdar://problem/28115680>
+
+        Reviewed by Beth Dakin.
+
+        The media controls playhead currently does not animate smoothly during playback because we don't specify a
+        playback rate when updating the WebPlaybackControlsManager's timing value. However, simply setting this timing
+        value to the current playback rate (as known to the UI process) results in the UI process receiving multiple
+        updates from the web process where the current time is equal (or even less than) the time at which media began
+        to play, which results in the playhead seeking backwards to the start time multiple times when playing or
+        resuming media.
+
+        To address this, in WebCore, we inform the playback session model of the media time when playback begins (i.e.
+        a `playing` or `play` event is fired). This message precedes both the "rate changed" and "current time changed"
+        messages.
+
+        Unit tests to be added in a future patch.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::notifyAboutPlaying):
+        (WebCore::HTMLMediaElement::setReadyState):
+        (WebCore::HTMLMediaElement::playInternal):
+        * html/HTMLMediaElement.h:
+        (WebCore::HTMLMediaElement::playbackStartedTime):
+        * platform/cocoa/WebPlaybackSessionModel.h:
+        (WebCore::WebPlaybackSessionModelClient::playbackStartedTimeChanged):
+        (WebCore::WebPlaybackSessionModelClient::bufferedTimeChanged): Deleted.
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.h:
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
+        (WebPlaybackSessionModelMediaElement::updateForEventName):
+        (WebPlaybackSessionModelMediaElement::playbackStartedTime):
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        * platform/mac/WebPlaybackSessionInterfaceMac.h:
+        * platform/mac/WebPlaybackSessionInterfaceMac.mm:
+        (WebCore::WebPlaybackSessionInterfaceMac::currentTimeChanged):
+        (WebCore::WebPlaybackSessionInterfaceMac::rateChanged):
+        (WebCore::WebPlaybackSessionInterfaceMac::beginScrubbing):
+        (WebCore::WebPlaybackSessionInterfaceMac::endScrubbing):
+        (WebCore::WebPlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming):
+
 2016-09-23  Zalan Bujtas  <zalan@apple.com>
 
         ASSERTION FAILED: !newRelayoutRoot.container() || is<RenderView>(newRelayoutRoot.container()) || !newRelayoutRoot.container()->needsLayout() while loading sohu.com
index b285d5c..a2dc1be 100644 (file)
@@ -1028,6 +1028,7 @@ void HTMLMediaElement::scheduleNotifyAboutPlaying()
 
 void HTMLMediaElement::notifyAboutPlaying()
 {
+    m_playbackStartedTime = currentMediaTime().toDouble();
     dispatchEvent(Event::create(eventNames().playingEvent, false, true));
     resolvePendingPlayPromises();
 
@@ -2421,6 +2422,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
         if (canTransitionFromAutoplayToPlay()) {
             m_paused = false;
             invalidateCachedTime();
+            m_playbackStartedTime = currentMediaTime().toDouble();
             scheduleEvent(eventNames().playEvent);
             scheduleNotifyAboutPlaying();
         }
@@ -3210,6 +3212,7 @@ bool HTMLMediaElement::playInternal()
     if (m_paused) {
         m_paused = false;
         invalidateCachedTime();
+        m_playbackStartedTime = currentMediaTime().toDouble();
         scheduleEvent(eventNames().playEvent);
 
         if (m_readyState <= HAVE_CURRENT_DATA)
index 7cd0ff3..7c6dea0 100644 (file)
@@ -478,6 +478,8 @@ public:
     bool hasEverHadAudio() const { return m_hasEverHadAudio; }
     bool hasEverHadVideo() const { return m_hasEverHadVideo; }
 
+    double playbackStartedTime() const { return m_playbackStartedTime; }
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
     virtual ~HTMLMediaElement();
@@ -858,6 +860,7 @@ private:
     MediaTime m_lastSeekTime;
     
     double m_previousProgressTime;
+    double m_playbackStartedTime { 0 };
 
     // The last time a timeupdate event was sent (based on monotonic clock).
     double m_clockTimeAtLastUpdateEvent;
index a250e3c..e30f80c 100644 (file)
@@ -59,10 +59,12 @@ public:
 
     enum ExternalPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
 
+    virtual double playbackStartedTime() const = 0;
     virtual double duration() const = 0;
     virtual double currentTime() const = 0;
     virtual double bufferedTime() const = 0;
     virtual bool isPlaying() const = 0;
+    virtual bool isScrubbing() const = 0;
     virtual float playbackRate() const = 0;
     virtual Ref<TimeRanges> seekableRanges() const = 0;
     virtual bool canPlayFastReverse() const = 0;
@@ -82,6 +84,7 @@ public:
     virtual void durationChanged(double) { }
     virtual void currentTimeChanged(double /* currentTime */, double /* anchorTime */) { }
     virtual void bufferedTimeChanged(double) { }
+    virtual void playbackStartedTimeChanged(double /* playbackStartedTime */) { }
     virtual void rateChanged(bool /* isPlaying */, float /* playbackRate */) { }
     virtual void seekableRangesChanged(const TimeRanges&) { }
     virtual void canPlayFastReverseChanged(bool) { }
index b9d23f7..135097d 100644 (file)
@@ -73,6 +73,7 @@ public:
     double currentTime() const final;
     double bufferedTime() const final;
     bool isPlaying() const final;
+    bool isScrubbing() const final { return false; }
     float playbackRate() const final;
     Ref<TimeRanges> seekableRanges() const final;
     bool canPlayFastReverse() const final;
@@ -98,6 +99,7 @@ private:
     Vector<RefPtr<TextTrack>> m_legibleTracksForMenu;
     Vector<RefPtr<AudioTrack>> m_audioTracksForMenu;
     
+    double playbackStartedTime() const;
     void updateLegibleOptions();
 };
     
index cdceee1..b10f2e9 100644 (file)
@@ -106,6 +106,13 @@ void WebPlaybackSessionModelMediaElement::updateForEventName(const WTF::AtomicSt
     }
 
     if (all
+        || eventName == eventNames().playEvent
+        || eventName == eventNames().playingEvent) {
+        for (auto client : m_clients)
+            client->playbackStartedTimeChanged(playbackStartedTime());
+    }
+
+    if (all
         || eventName == eventNames().pauseEvent
         || eventName == eventNames().playEvent
         || eventName == eventNames().ratechangeEvent) {
@@ -287,6 +294,14 @@ void WebPlaybackSessionModelMediaElement::updateLegibleOptions()
     }
 }
 
+double WebPlaybackSessionModelMediaElement::playbackStartedTime() const
+{
+    if (!m_mediaElement)
+        return 0;
+
+    return m_mediaElement->playbackStartedTime();
+}
+
 const Vector<AtomicString>& WebPlaybackSessionModelMediaElement::observedEventNames()
 {
     // FIXME(157452): Remove the right-hand constructor notation once NeverDestroyed supports initializer_lists.
index 89d8c39..3a8b8b5 100644 (file)
@@ -147,9 +147,11 @@ private:
     void selectAudioMediaOption(uint64_t) override;
     void selectLegibleMediaOption(uint64_t) override;
     double duration() const override;
+    double playbackStartedTime() const override { return 0; }
     double currentTime() const override;
     double bufferedTime() const override;
     bool isPlaying() const override;
+    bool isScrubbing() const override { return false; }
     float playbackRate() const override;
     Ref<TimeRanges> seekableRanges() const override;
     bool canPlayFastReverse() const override;
index 054a843..9ad8054 100644 (file)
@@ -63,12 +63,16 @@ public:
     WEBCORE_EXPORT void invalidate();
     WEBCORE_EXPORT void ensureControlsManager();
     WEBCORE_EXPORT void setPlayBackControlsManager(WebPlaybackControlsManager *);
+    WEBCORE_EXPORT void beginScrubbing();
+    WEBCORE_EXPORT void endScrubbing();
     WEBCORE_EXPORT WebPlaybackControlsManager *playBackControlsManager();
 
 private:
     WebPlaybackSessionInterfaceMac(WebPlaybackSessionModel&);
     WebPlaybackSessionModel* m_playbackSessionModel { nullptr };
     WebPlaybackControlsManager *m_playbackControlsManager  { nullptr };
+
+    void updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying);
 };
 
 }
index 16f18cf..d3b0426 100644 (file)
@@ -76,12 +76,7 @@ void WebPlaybackSessionInterfaceMac::durationChanged(double duration)
 void WebPlaybackSessionInterfaceMac::currentTimeChanged(double currentTime, double anchorTime)
 {
     WebPlaybackControlsManager* controlsManager = playBackControlsManager();
-
-    NSTimeInterval anchorTimeStamp = ![controlsManager rate] ? NAN : anchorTime;
-    AVValueTiming *timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime
-        anchorTimeStamp:anchorTimeStamp rate:0];
-
-    [controlsManager setTiming:timing];
+    updatePlaybackControlsManagerTiming(currentTime, anchorTime, controlsManager.rate, controlsManager.playing);
 }
 
 void WebPlaybackSessionInterfaceMac::rateChanged(bool isPlaying, float playbackRate)
@@ -89,6 +84,18 @@ void WebPlaybackSessionInterfaceMac::rateChanged(bool isPlaying, float playbackR
     WebPlaybackControlsManager* controlsManager = playBackControlsManager();
     [controlsManager setRate:isPlaying ? playbackRate : 0.];
     [controlsManager setPlaying:isPlaying];
+    updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], playbackRate, isPlaying);
+}
+
+void WebPlaybackSessionInterfaceMac::beginScrubbing()
+{
+    updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], 0, false);
+    webPlaybackSessionModel()->beginScrubbing();
+}
+
+void WebPlaybackSessionInterfaceMac::endScrubbing()
+{
+    webPlaybackSessionModel()->endScrubbing();
 }
 
 static RetainPtr<NSMutableArray> timeRangesToArray(const TimeRanges& timeRanges)
@@ -163,6 +170,27 @@ void WebPlaybackSessionInterfaceMac::setPlayBackControlsManager(WebPlaybackContr
     [manager setLegibleMediaSelectionOptions:m_playbackSessionModel->legibleMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->legibleMediaSelectedIndex())];
 }
 
+void WebPlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying)
+{
+    WebPlaybackControlsManager *manager = playBackControlsManager();
+    if (!manager)
+        return;
+
+    WebPlaybackSessionModel *model = webPlaybackSessionModel();
+    if (!model)
+        return;
+
+    double effectiveAnchorTime = playbackRate ? anchorTime : NAN;
+    double effectivePlaybackRate = playbackRate;
+    if (!isPlaying
+        || model->isScrubbing()
+        || (manager.rate > 0 && model->playbackStartedTime() >= currentTime)
+        || (manager.rate < 0 && model->playbackStartedTime() <= currentTime))
+        effectivePlaybackRate = 0;
+
+    manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime anchorTimeStamp:effectiveAnchorTime rate:effectivePlaybackRate];
+}
+
 }
 
 #endif // PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
index bab067d..14ff8a4 100644 (file)
@@ -1,3 +1,34 @@
+2016-09-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Media controls playhead does not animate smoothly while playing
+        https://bugs.webkit.org/show_bug.cgi?id=162399
+        <rdar://problem/28115680>
+
+        Reviewed by Beth Dakin.
+
+        See WebCore ChangeLog for more details.
+
+        In the UI process, we update the WebPlaybackSessionManager's timing value when the rate or current time changes.
+        Each AVValueTiming is generated from the current time, system anchor time, and playback rate. The behavior of
+        the first two properties is unaffected. However, the rate used to update the timing value is the effective
+        playback rate, which is equal to the playback rate unless we are (1) not playing, (2) interacting with the media
+        controls in such a way that the media is essentially not playing, or (3) the current time precedes the playback
+        start time, accounting for playback direction. In these cases, our effective playback rate is 0, which means
+        that we do not animate the playhead.
+
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
+        (WebKit::WebPlaybackSessionModelContext::beginScrubbing):
+        (WebKit::WebPlaybackSessionModelContext::endScrubbing):
+        (WebKit::WebPlaybackSessionModelContext::setPlaybackStartedTime):
+        (WebKit::WebPlaybackSessionModelContext::setCurrentTime):
+        (WebKit::WebPlaybackSessionManagerProxy::setPlaybackStartedTime):
+        * WebProcess/cocoa/WebPlaybackSessionManager.h:
+        * WebProcess/cocoa/WebPlaybackSessionManager.mm:
+        (WebKit::WebPlaybackSessionInterfaceContext::playbackStartedTimeChanged):
+        (WebKit::WebPlaybackSessionManager::playbackStartedTimeChanged):
+
 2016-09-23  Caitlin Potter  <caitp@igalia.com>
 
         [JSC] Implement parsing of Async Functions
index 8528c1f..dd535e3 100644 (file)
@@ -71,6 +71,7 @@ public:
     void setDuration(double);
     void setCurrentTime(double);
     void setBufferedTime(double);
+    void setPlaybackStartedTime(double);
     void setRate(bool isPlaying, float playbackRate);
     void setSeekableRanges(WebCore::TimeRanges&);
     void setCanPlayFastReverse(bool);
@@ -102,10 +103,12 @@ private:
     void selectAudioMediaOption(uint64_t) final;
     void selectLegibleMediaOption(uint64_t) final;
 
+    double playbackStartedTime() const final { return m_playbackStartedTime; }
     double duration() const final { return m_duration; }
     double currentTime() const final { return m_currentTime; }
     double bufferedTime() const final { return m_bufferedTime; }
     bool isPlaying() const final { return m_isPlaying; }
+    bool isScrubbing() const final { return m_isScrubbing; }
     float playbackRate() const final { return m_playbackRate; }
     Ref<WebCore::TimeRanges> seekableRanges() const final { return m_seekableRanges.copyRef(); }
     bool canPlayFastReverse() const final { return m_canPlayFastReverse; }
@@ -121,10 +124,13 @@ private:
     WebPlaybackSessionManagerProxy* m_manager;
     uint64_t m_contextId;
     HashSet<WebCore::WebPlaybackSessionModelClient*> m_clients;
+    double m_playbackStartedTime { 0 };
+    bool m_playbackStartedTimeNeedsUpdate { false };
     double m_duration { 0 };
     double m_currentTime { 0 };
     double m_bufferedTime { 0 };
     bool m_isPlaying { false };
+    bool m_isScrubbing { false };
     float m_playbackRate { 0 };
     Ref<WebCore::TimeRanges> m_seekableRanges { WebCore::TimeRanges::create() };
     bool m_canPlayFastReverse { false };
@@ -176,6 +182,7 @@ private:
     void setExternalPlaybackProperties(uint64_t contextId, bool enabled, uint32_t targetType, String localizedDeviceName);
     void setWirelessVideoPlaybackDisabled(uint64_t contextId, bool);
     void setDuration(uint64_t contextId, double duration);
+    void setPlaybackStartedTime(uint64_t contextId, double playbackStartedTime);
     void setRate(uint64_t contextId, bool isPlaying, double rate);
     void handleControlledElementIDResponse(uint64_t, String) const;
 
index 825b9eb..9ce69f6 100644 (file)
@@ -32,6 +32,7 @@ messages -> WebPlaybackSessionManagerProxy {
     SetExternalPlaybackProperties(uint64_t contextId, bool enabled, uint32_t targetType, String localizedDeviceName)
     SetWirelessVideoPlaybackDisabled(uint64_t contextId, bool disabled)
     SetDuration(uint64_t contextId, double duration)
+    SetPlaybackStartedTime(uint64_t contextId, double playbackStartedTime)
     SetRate(uint64_t contextId, bool isPlaying, double rate)
     SetUpPlaybackControlsManagerWithID(uint64_t contextId)
     ClearPlaybackControlsManager()
index 5a93ffa..c92b0a9 100644 (file)
@@ -74,12 +74,17 @@ void WebPlaybackSessionModelContext::beginScrubbing()
 {
     if (m_manager)
         m_manager->beginScrubbing(m_contextId);
+
+    m_isScrubbing = true;
 }
 
 void WebPlaybackSessionModelContext::endScrubbing()
 {
     if (m_manager)
         m_manager->endScrubbing(m_contextId);
+
+    m_isScrubbing = false;
+    m_playbackStartedTimeNeedsUpdate = isPlaying();
 }
 
 void WebPlaybackSessionModelContext::seekToTime(double time)
@@ -124,6 +129,12 @@ void WebPlaybackSessionModelContext::selectLegibleMediaOption(uint64_t optionId)
         m_manager->selectLegibleMediaOption(m_contextId, optionId);
 }
 
+void WebPlaybackSessionModelContext::setPlaybackStartedTime(double playbackStartedTime)
+{
+    m_playbackStartedTime = playbackStartedTime;
+    m_playbackStartedTimeNeedsUpdate = false;
+}
+
 void WebPlaybackSessionModelContext::setDuration(double duration)
 {
     m_duration = duration;
@@ -135,6 +146,8 @@ void WebPlaybackSessionModelContext::setCurrentTime(double currentTime)
 {
     m_currentTime = currentTime;
     auto anchorTime = [[NSProcessInfo processInfo] systemUptime];
+    if (m_playbackStartedTimeNeedsUpdate)
+        setPlaybackStartedTime(currentTime);
 
     for (auto* client : m_clients)
         client->currentTimeChanged(currentTime, anchorTime);
@@ -389,6 +402,11 @@ void WebPlaybackSessionManagerProxy::setDuration(uint64_t contextId, double dura
     ensureModel(contextId).setDuration(duration);
 }
 
+void WebPlaybackSessionManagerProxy::setPlaybackStartedTime(uint64_t contextId, double playbackStartedTime)
+{
+    ensureModel(contextId).setPlaybackStartedTime(playbackStartedTime);
+}
+
 void WebPlaybackSessionManagerProxy::setRate(uint64_t contextId, bool isPlaying, double rate)
 {
     ensureModel(contextId).setRate(isPlaying, rate);
index 472f6e0..4522615 100644 (file)
@@ -77,6 +77,7 @@ private:
     void durationChanged(double) final;
     void currentTimeChanged(double currentTime, double anchorTime) final;
     void bufferedTimeChanged(double) final;
+    void playbackStartedTimeChanged(double playbackStartedTime) final;
     void rateChanged(bool isPlaying, float playbackRate) final;
     void seekableRangesChanged(const WebCore::TimeRanges&) final;
     void canPlayFastReverseChanged(bool value) final;
@@ -122,6 +123,7 @@ protected:
     void durationChanged(uint64_t contextId, double);
     void currentTimeChanged(uint64_t contextId, double currentTime, double anchorTime);
     void bufferedTimeChanged(uint64_t contextId, double bufferedTime);
+    void playbackStartedTimeChanged(uint64_t contextId, double playbackStartedTime);
     void rateChanged(uint64_t contextId, bool isPlaying, float playbackRate);
     void seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges&);
     void canPlayFastReverseChanged(uint64_t contextId, bool value);
index 8a14877..3c8fb34 100644 (file)
@@ -96,6 +96,12 @@ void WebPlaybackSessionInterfaceContext::rateChanged(bool isPlaying, float playb
         m_manager->rateChanged(m_contextId, isPlaying, playbackRate);
 }
 
+void WebPlaybackSessionInterfaceContext::playbackStartedTimeChanged(double playbackStartedTime)
+{
+    if (m_manager)
+        m_manager->playbackStartedTimeChanged(m_contextId, playbackStartedTime);
+}
+
 void WebPlaybackSessionInterfaceContext::seekableRangesChanged(const WebCore::TimeRanges& ranges)
 {
     if (m_manager)
@@ -297,6 +303,11 @@ void WebPlaybackSessionManager::bufferedTimeChanged(uint64_t contextId, double b
     m_page->send(Messages::WebPlaybackSessionManagerProxy::SetBufferedTime(contextId, bufferedTime), m_page->pageID());
 }
 
+void WebPlaybackSessionManager::playbackStartedTimeChanged(uint64_t contextId, double playbackStartedTime)
+{
+    m_page->send(Messages::WebPlaybackSessionManagerProxy::SetPlaybackStartedTime(contextId, playbackStartedTime), m_page->pageID());
+}
+
 void WebPlaybackSessionManager::rateChanged(uint64_t contextId, bool isPlaying, float playbackRate)
 {
     m_page->send(Messages::WebPlaybackSessionManagerProxy::SetRate(contextId, isPlaying, playbackRate), m_page->pageID());