Title: [245039] trunk
Revision
245039
Author
eric.carl...@apple.com
Date
2019-05-07 15:00:32 -0700 (Tue, 07 May 2019)

Log Message

Define media buffering policy
https://bugs.webkit.org/show_bug.cgi?id=196979
<rdar://problem/28383861>

Reviewed by Jer Noble.

Source/WebCore:

Test: MediaBufferingPolicy API test.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::suspend):
(WebCore::HTMLMediaElement::resume):
(WebCore::HTMLMediaElement::createMediaPlayer):
(WebCore::HTMLMediaElement::setBufferingPolicy):
(WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
(WebCore::HTMLMediaElement::bufferingPolicy const):
(WebCore::HTMLMediaElement::setShouldBufferData): Deleted.
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::shouldBufferData const): Deleted.
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::updateClientDataBuffering):
(WebCore::MediaElementSession::preferredBufferingPolicy const):
(WebCore::MediaElementSession::dataBufferingPermitted const): Deleted.
* html/MediaElementSession.h:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::setBufferingPolicy):
(WebCore::convertEnumerationToString):
(WebCore::MediaPlayer::setShouldBufferData): Deleted.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerEnums.h:
(WTF::LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy>::toString):
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setBufferingPolicy):
(WebCore::MediaPlayerPrivateInterface::setShouldBufferData): Deleted.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setBufferingPolicy):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldBufferData): Deleted.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers): Deleted.
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setShouldBufferData): Deleted.
* testing/Internals.cpp:
(WebCore::Internals::elementShouldBufferData):
(WebCore::Internals::elementBufferingPolicy):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebCore/PAL:

* pal/spi/mac/AVFoundationSPI.h:

Source/WTF:

* wtf/Platform.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm: Added.
(waitUntilBufferingPolicyIsEqualTo):
(TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (245038 => 245039)


--- trunk/Source/WTF/ChangeLog	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WTF/ChangeLog	2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,13 @@
+2019-05-07  Eric Carlson  <eric.carl...@apple.com>
+
+        Define media buffering policy
+        https://bugs.webkit.org/show_bug.cgi?id=196979
+        <rdar://problem/28383861>
+
+        Reviewed by Jer Noble.
+
+        * wtf/Platform.h:
+
 2019-05-07  Robin Morisset  <rmoris...@apple.com>
 
         WTF::BitVector should have an isEmpty() method

Modified: trunk/Source/WTF/wtf/Platform.h (245038 => 245039)


--- trunk/Source/WTF/wtf/Platform.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WTF/wtf/Platform.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -1527,3 +1527,8 @@
 #define HAVE_APP_LINKS_WITH_ISENABLED 1
 #define HAVE_ROUTE_SHARING_POLICY_LONG_FORM_VIDEO 1
 #endif
+
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (PLATFORM(WATCHOS) && __WATCH_OS_VERSION_MIN_REQUIRED >= 60000) || (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 130000)
+#define HAVE_AVPLAYER_RESOURCE_CONSERVATION_LEVEL 1
+#endif
+

Modified: trunk/Source/WebCore/ChangeLog (245038 => 245039)


--- trunk/Source/WebCore/ChangeLog	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/ChangeLog	2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,55 @@
+2019-05-07  Eric Carlson  <eric.carl...@apple.com>
+
+        Define media buffering policy
+        https://bugs.webkit.org/show_bug.cgi?id=196979
+        <rdar://problem/28383861>
+
+        Reviewed by Jer Noble.
+
+        Test: MediaBufferingPolicy API test.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+        (WebCore::HTMLMediaElement::suspend):
+        (WebCore::HTMLMediaElement::resume):
+        (WebCore::HTMLMediaElement::createMediaPlayer):
+        (WebCore::HTMLMediaElement::setBufferingPolicy):
+        (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
+        (WebCore::HTMLMediaElement::bufferingPolicy const):
+        (WebCore::HTMLMediaElement::setShouldBufferData): Deleted.
+        * html/HTMLMediaElement.h:
+        (WebCore::HTMLMediaElement::shouldBufferData const): Deleted.
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::updateClientDataBuffering):
+        (WebCore::MediaElementSession::preferredBufferingPolicy const):
+        (WebCore::MediaElementSession::dataBufferingPermitted const): Deleted.
+        * html/MediaElementSession.h:
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::setBufferingPolicy):
+        (WebCore::convertEnumerationToString):
+        (WebCore::MediaPlayer::setShouldBufferData): Deleted.
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerEnums.h:
+        (WTF::LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy>::toString):
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::setBufferingPolicy):
+        (WebCore::MediaPlayerPrivateInterface::setShouldBufferData): Deleted.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setBufferingPolicy):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldBufferData): Deleted.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers): Deleted.
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setShouldBufferData): Deleted.
+        * testing/Internals.cpp:
+        (WebCore::Internals::elementShouldBufferData):
+        (WebCore::Internals::elementBufferingPolicy):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-05-07  Alex Christensen  <achristen...@webkit.org>
 
         Add SPI to set a list of hosts to which to send custom header fields cross-origin

Modified: trunk/Source/WebCore/PAL/ChangeLog (245038 => 245039)


--- trunk/Source/WebCore/PAL/ChangeLog	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/PAL/ChangeLog	2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,13 @@
+2019-05-07  Eric Carlson  <eric.carl...@apple.com>
+
+        Define media buffering policy
+        https://bugs.webkit.org/show_bug.cgi?id=196979
+        <rdar://problem/28383861>
+
+        Reviewed by Jer Noble.
+
+        * pal/spi/mac/AVFoundationSPI.h:
+
 2019-05-04  Alex Christensen  <achristen...@webkit.org>
 
         Revert r244953 and r244954 because they broke internal builds.

Modified: trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h (245038 => 245039)


--- trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -324,3 +324,16 @@
 NS_ASSUME_NONNULL_END
 #endif
 
+#if !USE(APPLE_INTERNAL_SDK) && HAVE(AVPLAYER_RESOURCE_CONSERVATION_LEVEL)
+@interface AVPlayer (AVPlayerPrivate)
+
+@property (nonatomic) AVPlayerResourceConservationLevel resourceConservationLevelWhilePaused;
+
+typedef NS_ENUM(NSInteger, AVPlayerResourceConservationLevel) {
+    AVPlayerResourceConservationLevelNone                                 = 0,
+    AVPlayerResourceConservationLevelReduceReadAhead                      = 1,
+    AVPlayerResourceConservationLevelReuseActivePlayerResources           = 2,
+    AVPlayerResourceConservationLevelRecycleBuffer                        = 3,
+};
+@end
+#endif

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (245038 => 245039)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2019-05-07 22:00:32 UTC (rev 245039)
@@ -449,7 +449,6 @@
     , m_completelyLoaded(false)
     , m_havePreparedToPlay(false)
     , m_parsingInProgress(createdByParser)
-    , m_shouldBufferData(true)
     , m_elementIsHidden(document.hidden())
     , m_creatingControls(false)
     , m_receivedLayoutSizeChanged(false)
@@ -5779,7 +5778,7 @@
     case ReasonForSuspension::PageCache:
         stopWithoutDestroyingMediaPlayer();
         m_asyncEventQueue.suspend();
-        setShouldBufferData(false);
+        setBufferingPolicy(BufferingPolicy::MakeResourcesPurgeable);
         m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia);
         break;
     case ReasonForSuspension::PageWillBeSuspended:
@@ -5798,8 +5797,6 @@
 
     m_asyncEventQueue.resume();
 
-    setShouldBufferData(true);
-
     if (!m_mediaSession->pageAllowsPlaybackAfterResuming())
         document().addMediaCanStartListener(*this);
     else
@@ -5806,6 +5803,7 @@
         setPausedInternal(false);
 
     m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia);
+    m_mediaSession->updateBufferingPolicy();
 
     if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTaskQueue.hasPendingTask()) {
         // Restart the load if it was aborted in the middle by moving the document to the page cache.
@@ -6705,7 +6703,7 @@
 #endif
 
     m_player = MediaPlayer::create(*this);
-    m_player->setShouldBufferData(m_shouldBufferData);
+    m_player->setBufferingPolicy(m_bufferingPolicy);
     schedulePlaybackControlsManagerUpdate();
 
 #if ENABLE(WEB_AUDIO)
@@ -7882,20 +7880,23 @@
     return true;
 }
 
-void HTMLMediaElement::setShouldBufferData(bool shouldBuffer)
+void HTMLMediaElement::setBufferingPolicy(BufferingPolicy policy)
 {
-    if (shouldBuffer == m_shouldBufferData)
+    if (policy == m_bufferingPolicy)
         return;
 
-    m_shouldBufferData = shouldBuffer;
+    INFO_LOG(LOGIDENTIFIER, policy);
+
+    m_bufferingPolicy = policy;
     if (m_player)
-        m_player->setShouldBufferData(shouldBuffer);
+        m_player->setBufferingPolicy(policy);
 }
 
 void HTMLMediaElement::purgeBufferedDataIfPossible()
 {
-#if PLATFORM(IOS_FAMILY)
-    if (!MemoryPressureHandler::singleton().isUnderMemoryPressure() && m_mediaSession->dataBufferingPermitted())
+    INFO_LOG(LOGIDENTIFIER);
+
+    if (!MemoryPressureHandler::singleton().isUnderMemoryPressure() && m_mediaSession->preferredBufferingPolicy() == BufferingPolicy::Default)
         return;
 
     if (isPlayingToExternalTarget()) {
@@ -7903,13 +7904,7 @@
         return;
     }
 
-    // This is called to relieve memory pressure. Turning off buffering causes the media playback
-    // daemon to release memory associated with queued-up video frames.
-    // We turn it back on right away, but new frames won't get loaded unless playback is resumed.
-    INFO_LOG(LOGIDENTIFIER, "toggling data buffering");
-    setShouldBufferData(false);
-    setShouldBufferData(true);
-#endif
+    setBufferingPolicy(BufferingPolicy::PurgeResources);
 }
 
 bool HTMLMediaElement::canSaveMediaData() const
@@ -8131,6 +8126,11 @@
     m_mediaSession->inActiveDocumentChanged();
 }
 
+HTMLMediaElementEnums::BufferingPolicy HTMLMediaElement::bufferingPolicy() const
+{
+    return m_bufferingPolicy;    
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (245038 => 245039)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -268,13 +268,14 @@
 
     WEBCORE_EXPORT void play() override;
     WEBCORE_EXPORT void pause() override;
-    void setShouldBufferData(bool);
-    WEBCORE_EXPORT bool shouldBufferData() const { return m_shouldBufferData; }
     WEBCORE_EXPORT void fastSeek(double);
     double minFastReverseRate() const;
     double maxFastForwardRate() const;
 
-    void purgeBufferedDataIfPossible();
+    using HTMLMediaElementEnums::BufferingPolicy;
+    void setBufferingPolicy(BufferingPolicy);
+    WEBCORE_EXPORT BufferingPolicy bufferingPolicy() const;
+    WEBCORE_EXPORT void purgeBufferedDataIfPossible();
 
 // captions
     WEBCORE_EXPORT bool webkitHasClosedCaptions() const;
@@ -1072,6 +1073,8 @@
     ScanType m_scanType { Scan };
     ScanDirection m_scanDirection { Forward };
 
+    BufferingPolicy m_bufferingPolicy { BufferingPolicy::Default };
+
     bool m_firstTimePlaying : 1;
     bool m_playing : 1;
     bool m_isWaitingUntilMediaCanStart : 1;
@@ -1099,7 +1102,6 @@
     bool m_completelyLoaded : 1;
     bool m_havePreparedToPlay : 1;
     bool m_parsingInProgress : 1;
-    bool m_shouldBufferData : 1;
     bool m_elementIsHidden : 1;
     bool m_elementWasRemovedFromDOM : 1;
     bool m_creatingControls : 1;

Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (245038 => 245039)


--- trunk/Source/WebCore/html/MediaElementSession.cpp	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp	2019-05-07 22:00:32 UTC (rev 245039)
@@ -216,7 +216,7 @@
     if (m_clientDataBufferingTimer.isActive())
         m_clientDataBufferingTimer.stop();
 
-    m_element.setShouldBufferData(dataBufferingPermitted());
+    m_element.setBufferingPolicy(preferredBufferingPolicy());
 }
 
 void MediaElementSession::addBehaviorRestriction(BehaviorRestrictions restrictions)
@@ -356,29 +356,29 @@
     return true;
 }
 
-bool MediaElementSession::dataBufferingPermitted() const
+MediaPlayer::BufferingPolicy MediaElementSession::preferredBufferingPolicy() const
 {
     if (isSuspended())
-        return false;
+        return MediaPlayer::BufferingPolicy::MakeResourcesPurgeable;
 
     if (bufferingSuspended())
-        return false;
+        return MediaPlayer::BufferingPolicy::LimitReadAhead;
 
     if (state() == PlatformMediaSession::Playing)
-        return true;
+        return MediaPlayer::BufferingPolicy::Default;
 
     if (shouldOverrideBackgroundLoadingRestriction())
-        return true;
+        return MediaPlayer::BufferingPolicy::Default;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     if (m_shouldPlayToPlaybackTarget)
-        return true;
+        return MediaPlayer::BufferingPolicy::Default;
 #endif
 
     if (m_elementIsHiddenUntilVisibleInViewport || m_elementIsHiddenBecauseItWasRemovedFromDOM || m_element.elementIsHidden())
-        return false;
+        return MediaPlayer::BufferingPolicy::MakeResourcesPurgeable;
 
-    return true;
+    return MediaPlayer::BufferingPolicy::Default;
 }
 
 bool MediaElementSession::fullscreenPermitted() const

Modified: trunk/Source/WebCore/html/MediaElementSession.h (245038 => 245039)


--- trunk/Source/WebCore/html/MediaElementSession.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/MediaElementSession.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -73,7 +73,7 @@
     SuccessOr<MediaPlaybackDenialReason> playbackPermitted() const;
     bool autoplayPermitted() const;
     bool dataLoadingPermitted() const;
-    bool dataBufferingPermitted() const;
+    MediaPlayer::BufferingPolicy preferredBufferingPolicy() const;
     bool fullscreenPermitted() const;
     bool pageAllowsDataLoading() const;
     bool pageAllowsPlaybackAfterResuming() const;
@@ -104,6 +104,7 @@
     void suspendBuffering() override;
     void resumeBuffering() override;
     bool bufferingSuspended() const;
+    void updateBufferingPolicy() { scheduleClientDataBufferingCheck(); }
 
     // Restrictions to modify default behaviors.
     enum BehaviorRestrictionFlags : unsigned {

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2019-05-07 22:00:32 UTC (rev 245039)
@@ -563,9 +563,9 @@
     m_private->pause();
 }
 
-void MediaPlayer::setShouldBufferData(bool shouldBuffer)
+void MediaPlayer::setBufferingPolicy(BufferingPolicy policy)
 {
-    m_private->setShouldBufferData(shouldBuffer);
+    m_private->setBufferingPolicy(policy);
 }
 
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
@@ -1640,6 +1640,22 @@
     return values[static_cast<size_t>(enumerationValue)];
 }
 
+String convertEnumerationToString(MediaPlayerEnums::BufferingPolicy enumerationValue)
+{
+    static const NeverDestroyed<String> values[] = {
+        MAKE_STATIC_STRING_IMPL("Default"),
+        MAKE_STATIC_STRING_IMPL("LimitReadAhead"),
+        MAKE_STATIC_STRING_IMPL("MakeResourcesPurgeable"),
+        MAKE_STATIC_STRING_IMPL("PurgeResources"),
+    };
+    static_assert(!static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::Default), "MediaPlayerEnums::Default is not 0 as expected");
+    static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::LimitReadAhead) == 1, "MediaPlayerEnums::LimitReadAhead is not 1 as expected");
+    static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::MakeResourcesPurgeable) == 2, "MediaPlayerEnums::MakeResourcesPurgeable is not 2 as expected");
+    static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::PurgeResources) == 3, "MediaPlayerEnums::PurgeResources is not 3 as expected");
+    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+    return values[static_cast<size_t>(enumerationValue)];
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -312,8 +312,10 @@
     void prepareToPlay();
     void play();
     void pause();
-    void setShouldBufferData(bool);
 
+    using MediaPlayerEnums::BufferingPolicy;
+    void setBufferingPolicy(BufferingPolicy);
+
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
     // Represents synchronous exceptions that can be thrown from the Encrypted Media methods.
     // This is different from the asynchronous MediaKeyError.

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -43,6 +43,13 @@
         VideoFullscreenModePictureInPicture = 1 << 1,
     };
     typedef uint32_t VideoFullscreenMode;
+
+    enum class BufferingPolicy {
+        Default,
+        LimitReadAhead,
+        MakeResourcesPurgeable,
+        PurgeResources,
+    };
 };
 
 WTF::String convertEnumerationToString(MediaPlayerEnums::ReadyState);
@@ -49,6 +56,7 @@
 WTF::String convertEnumerationToString(MediaPlayerEnums::NetworkState);
 WTF::String convertEnumerationToString(MediaPlayerEnums::Preload);
 WTF::String convertEnumerationToString(MediaPlayerEnums::SupportsType);
+WTF::String convertEnumerationToString(MediaPlayerEnums::BufferingPolicy);
 
 } // namespace WebCore
 
@@ -74,4 +82,12 @@
     }
 };
 
+template <>
+struct LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy> {
+    static WTF::String toString(const WebCore::MediaPlayerEnums::BufferingPolicy policy)
+    {
+        return convertEnumerationToString(policy);
+    }
+};
+
 }; // namespace WTF

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -68,7 +68,7 @@
 
     virtual void play() = 0;
     virtual void pause() = 0;    
-    virtual void setShouldBufferData(bool) { }
+    virtual void setBufferingPolicy(MediaPlayer::BufferingPolicy) { }
 
     virtual bool supportsPictureInPicture() const { return false; }
     virtual bool supportsFullscreen() const { return false; }

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -121,7 +121,7 @@
     void canPlayFastReverseDidChange(bool);
     void canPlayFastForwardDidChange(bool);
 
-    void setShouldBufferData(bool) override;
+    void setBufferingPolicy(MediaPlayerEnums::BufferingPolicy) override;
 
 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT)
     void outputMediaDataWillChange(AVPlayerItemVideoOutput*);
@@ -424,11 +424,11 @@
     mutable long long m_cachedTotalBytes;
     unsigned m_pendingStatusChanges;
     int m_cachedItemStatus;
+    MediaPlayer::BufferingPolicy m_bufferingPolicy { MediaPlayer::BufferingPolicy::Default };
     bool m_cachedLikelyToKeepUp;
     bool m_cachedBufferEmpty;
     bool m_cachedBufferFull;
     bool m_cachedHasEnabledAudio;
-    bool m_shouldBufferData;
     bool m_cachedIsReadyForDisplay;
     bool m_haveBeenAskedToCreateLayer;
     bool m_cachedCanPlayFastForward;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2019-05-07 22:00:32 UTC (rev 245039)
@@ -348,7 +348,6 @@
     , m_cachedBufferEmpty(false)
     , m_cachedBufferFull(false)
     , m_cachedHasEnabledAudio(false)
-    , m_shouldBufferData(true)
     , m_cachedIsReadyForDisplay(false)
     , m_haveBeenAskedToCreateLayer(false)
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -379,7 +378,7 @@
 
 void MediaPlayerPrivateAVFoundationObjC::cancelLoad()
 {
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
     tearDownVideoRendering();
 
     [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
@@ -543,7 +542,7 @@
     updateVideoLayerGravity();
     [m_videoLayer setContentsScale:player()->client().mediaPlayerContentsScale()];
     IntSize defaultSize = snappedIntRect(player()->client().mediaPlayerContentBoxRect()).size();
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
 
     m_videoFullscreenLayerManager->setVideoLayer(m_videoLayer.get(), defaultSize);
 
@@ -558,7 +557,7 @@
     if (!m_videoLayer)
         return;
 
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
 
     [m_videoLayer removeObserver:m_objcObserver.get() forKeyPath:@"readyForDisplay"];
     [m_videoLayer setPlayer:nil];
@@ -698,7 +697,7 @@
     if (m_avAsset)
         return;
 
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
 
     setDelayCallbacks(true);
 
@@ -835,7 +834,7 @@
     if (m_avPlayer)
         return;
 
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
 
     setDelayCallbacks(true);
 
@@ -884,7 +883,7 @@
     if (m_avPlayerItem)
         return;
 
-    INFO_LOG(LOGIDENTIFIER);
+    ALWAYS_LOG(LOGIDENTIFIER);
 
     setDelayCallbacks(true);
 
@@ -1112,10 +1111,11 @@
     
 void MediaPlayerPrivateAVFoundationObjC::platformPlay()
 {
-    INFO_LOG(LOGIDENTIFIER);
     if (!metaDataAvailable())
         return;
 
+    ALWAYS_LOG(LOGIDENTIFIER);
+
     m_requestedPlaying = true;
     setPlayerRate(m_requestedRate);
 }
@@ -1122,10 +1122,11 @@
 
 void MediaPlayerPrivateAVFoundationObjC::platformPause()
 {
-    INFO_LOG(LOGIDENTIFIER);
     if (!metaDataAvailable())
         return;
 
+    ALWAYS_LOG(LOGIDENTIFIER);
+
     m_requestedPlaying = false;
     setPlayerRate(0);
 }
@@ -1215,6 +1216,8 @@
     if (!m_avPlayer)
         return;
 
+    ALWAYS_LOG(LOGIDENTIFIER, volume);
+
     [m_avPlayer.get() setVolume:volume];
 #endif
 }
@@ -1224,7 +1227,7 @@
     if (m_muted == muted)
         return;
 
-    INFO_LOG(LOGIDENTIFIER, muted);
+    ALWAYS_LOG(LOGIDENTIFIER, muted);
 
     m_muted = muted;
 
@@ -1241,7 +1244,7 @@
     if (!metaDataAvailable())
         return;
 
-    INFO_LOG(LOGIDENTIFIER, closedCaptionsVisible);
+    ALWAYS_LOG(LOGIDENTIFIER, closedCaptionsVisible);
 }
 
 void MediaPlayerPrivateAVFoundationObjC::setRateDouble(double rate)
@@ -2859,19 +2862,45 @@
     updateStates();
 }
 
-void MediaPlayerPrivateAVFoundationObjC::setShouldBufferData(bool shouldBuffer)
+void MediaPlayerPrivateAVFoundationObjC::setBufferingPolicy(MediaPlayer::BufferingPolicy policy)
 {
-    INFO_LOG(LOGIDENTIFIER, shouldBuffer);
+    ALWAYS_LOG(LOGIDENTIFIER, policy);
 
-    if (m_shouldBufferData == shouldBuffer)
+    if (m_bufferingPolicy == policy)
         return;
 
-    m_shouldBufferData = shouldBuffer;
+    m_bufferingPolicy = policy;
     
     if (!m_avPlayer)
         return;
 
-    setAVPlayerItem(shouldBuffer ? m_avPlayerItem.get() : nil);
+#if HAVE(AVPLAYER_RESOURCE_CONSERVATION_LEVEL)
+    static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::Default) == AVPlayerResourceConservationLevelNone, "MediaPlayer::BufferingPolicy::Default is not AVPlayerResourceConservationLevelNone as expected");
+    static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::LimitReadAhead) == AVPlayerResourceConservationLevelReduceReadAhead, "MediaPlayer::BufferingPolicy::LimitReadAhead is not AVPlayerResourceConservationLevelReduceReadAhead as expected");
+    static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::MakeResourcesPurgeable) == AVPlayerResourceConservationLevelReuseActivePlayerResources, "MediaPlayer::BufferingPolicy::MakeResourcesPurgeable is not AVPlayerResourceConservationLevelReuseActivePlayerResources as expected");
+    static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::PurgeResources) == AVPlayerResourceConservationLevelRecycleBuffer, "MediaPlayer::BufferingPolicy::PurgeResources is not AVPlayerResourceConservationLevelRecycleBuffer as expected");
+
+    if ([m_avPlayer respondsToSelector:@selector(setResourceConservationLevelWhilePaused:)]) {
+        m_avPlayer.get().resourceConservationLevelWhilePaused = static_cast<AVPlayerResourceConservationLevel>(policy);
+        updateStates();
+        return;
+    }
+#endif
+
+    switch (policy) {
+    case MediaPlayer::BufferingPolicy::Default:
+        setAVPlayerItem(m_avPlayerItem.get());
+        break;
+    case MediaPlayer::BufferingPolicy::LimitReadAhead:
+    case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable:
+        setAVPlayerItem(nil);
+        break;
+    case MediaPlayer::BufferingPolicy::PurgeResources:
+        setAVPlayerItem(nil);
+        setAVPlayerItem(m_avPlayerItem.get());
+        break;
+    }
+
     updateStates();
 }
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -154,7 +154,6 @@
     
     void enqueueVideoSample(MediaStreamTrackPrivate&, MediaSample&);
     void enqueueCorrectedVideoSample(MediaSample&);
-    void flushAndRemoveVideoSampleBuffers();
     void requestNotificationWhenReadyForVideoData();
 
     void paint(GraphicsContext&, const FloatRect&) override;
@@ -174,7 +173,7 @@
 
     bool ended() const override { return m_ended; }
 
-    void setShouldBufferData(bool) override;
+    void setBufferingPolicy(MediaPlayer::BufferingPolicy) override;
 
     MediaPlayer::ReadyState currentReadyState();
     void updateReadyState();

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (245038 => 245039)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2019-05-07 22:00:32 UTC (rev 245039)
@@ -457,11 +457,6 @@
         [m_sampleBufferDisplayLayer flush];
 }
 
-void MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers()
-{
-    [m_sampleBufferDisplayLayer flushAndRemoveImage];
-}
-
 void MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers()
 {
     if (m_sampleBufferDisplayLayer)
@@ -1149,10 +1144,10 @@
     m_player->networkStateChanged();
 }
 
-void MediaPlayerPrivateMediaStreamAVFObjC::setShouldBufferData(bool shouldBuffer)
+void MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy(MediaPlayer::BufferingPolicy policy)
 {
-    if (!shouldBuffer)
-        flushAndRemoveVideoSampleBuffers();
+    if (policy != MediaPlayer::BufferingPolicy::Default)
+        [m_sampleBufferDisplayLayer flushAndRemoveImage];
 }
 
 void MediaPlayerPrivateMediaStreamAVFObjC::scheduleDeferredTask(Function<void ()>&& function)

Modified: trunk/Source/WebCore/testing/Internals.cpp (245038 => 245039)


--- trunk/Source/WebCore/testing/Internals.cpp	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.cpp	2019-05-07 22:00:32 UTC (rev 245039)
@@ -3501,9 +3501,25 @@
 
 bool Internals::elementShouldBufferData(HTMLMediaElement& element)
 {
-    return element.shouldBufferData();
+    return element.bufferingPolicy() < MediaPlayer::BufferingPolicy::LimitReadAhead;
 }
 
+String Internals::elementBufferingPolicy(HTMLMediaElement& element)
+{
+    switch (element.bufferingPolicy()) {
+    case MediaPlayer::BufferingPolicy::Default:
+        return "Default";
+    case MediaPlayer::BufferingPolicy::LimitReadAhead:
+        return "LimitReadAhead";
+    case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable:
+        return "MakeResourcesPurgeable";
+    case MediaPlayer::BufferingPolicy::PurgeResources:
+        return "PurgeResources";
+    }
+
+    ASSERT_NOT_REACHED();
+    return "UNKNOWN";
+}
 #endif
 
 bool Internals::isSelectPopupVisible(HTMLSelectElement& element)

Modified: trunk/Source/WebCore/testing/Internals.h (245038 => 245039)


--- trunk/Source/WebCore/testing/Internals.h	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.h	2019-05-07 22:00:32 UTC (rev 245039)
@@ -540,6 +540,7 @@
     void endSimulatedHDCPError(HTMLMediaElement&);
 
     bool elementShouldBufferData(HTMLMediaElement&);
+    String elementBufferingPolicy(HTMLMediaElement&);
 #endif
 
     bool isSelectPopupVisible(HTMLSelectElement&);

Modified: trunk/Source/WebCore/testing/Internals.idl (245038 => 245039)


--- trunk/Source/WebCore/testing/Internals.idl	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.idl	2019-05-07 22:00:32 UTC (rev 245039)
@@ -528,6 +528,7 @@
     [Conditional=VIDEO] void endSimulatedHDCPError(HTMLMediaElement media);
 
     [Conditional=VIDEO] boolean elementShouldBufferData(HTMLMediaElement media);
+    [Conditional=VIDEO] DOMString elementBufferingPolicy(HTMLMediaElement media);
 
     [Conditional=LEGACY_ENCRYPTED_MEDIA] void initializeMockCDM();
     [Conditional=ENCRYPTED_MEDIA] MockCDMFactory registerMockCDM();

Modified: trunk/Tools/ChangeLog (245038 => 245039)


--- trunk/Tools/ChangeLog	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Tools/ChangeLog	2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,16 @@
+2019-05-07  Eric Carlson  <eric.carl...@apple.com>
+
+        Define media buffering policy
+        https://bugs.webkit.org/show_bug.cgi?id=196979
+        <rdar://problem/28383861>
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm: Added.
+        (waitUntilBufferingPolicyIsEqualTo):
+        (TEST):
+
 2019-05-07  Alex Christensen  <achristen...@webkit.org>
 
         Add SPI to set a list of hosts to which to send custom header fields cross-origin

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (245038 => 245039)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-05-07 22:00:32 UTC (rev 245039)
@@ -32,6 +32,7 @@
 		0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */; };
 		0799C34B1EBA3301003B7532 /* disableGetUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */; };
 		07C046CA1E4262A8007201E7 /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07C046C91E42573E007201E7 /* CARingBuffer.cpp */; };
+		07CC7DFE2266330900E39181 /* MediaBufferingPolicy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */; };
 		07CD32F62065B5430064A4BE /* AVFoundationPreference.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */; };
 		07CE1CF31F06A7E000BF89F5 /* GetUserMediaNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */; };
 		07E1F6A21FFC44FA0096C7EC /* getDisplayMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */; };
@@ -1349,6 +1350,7 @@
 		076E507E1F45031E006E9F5A /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logging.cpp; sourceTree = "<group>"; };
 		0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = disableGetUserMedia.html; sourceTree = "<group>"; };
 		07C046C91E42573E007201E7 /* CARingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CARingBuffer.cpp; sourceTree = "<group>"; };
+		07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaBufferingPolicy.mm; sourceTree = "<group>"; };
 		07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationPreference.mm; sourceTree = "<group>"; };
 		07CD32F72065B72A0064A4BE /* video.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = video.html; sourceTree = "<group>"; };
 		07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetUserMediaNavigation.mm; sourceTree = "<group>"; };
@@ -2623,6 +2625,7 @@
 				46C519D81D355A7300DAA51A /* LocalStorageNullEntries.mm */,
 				8C10AF96206467770018FD90 /* LocalStoragePersistence.mm */,
 				7A6A2C6F1DCCF87B00C0D085 /* LocalStorageQuirkTest.mm */,
+				07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */,
 				5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */,
 				51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */,
 				1ABC3DED1899BE6D004F0626 /* Navigation.mm */,
@@ -4236,6 +4239,7 @@
 				7A6A2C701DCCFA8C00C0D085 /* LocalStorageQuirkTest.mm in Sources */,
 				076E507F1F4513D6006E9F5A /* Logging.cpp in Sources */,
 				CE1866491F72E8F100A0CAB6 /* MarkedText.cpp in Sources */,
+				07CC7DFE2266330900E39181 /* MediaBufferingPolicy.mm in Sources */,
 				CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */,
 				CDC9442E1EF1FC080059C3C4 /* MediaStreamTrackDetached.mm in Sources */,
 				7CCE7EB21A411A5100447C4C /* MemoryCacheAddImageToCacheIOS.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm (0 => 245039)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm	2019-05-07 22:00:32 UTC (rev 245039)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if WK_HAVE_C_SPI
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
+
+static void waitUntilBufferingPolicyIsEqualTo(WKWebView* webView, const char* expected)
+{
+    NSString* observed;
+    int tries = 0;
+    do {
+        observed = [webView stringByEvaluatingJavaScript:@"window.internals.elementBufferingPolicy(document.querySelector('video'))"];
+        if ([observed isEqualToString:@(expected)])
+            break;
+
+        TestWebKitAPI::Util::sleep(0.1);
+    } while (++tries <= 100);
+
+    EXPECT_WK_STREQ(expected, observed);
+}
+
+TEST(WebKit, MediaBufferingPolicy)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+    configuration.get().processPool = (WKProcessPool *)context.get();
+    configuration.get()._mediaDataLoadsAutomatically = YES;
+    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+
+    __block bool isPlaying = false;
+    [webView performAfterReceivingMessage:@"playing" action:^() { isPlaying = true; }];
+
+    [webView synchronouslyLoadTestPageNamed:@"video-with-audio"];
+    TestWebKitAPI::Util::run(&isPlaying);
+
+    waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default");
+
+    [webView stringByEvaluatingJavaScript:@"document.querySelector('video').pause()"];
+
+    // Suspending the process also forces a memory warning, which should purge whatever possible ASAP.
+    [webView _processWillSuspendImminentlyForTesting];
+    waitUntilBufferingPolicyIsEqualTo(webView.get(), "PurgeResources");
+
+    // And should switch back to default when buffering is allowed.
+    [webView _processDidResumeForTesting];
+    waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default");
+
+    // All resources should be marked as purgeable when the document is hidden.
+#if PLATFORM(MAC)
+    [webView.get().window setIsVisible:NO];
+#else
+    webView.get().window.hidden = YES;
+#endif
+    waitUntilBufferingPolicyIsEqualTo(webView.get(), "MakeResourcesPurgeable");
+
+#if PLATFORM(MAC)
+    [webView.get().window setIsVisible:YES];
+#else
+    webView.get().window.hidden = NO;
+#endif
+
+    // Policy should go back to default when playback starts.
+    isPlaying = false;
+    [webView stringByEvaluatingJavaScript:@"go()"];
+    TestWebKitAPI::Util::run(&isPlaying);
+
+    waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default");
+}
+
+#endif // WK_HAVE_C_SPI
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to