Allow clients to override their own hardware media requirements where no fallback...
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jul 2017 22:04:20 +0000 (22:04 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jul 2017 22:04:20 +0000 (22:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174426
<rdar://problem/32537704>

Reviewed by Eric Carlson.

Source/WebCore:

Add a new setting which allows clients to specify their own mediaContentTypesRequiringHardwareSupport should be
ignared in the case where no fallback exists, such as the case of a single <source> element, or setting the src
attribute directly.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::havePotentialSourceChild):
(WebCore::HTMLMediaElement::selectNextSourceChild):
(WebCore::HTMLMediaElement::sourceWasAdded):
(WebCore::HTMLMediaElement::sourceWasRemoved):
(WebCore::HTMLMediaElement::mediaPlayerShouldCheckHardwareSupport):
* html/HTMLMediaElement.h:
* page/Settings.h:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::shouldCheckHardwareSupport):
* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerShouldCheckHardwareSupport):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::assetStatus):
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
(WebCore::SourceBufferPrivateAVFObjC::didParseStreamDataAsAsset):

Source/WebKit:

Add a new WKWebViewConfiguration property, as well as a new WKPreferences function, both to control
WebCore's new allowMediaContentTypesRequiringHardwareSupportAsFallback setting.

* Shared/WebPreferencesDefinitions.h:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesGetAllowMediaContentTypesRequiringHardwareSupportAsFallback):
(WKPreferencesSetAllowMediaContentTypesRequiringHardwareSupportAsFallback):
* UIProcess/API/C/WKPreferencesRef.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _setAllowMediaContentTypesRequiringHardwareSupportAsFallback:]):
(-[WKWebViewConfiguration _allowMediaContentTypesRequiringHardwareSupportAsFallback]):
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):

Source/WebKitLegacy/mac:

Add a new WebPreferences property to control WebCore's new
allowMediaContentTypesRequiringHardwareSupportAsFallback setting.

* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences allowMediaContentTypesRequiringHardwareSupportAsFallback]):
(-[WebPreferences setAllowMediaContentTypesRequiringHardwareSupportAsFallback:]):
* WebView/WebPreferencesPrivate.h:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

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

23 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/page/Settings.in
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferencesDefinitions.h
Source/WebKit/UIProcess/API/C/WKPreferences.cpp
Source/WebKit/UIProcess/API/C/WKPreferencesRef.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKitLegacy/mac/WebView/WebPreferences.mm
Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
Source/WebKitLegacy/mac/WebView/WebView.mm

index 77a920b..9380eff 100644 (file)
@@ -1,3 +1,32 @@
+2017-07-14  Jer Noble  <jer.noble@apple.com>
+
+        Allow clients to override their own hardware media requirements where no fallback media exists.
+        https://bugs.webkit.org/show_bug.cgi?id=174426
+        <rdar://problem/32537704>
+
+        Reviewed by Eric Carlson.
+
+        Add a new setting which allows clients to specify their own mediaContentTypesRequiringHardwareSupport should be
+        ignared in the case where no fallback exists, such as the case of a single <source> element, or setting the src
+        attribute directly.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::havePotentialSourceChild):
+        (WebCore::HTMLMediaElement::selectNextSourceChild):
+        (WebCore::HTMLMediaElement::sourceWasAdded):
+        (WebCore::HTMLMediaElement::sourceWasRemoved):
+        (WebCore::HTMLMediaElement::mediaPlayerShouldCheckHardwareSupport):
+        * html/HTMLMediaElement.h:
+        * page/Settings.h:
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::shouldCheckHardwareSupport):
+        * platform/graphics/MediaPlayer.h:
+        (WebCore::MediaPlayerClient::mediaPlayerShouldCheckHardwareSupport):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::assetStatus):
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+        (WebCore::SourceBufferPrivateAVFObjC::didParseStreamDataAsAsset):
+
 2017-07-14  Chris Dumez  <cdumez@apple.com>
 
         Possible crash under NetworkSocketStream::didFailSocketStream()
index 267473f..afcd70b 100644 (file)
@@ -43,7 +43,7 @@
 #include "DiagnosticLoggingKeys.h"
 #include "Document.h"
 #include "DocumentLoader.h"
-#include "ElementIterator.h"
+#include "ElementChildIterator.h"
 #include "EventNames.h"
 #include "FrameLoader.h"
 #include "FrameLoaderClient.h"
@@ -4222,7 +4222,7 @@ bool HTMLMediaElement::havePotentialSourceChild()
     // Stash the current <source> node and next nodes so we can restore them after checking
     // to see there is another potential.
     RefPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
-    RefPtr<Node> nextNode = m_nextChildNodeToConsider;
+    RefPtr<HTMLSourceElement> nextNode = m_nextChildNodeToConsider;
 
     URL nextURL = selectNextSourceChild(0, 0, DoNothing);
 
@@ -4250,31 +4250,21 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
         return URL();
     }
 
-    URL mediaURL;
-    HTMLSourceElement* source = nullptr;
-    String type;
-    bool lookingForStartNode = m_nextChildNodeToConsider;
-    bool canUseSourceElement = false;
-    bool okToLoadSourceURL;
+    // Because the DOM may be mutated in the course of the following algorithm,
+    // keep strong references to each of the child source nodes, and verify that
+    // each still is a child of this media element before using.
+    Vector<Ref<HTMLSourceElement>> potentialSourceNodes;
+    auto sources = childrenOfType<HTMLSourceElement>(*this);
+    for (auto next = m_nextChildNodeToConsider ? sources.beginAt(*m_nextChildNodeToConsider) : sources.begin(), end = sources.end(); next != end; ++next)
+        potentialSourceNodes.append(*next);
 
-    NodeVector potentialSourceNodes;
-    getChildNodes(*this, potentialSourceNodes);
-
-    for (unsigned i = 0; !canUseSourceElement && i < potentialSourceNodes.size(); ++i) {
-        Node& node = potentialSourceNodes[i].get();
-        if (lookingForStartNode && m_nextChildNodeToConsider != &node)
-            continue;
-        lookingForStartNode = false;
-
-        if (!node.hasTagName(sourceTag))
+    for (auto& source : potentialSourceNodes) {
+        if (source->parentNode() != this)
             continue;
-        if (node.parentNode() != this)
-            continue;
-
-        source = downcast<HTMLSourceElement>(&node);
 
         // If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
-        mediaURL = source->getNonEmptyURLAttribute(srcAttr);
+        auto mediaURL = source->getNonEmptyURLAttribute(srcAttr);
+        String type;
 #if !LOG_DISABLED
         if (shouldLog)
             LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'src' is %s", this, urlForLoggingMedia(mediaURL).utf8().data());
@@ -4309,48 +4299,49 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
 #if ENABLE(MEDIA_STREAM)
             parameters.isMediaStream = mediaURL.protocolIs(mediaStreamBlobProtocol);
 #endif
-            parameters.contentTypesRequiringHardwareSupport = mediaContentTypesRequiringHardwareSupport();
+            if (!document().settings().allowMediaContentTypesRequiringHardwareSupportAsFallback() || Traversal<HTMLSourceElement>::nextSkippingChildren(source))
+                parameters.contentTypesRequiringHardwareSupport = mediaContentTypesRequiringHardwareSupport();
 
             if (!MediaPlayer::supportsType(parameters, this))
                 goto CheckAgain;
         }
 
         // Is it safe to load this url?
-        okToLoadSourceURL = isSafeToLoadURL(mediaURL, actionIfInvalid) && dispatchBeforeLoadEvent(mediaURL.string());
+        if (!isSafeToLoadURL(mediaURL, actionIfInvalid) || !dispatchBeforeLoadEvent(mediaURL.string()))
+            goto CheckAgain;
 
         // A 'beforeload' event handler can mutate the DOM, so check to see if the source element is still a child node.
-        if (node.parentNode() != this) {
+        if (source->parentNode() != this) {
             LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'beforeload' removed current element", this);
-            source = nullptr;
-            goto CheckAgain;
+            continue;
         }
 
-        if (!okToLoadSourceURL)
-            goto CheckAgain;
-
         // Making it this far means the <source> looks reasonable.
-        canUseSourceElement = true;
+        if (contentType)
+            *contentType = ContentType(type);
+        m_nextChildNodeToConsider = Traversal<HTMLSourceElement>::nextSkippingChildren(source);
+        m_currentSourceNode = WTFMove(source);
+
+#if !LOG_DISABLED
+        if (shouldLog)
+            LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) -> %p, %s", this, m_currentSourceNode.get(), urlForLoggingMedia(mediaURL).utf8().data());
+#endif
+
+        return mediaURL;
 
 CheckAgain:
-        if (!canUseSourceElement && actionIfInvalid == Complain && source)
+        if (actionIfInvalid == Complain)
             source->scheduleErrorEvent();
     }
 
-    if (canUseSourceElement) {
-        if (contentType)
-            *contentType = ContentType(type);
-        m_currentSourceNode = source;
-        m_nextChildNodeToConsider = source->nextSibling();
-    } else {
-        m_currentSourceNode = nullptr;
-        m_nextChildNodeToConsider = nullptr;
-    }
+    m_currentSourceNode = nullptr;
+    m_nextChildNodeToConsider = nullptr;
 
 #if !LOG_DISABLED
     if (shouldLog)
-        LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) -> %p, %s", this, m_currentSourceNode.get(), canUseSourceElement ? urlForLoggingMedia(mediaURL).utf8().data() : "");
+        LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) -> %p, failed", this, m_currentSourceNode.get());
 #endif
-    return canUseSourceElement ? mediaURL : URL();
+    return URL();
 }
 
 void HTMLMediaElement::sourceWasAdded(HTMLSourceElement& source)
@@ -4380,7 +4371,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement& source)
         return;
     }
 
-    if (m_currentSourceNode && &source == m_currentSourceNode->nextSibling()) {
+    if (m_currentSourceNode && &source == Traversal<HTMLSourceElement>::nextSibling(*m_currentSourceNode)) {
         LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this);
         m_nextChildNodeToConsider = &source;
         return;
@@ -4419,8 +4410,7 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement& source)
         return;
 
     if (&source == m_nextChildNodeToConsider) {
-        if (m_currentSourceNode)
-            m_nextChildNodeToConsider = m_currentSourceNode->nextSibling();
+        m_nextChildNodeToConsider = m_currentSourceNode ? Traversal<HTMLSourceElement>::nextSibling(*m_currentSourceNode) : nullptr;
         LOG(Media, "HTMLMediaElement::sourceRemoved(%p) - m_nextChildNodeToConsider set to %p", this, m_nextChildNodeToConsider.get());
     } else if (&source == m_currentSourceNode) {
         // Clear the current source node pointer, but don't change the movie as the spec says:
@@ -6676,6 +6666,20 @@ const Vector<ContentType>& HTMLMediaElement::mediaContentTypesRequiringHardwareS
     return document().settings().mediaContentTypesRequiringHardwareSupport();
 }
 
+bool HTMLMediaElement::mediaPlayerShouldCheckHardwareSupport() const
+{
+    if (!document().settings().allowMediaContentTypesRequiringHardwareSupportAsFallback())
+        return true;
+
+    if (m_loadState == LoadingFromSourceElement && m_currentSourceNode && !m_nextChildNodeToConsider)
+        return false;
+
+    if (m_loadState == LoadingFromSrcAttr)
+        return false;
+
+    return true;
+}
+
 #if USE(GSTREAMER)
 void HTMLMediaElement::requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback)
 {
index 8c56b22..af0206e 100644 (file)
@@ -684,6 +684,7 @@ private:
     double mediaPlayerRequestedPlaybackRate() const final;
     VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
     bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep() == SleepType::Display; }
+    bool mediaPlayerShouldCheckHardwareSupport() const final;
     const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const final;
 
 #if USE(GSTREAMER)
@@ -931,7 +932,7 @@ private:
     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
     LoadState m_loadState { WaitingForSource };
     RefPtr<HTMLSourceElement> m_currentSourceNode;
-    RefPtr<Node> m_nextChildNodeToConsider;
+    RefPtr<HTMLSourceElement> m_nextChildNodeToConsider;
 
     VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone };
     bool m_preparedForInline;
index 99ab2bc..6ea25fb 100644 (file)
@@ -297,3 +297,5 @@ subresourceIntegrityEnabled initial=true
 constantPropertiesEnabled initial=false
 
 viewportFitEnabled initial=false
+
+allowMediaContentTypesRequiringHardwareSupportAsFallback initial=false
index 3c9d77b..6a20653 100644 (file)
@@ -1482,6 +1482,11 @@ const Vector<ContentType>& MediaPlayer::mediaContentTypesRequiringHardwareSuppor
     return client().mediaContentTypesRequiringHardwareSupport();
 }
 
+bool MediaPlayer::shouldCheckHardwareSupport() const
+{
+    return client().mediaPlayerShouldCheckHardwareSupport();
+}
+
 }
 
 #endif
index 92f2485..fcfd062 100644 (file)
@@ -276,6 +276,7 @@ public:
 
     virtual bool mediaPlayerShouldDisableSleep() const { return false; }
     virtual const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const;
+    virtual bool mediaPlayerShouldCheckHardwareSupport() const { return false; }
 };
 
 class MediaPlayerSupportsTypeClient {
@@ -594,6 +595,7 @@ public:
     bool contentMIMETypeWasInferredFromExtension() const { return m_contentMIMETypeWasInferredFromExtension; }
 
     const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const;
+    bool shouldCheckHardwareSupport() const;
 
 private:
     MediaPlayer(MediaPlayerClient&);
index f79efd5..c9fef84 100644 (file)
@@ -1609,6 +1609,9 @@ MediaPlayerPrivateAVFoundation::AssetStatus MediaPlayerPrivateAVFoundationObjC::
             return MediaPlayerAVAssetStatusCancelled; // Loading of at least one key was cancelled.
     }
 
+    if (!player()->shouldCheckHardwareSupport())
+        m_tracksArePlayable = true;
+
     if (!m_tracksArePlayable) {
         m_tracksArePlayable = true;
         for (AVAssetTrack *track in [m_avAsset tracks]) {
index aeed1cd..5e4819c 100644 (file)
@@ -120,6 +120,7 @@ public:
 #endif
 
     const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const;
+    bool shouldCheckHardwareSupport() const;
 
     WeakPtr<MediaPlayerPrivateMediaSourceAVFObjC> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
 
index cca3c25..6d2136d 100644 (file)
@@ -961,6 +961,11 @@ const Vector<ContentType>& MediaPlayerPrivateMediaSourceAVFObjC::mediaContentTyp
     return m_player->mediaContentTypesRequiringHardwareSupport();
 }
 
+bool MediaPlayerPrivateMediaSourceAVFObjC::shouldCheckHardwareSupport() const
+{
+    return m_player->shouldCheckHardwareSupport();
+}
+
 void MediaPlayerPrivateMediaSourceAVFObjC::setReadyState(MediaPlayer::ReadyState readyState)
 {
     if (m_readyState == readyState)
index cada58e..254f847 100644 (file)
@@ -485,10 +485,12 @@ void SourceBufferPrivateAVFObjC::didParseStreamDataAsAsset(AVAsset* asset)
     if (!m_mediaSource)
         return;
 
-    for (AVAssetTrack *track in [asset tracks]) {
-        if (!assetTrackMeetsHardwareDecodeRequirements(track, m_mediaSource->player()->mediaContentTypesRequiringHardwareSupport())) {
-            m_parsingSucceeded = false;
-            return;
+    if (m_mediaSource->player()->shouldCheckHardwareSupport()) {
+        for (AVAssetTrack *track in [asset tracks]) {
+            if (!assetTrackMeetsHardwareDecodeRequirements(track, m_mediaSource->player()->mediaContentTypesRequiringHardwareSupport())) {
+                m_parsingSucceeded = false;
+                return;
+            }
         }
     }
 
index 925405a..c88d5fc 100644 (file)
@@ -1,3 +1,30 @@
+2017-07-14  Jer Noble  <jer.noble@apple.com>
+
+        Allow clients to override their own hardware media requirements where no fallback media exists.
+        https://bugs.webkit.org/show_bug.cgi?id=174426
+        <rdar://problem/32537704>
+
+        Reviewed by Eric Carlson.
+
+        Add a new WKWebViewConfiguration property, as well as a new WKPreferences function, both to control
+        WebCore's new allowMediaContentTypesRequiringHardwareSupportAsFallback setting.
+
+        * Shared/WebPreferencesDefinitions.h:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesGetAllowMediaContentTypesRequiringHardwareSupportAsFallback):
+        (WKPreferencesSetAllowMediaContentTypesRequiringHardwareSupportAsFallback):
+        * UIProcess/API/C/WKPreferencesRef.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]):
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration init]):
+        (-[WKWebViewConfiguration copyWithZone:]):
+        (-[WKWebViewConfiguration _setAllowMediaContentTypesRequiringHardwareSupportAsFallback:]):
+        (-[WKWebViewConfiguration _allowMediaContentTypesRequiringHardwareSupportAsFallback]):
+        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
 2017-07-14  Chris Dumez  <cdumez@apple.com>
 
         Possible crash under NetworkSocketStream::didFailSocketStream()
index 062c678..1a36962 100644 (file)
 #define DEFAULT_LEGACY_ENCRYPTED_MEDIA_API_ENABLED true
 #endif
 
+#if PLATFORM(COCOA)
+#define DEFAULT_ALLOW_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT_AS_FALLBACK true
+#else
+#define DEFAULT_ALLOW_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT_AS_FALLBACK false
+#endif
+
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
 #define DEFAULT_SUBPIXEL_ANTIALIASED_LAYER_TEXT_ENABLED true
 #else
     macro(ResourceTimingEnabled, resourceTimingEnabled, Bool, bool, DEFAULT_RESOURCE_TIMING_ENABLED, "Resource Timing", "Enable ResourceTiming API") \
     macro(UserTimingEnabled, userTimingEnabled, Bool, bool, true, "User Timing", "Enable UserTiming API") \
     macro(LegacyEncryptedMediaAPIEnabled, legacyEncryptedMediaAPIEnabled, Bool, bool, DEFAULT_LEGACY_ENCRYPTED_MEDIA_API_ENABLED, "Enable Legacy EME API", "Enable legacy EME API") \
+    macro(AllowMediaContentTypesRequiringHardwareSupportAsFallback, allowMediaContentTypesRequiringHardwareSupportAsFallback, Bool, bool, DEFAULT_ALLOW_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT_AS_FALLBACK, "Allow Media Content Types Requirining Hardware As Fallback", "Allow Media Content Types Requirining Hardware As Fallback") \
     \
 
 #define FOR_EACH_WEBKIT_DOUBLE_PREFERENCE(macro) \
index bfa9eb6..4e94365 100644 (file)
@@ -1802,3 +1802,14 @@ void WKPreferencesSetLegacyEncryptedMediaAPIEnabled(WKPreferencesRef preferences
 {
     return toImpl(preferencesRef)->setLegacyEncryptedMediaAPIEnabled(enabled);
 }
+
+bool WKPreferencesGetAllowMediaContentTypesRequiringHardwareSupportAsFallback(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->allowMediaContentTypesRequiringHardwareSupportAsFallback();
+}
+
+void WKPreferencesSetAllowMediaContentTypesRequiringHardwareSupportAsFallback(WKPreferencesRef preferencesRef, bool allow)
+{
+    return toImpl(preferencesRef)->setAllowMediaContentTypesRequiringHardwareSupportAsFallback(allow);
+}
+
index 1abce8d..9523f59 100644 (file)
@@ -300,6 +300,10 @@ WK_EXPORT void WKPreferencesSetApplePayCapabilityDisclosureAllowed(WKPreferences
 WK_EXPORT bool WKPreferencesGetLegacyEncryptedMediaAPIEnabled(WKPreferencesRef preferencesRef);
 WK_EXPORT void WKPreferencesSetLegacyEncryptedMediaAPIEnabled(WKPreferencesRef preferencesRef, bool enabled);
 
+// Defaults to true.
+WK_EXPORT bool WKPreferencesGetAllowMediaContentTypesRequiringHardwareSupportAsFallback(WKPreferencesRef preferencesRef);
+WK_EXPORT void WKPreferencesSetAllowMediaContentTypesRequiringHardwareSupportAsFallback(WKPreferencesRef preferencesRef, bool allow);
+
 #ifdef __cplusplus
 }
 #endif
index 3221d75..3be40d7 100644 (file)
@@ -512,6 +512,7 @@ static uint32_t convertSystemLayoutDirection(NSUserInterfaceLayoutDirection dire
 
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::needsStorageAccessFromFileURLsQuirkKey(), WebKit::WebPreferencesStore::Value(!![_configuration _needsStorageAccessFromFileURLsQuirk]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::mediaContentTypesRequiringHardwareSupportKey(), WebKit::WebPreferencesStore::Value(String([_configuration _mediaContentTypesRequiringHardwareSupport])));
+    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowMediaContentTypesRequiringHardwareSupportAsFallbackKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowMediaContentTypesRequiringHardwareSupportAsFallback]));
 
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::legacyEncryptedMediaAPIEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _legacyEncryptedMediaAPIEnabled]));
index fbf4a66..de9cdf1 100644 (file)
@@ -151,6 +151,7 @@ static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
 #endif
     BOOL _needsStorageAccessFromFileURLsQuirk;
     BOOL _legacyEncryptedMediaAPIEnabled;
+    BOOL _allowMediaContentTypesRequiringHardwareSupportAsFallback;
 
     RetainPtr<NSString> _overrideContentSecurityPolicy;
     RetainPtr<NSString> _mediaContentTypesRequiringHardwareSupport;
@@ -220,6 +221,7 @@ static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
 #endif
 
     _mediaContentTypesRequiringHardwareSupport = Settings::defaultMediaContentTypesRequiringHardwareSupport();
+    _allowMediaContentTypesRequiringHardwareSupportAsFallback = YES;
 
     return self;
 }
@@ -357,6 +359,7 @@ static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
     configuration->_urlSchemeHandlers.set(adoptNS([self._urlSchemeHandlers mutableCopyWithZone:zone]));
     configuration->_mediaContentTypesRequiringHardwareSupport = adoptNS([self._mediaContentTypesRequiringHardwareSupport copyWithZone:zone]);
     configuration->_legacyEncryptedMediaAPIEnabled = self->_legacyEncryptedMediaAPIEnabled;
+    configuration->_allowMediaContentTypesRequiringHardwareSupportAsFallback = self->_allowMediaContentTypesRequiringHardwareSupportAsFallback;
 
     return configuration;
 }
@@ -873,6 +876,16 @@ static NSString *defaultApplicationNameForUserAgent()
     return _legacyEncryptedMediaAPIEnabled;
 }
 
+- (void)_setAllowMediaContentTypesRequiringHardwareSupportAsFallback:(BOOL)allow
+{
+    _allowMediaContentTypesRequiringHardwareSupportAsFallback = allow;
+}
+
+- (BOOL)_allowMediaContentTypesRequiringHardwareSupportAsFallback
+{
+    return _allowMediaContentTypesRequiringHardwareSupportAsFallback;
+}
+
 @end
 
 @implementation WKWebViewConfiguration (WKDeprecated)
index 08892b8..780cda8 100644 (file)
@@ -87,6 +87,7 @@ typedef NS_ENUM(NSUInteger, _WKDragLiftDelay) {
 @property (nonatomic, setter=_setOverrideContentSecurityPolicy:) NSString *_overrideContentSecurityPolicy WK_API_AVAILABLE(macosx(10.12.3), ios(10.3));
 @property (nonatomic, setter=_setMediaContentTypesRequiringHardwareSupport:) NSString *_mediaContentTypesRequiringHardwareSupport WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setLegacyEncryptedMediaAPIEnabled:) BOOL _legacyEncryptedMediaAPIEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setAllowMediaContentTypesRequiringHardwareSupportAsFallback:) BOOL _allowMediaContentTypesRequiringHardwareSupportAsFallback WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
 
index 0859f66..32d866f 100644 (file)
@@ -3375,6 +3375,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
     settings.setAnimatedImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::animatedImageAsyncDecodingEnabledKey()));
     settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(store.getBoolValueForKey(WebPreferencesKey::shouldSuppressKeyboardInputDuringProvisionalNavigationKey()));
     settings.setMediaContentTypesRequiringHardwareSupport(store.getStringValueForKey(WebPreferencesKey::mediaContentTypesRequiringHardwareSupportKey()));
+    settings.setAllowMediaContentTypesRequiringHardwareSupportAsFallback(store.getBoolValueForKey(WebPreferencesKey::allowMediaContentTypesRequiringHardwareSupportAsFallbackKey()));
 
     settings.setMediaDocumentEntersFullscreenAutomatically(store.getBoolValueForKey(WebPreferencesKey::mediaDocumentEntersFullscreenAutomaticallyKey()));
 
index 5b8ec21..0d450c9 100644 (file)
@@ -1,3 +1,23 @@
+2017-07-14  Jer Noble  <jer.noble@apple.com>
+
+        Allow clients to override their own hardware media requirements where no fallback media exists.
+        https://bugs.webkit.org/show_bug.cgi?id=174426
+        <rdar://problem/32537704>
+
+        Reviewed by Eric Carlson.
+
+        Add a new WebPreferences property to control WebCore's new
+        allowMediaContentTypesRequiringHardwareSupportAsFallback setting.
+
+        * WebView/WebPreferenceKeysPrivate.h:
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]):
+        (-[WebPreferences allowMediaContentTypesRequiringHardwareSupportAsFallback]):
+        (-[WebPreferences setAllowMediaContentTypesRequiringHardwareSupportAsFallback:]):
+        * WebView/WebPreferencesPrivate.h:
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2017-07-12  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         Async image decoding for large images should be disabled by default
index 3fe25ec..5d31417 100644 (file)
 #define WebKitResourceTimingEnabledPreferenceKey @"WebKitResourceTimingEnabled"
 #define WebKitMediaContentTypesRequiringHardwareSupportPreferenceKey @"WebKitMediaContentTypesRequiringHardwareSupport"
 #define WebKitLegacyEncryptedMediaAPIEnabledKey @"WebKitLegacyEncryptedMediaAPIEnabled"
+#define WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey @"WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallback"
index d738366..cff7043 100644 (file)
@@ -677,6 +677,7 @@ public:
 #endif
         @YES, WebKitViewportFitEnabledPreferenceKey,
         @YES, WebKitConstantPropertiesEnabledPreferenceKey,
+        @YES, WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey,
         (NSString *)Settings::defaultMediaContentTypesRequiringHardwareSupport(), WebKitMediaContentTypesRequiringHardwareSupportPreferenceKey,
         nil];
 
@@ -3174,6 +3175,16 @@ static NSString *classIBCreatorID = nil;
     [self _setBoolValue:flag forKey:WebKitConstantPropertiesEnabledPreferenceKey];
 }
 
+- (BOOL)allowMediaContentTypesRequiringHardwareSupportAsFallback
+{
+    return [self _boolValueForKey:WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey];
+}
+
+- (void)setAllowMediaContentTypesRequiringHardwareSupportAsFallback:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey];
+}
+
 @end
 
 @implementation WebPreferences (WebInternal)
index e8f4783..86275af 100644 (file)
@@ -580,6 +580,7 @@ extern NSString *WebPreferencesCacheModelChangedInternalNotification;
 @property (nonatomic) BOOL legacyEncryptedMediaAPIEnabled;
 @property (nonatomic) BOOL viewportFitEnabled;
 @property (nonatomic) BOOL constantPropertiesEnabled;
+@property (nonatomic) BOOL allowMediaContentTypesRequiringHardwareSupportAsFallback;
 
 #if TARGET_OS_IPHONE
 @property (nonatomic) BOOL quickLookDocumentSavingEnabled;
index 4a170a3..b188706 100644 (file)
@@ -3038,6 +3038,8 @@ static bool needsSelfRetainWhileLoadingQuirk()
     RuntimeEnabledFeatures::sharedFeatures().setLegacyEncryptedMediaAPIEnabled(preferences.legacyEncryptedMediaAPIEnabled);
 #endif
 
+    settings.setAllowMediaContentTypesRequiringHardwareSupportAsFallback(preferences.allowMediaContentTypesRequiringHardwareSupportAsFallback);
+
     NSTimeInterval timeout = [preferences incrementalRenderingSuppressionTimeoutInSeconds];
     if (timeout > 0)
         settings.setIncrementalRenderingSuppressionTimeoutInSeconds(timeout);