Make AVFoundationEnabled preference available on iOS
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Mar 2018 11:39:53 +0000 (11:39 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Mar 2018 11:39:53 +0000 (11:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183876
<rdar://problem/38726459>

Reviewed by Youenn Fablet.

Source/WebCore:

Test: AVFoundationPref API test.

* html/HTMLAudioElement.idl: There is no need for a runtime setting to enable/disable audio,
there is already settings.mediaEnabled.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::prepareForLoad): Fail if there are no media engines registered.
(WebCore::HTMLMediaElement::noneSupported): Return early if m_error has already been set.
(WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Remove a typo.

* page/RuntimeEnabledFeatures.cpp:
(WebCore::RuntimeEnabledFeatures::audioEnabled const): Deleted.
* page/RuntimeEnabledFeatures.h:

Source/WebKit:

* Shared/WebPreferences.yaml: Set AVFoundationEnabled with DEFAULT_AVFOUNDATION_ENABLED.
* Shared/WebPreferencesDefaultValues.h:

* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _setAVFoundationEnabled:]): Enable for iOS.
(-[WKPreferences _avFoundationEnabled]): Ditto.
* UIProcess/API/Cocoa/WKPreferencesPrivate.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/video.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/AVFoundationPreference.mm: Added.
(-[PreferenceTestMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::AVFoundationPref::SetUp):
(TestWebKitAPI::AVFoundationPref::testWithPreference):
(TestWebKitAPI::TEST_F):

LayoutTests:

* media/media-error-fired-once-expected.txt: Added.
* media/media-error-fired-once.html: Added.

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

17 files changed:
LayoutTests/ChangeLog
LayoutTests/media/media-error-fired-once-expected.txt [new file with mode: 0644]
LayoutTests/media/media-error-fired-once.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLAudioElement.idl
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/page/RuntimeEnabledFeatures.cpp
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/Shared/WebPreferencesDefaultValues.h
Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm
Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit/video.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/AVFoundationPreference.mm [new file with mode: 0644]

index c5aaf7e..fb7dcbb 100644 (file)
@@ -1,3 +1,14 @@
+2018-03-27  Eric Carlson  <eric.carlson@apple.com>
+
+        Make AVFoundationEnabled preference available on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=183876
+        <rdar://problem/38726459>
+
+        Reviewed by Youenn Fablet.
+
+        * media/media-error-fired-once-expected.txt: Added.
+        * media/media-error-fired-once.html: Added.
+
 2018-03-27  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [GTK] Layout test editing/deleting/delete-surrogatepair.html crashing with CRITICAL **: enchant_dict_check: assertion 'g_utf8_validate(word, len, NULL)' failed
diff --git a/LayoutTests/media/media-error-fired-once-expected.txt b/LayoutTests/media/media-error-fired-once-expected.txt
new file mode 100644 (file)
index 0000000..96bb8a6
--- /dev/null
@@ -0,0 +1,4 @@
+RUN(video = document.createElement("video"))
+RUN(video.src = "content/does-not-exist.mpeg")
+END OF TEST
+
diff --git a/LayoutTests/media/media-error-fired-once.html b/LayoutTests/media/media-error-fired-once.html
new file mode 100644 (file)
index 0000000..e2bc8a9
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>error-event-only-fired-once</title>
+    <script src=video-test.js></script>
+    <script>
+        window.addEventListener('load', event => {
+        
+            run('video = document.createElement("video")');
+            video.controls = 1;
+
+            video.onerror = (event) => {
+
+                video.onerror = (event) => {
+                    failTest("'error' event fired twice.");
+                }
+
+                setTimeout(() => {
+                    endTest();
+                }, 200);
+
+                document.body.appendChild(video);
+            };
+
+            run('video.src = "content/does-not-exist.mpeg"');
+        });
+
+    </script>
+</head>
+<body>
+</body>
+</html>
+
+
index 5a9994a..d9888b3 100644 (file)
@@ -1,3 +1,24 @@
+2018-03-27  Eric Carlson  <eric.carlson@apple.com>
+
+        Make AVFoundationEnabled preference available on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=183876
+        <rdar://problem/38726459>
+
+        Reviewed by Youenn Fablet.
+
+        Test: AVFoundationPref API test.
+
+        * html/HTMLAudioElement.idl: There is no need for a runtime setting to enable/disable audio,
+        there is already settings.mediaEnabled.
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::prepareForLoad): Fail if there are no media engines registered.
+        (WebCore::HTMLMediaElement::noneSupported): Return early if m_error has already been set.
+        (WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Remove a typo.
+
+        * page/RuntimeEnabledFeatures.cpp:
+        (WebCore::RuntimeEnabledFeatures::audioEnabled const): Deleted.
+        * page/RuntimeEnabledFeatures.h:
+
 2018-03-27  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [GTK] Layout test editing/deleting/delete-surrogatepair.html crashing with CRITICAL **: enchant_dict_check: assertion 'g_utf8_validate(word, len, NULL)' failed
index e37706a..e112b6a 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 [
-    EnabledAtRuntime=Audio,
     Conditional=VIDEO,
     ConstructorCallWith=Document,
     NamedConstructor=Audio(optional [AtomicString] DOMString src)
index 7f9feb1..a0a0925 100644 (file)
@@ -1337,11 +1337,15 @@ void HTMLMediaElement::prepareForLoad()
     m_autoplaying = true;
     mediaSession().clientWillBeginAutoplaying();
 
-    // 9 - Invoke the media element's resource selection algorithm.
-    // Note, unless the restriction on requiring user action has been removed,
-    // do not begin downloading data.
-    if (m_mediaSession->dataLoadingPermitted(*this))
-        selectMediaResource();
+    if (!MediaPlayer::isAvailable())
+        noneSupported();
+    else {
+        // 9 - Invoke the media element's resource selection algorithm.
+        // Note, unless the restriction on requiring user action has been removed,
+        // do not begin downloading data.
+        if (m_mediaSession->dataLoadingPermitted(*this))
+            selectMediaResource();
+    }
 
     // 10 - Note: Playback of any previously playing media resource for this element stops.
 
@@ -2151,6 +2155,9 @@ void HTMLMediaElement::waitForSourceChange()
 
 void HTMLMediaElement::noneSupported()
 {
+    if (m_error)
+        return;
+
     INFO_LOG(LOGIDENTIFIER);
 
     stopPeriodicTimers();
@@ -6964,7 +6971,6 @@ void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture(MediaEle
         | MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker
         | MediaElementSession::RequireUserGestureToAutoplayToExternalDevice
 #endif
-        | MediaElementSession::RequireUserGestureForLoad
         | MediaElementSession::RequireUserGestureForVideoRateChange
         | MediaElementSession::RequireUserGestureForAudioRateChange
         | MediaElementSession::RequireUserGestureForFullscreen
index 8d52c44..8eb8e43 100644 (file)
@@ -57,11 +57,4 @@ bool RuntimeEnabledFeatures::spectreGadgetsEnabled() const
     return JSC::Options::enableSpectreGadgets();
 }
 
-#if ENABLE(VIDEO)
-bool RuntimeEnabledFeatures::audioEnabled() const
-{
-    return MediaPlayer::isAvailable();
-}
-#endif
-
 } // namespace WebCore
index 1bc7f04..8805983 100644 (file)
@@ -230,10 +230,6 @@ public:
 
     bool spectreGadgetsEnabled() const;
 
-#if ENABLE(VIDEO)
-    bool audioEnabled() const;
-#endif
-
     void setInspectorAdditionsEnabled(bool isEnabled) { m_inspectorAdditionsEnabled = isEnabled; }
     bool inspectorAdditionsEnabled() const { return m_inspectorAdditionsEnabled; }
 
index b2ea9be..265ab8b 100644 (file)
@@ -1,3 +1,19 @@
+2018-03-27  Eric Carlson  <eric.carlson@apple.com>
+
+        Make AVFoundationEnabled preference available on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=183876
+        <rdar://problem/38726459>
+
+        Reviewed by Youenn Fablet.
+
+        * Shared/WebPreferences.yaml: Set AVFoundationEnabled with DEFAULT_AVFOUNDATION_ENABLED.
+        * Shared/WebPreferencesDefaultValues.h:
+
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _setAVFoundationEnabled:]): Enable for iOS.
+        (-[WKPreferences _avFoundationEnabled]): Ditto.
+        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
+
 2018-03-26  Tim Horton  <timothy_horton@apple.com>
 
         Adopt WK_ALTERNATE_FRAMEWORKS_DIR in WebKit
index edc8c13..d826f5e 100644 (file)
@@ -198,7 +198,7 @@ AllowCrossOriginSubresourcesToAskForCredentials:
 
 AVFoundationEnabled:
   type: bool
-  defaultValue: true
+  defaultValue: DEFAULT_AVFOUNDATION_ENABLED
   getter: isAVFoundationEnabled
   webcoreBinding: DeprecatedGlobalSettings
   condition: USE(AVFOUNDATION)
index 41a7844..d4846dd 100644 (file)
 
 #endif
 
+#if !ENABLE(EXTRA_ZOOM_MODE)
+#define DEFAULT_AVFOUNDATION_ENABLED true
+#else
+#define DEFAULT_AVFOUNDATION_ENABLED false
+#endif
+
 // Cocoa ports must disable experimental features on release branches for now.
 #if ENABLE(EXPERIMENTAL_FEATURES) || PLATFORM(COCOA)
 #define DEFAULT_EXPERIMENTAL_FEATURES_ENABLED true
index 1c01df0..de74a74 100644 (file)
@@ -731,6 +731,16 @@ static WebCore::EditableLinkBehavior toEditableLinkBehavior(_WKEditableLinkBehav
     _preferences->setEditableLinkBehavior(toEditableLinkBehavior(editableLinkBehavior));
 }
 
+- (void)_setAVFoundationEnabled:(BOOL)enabled
+{
+    _preferences->setAVFoundationEnabled(enabled);
+}
+
+- (BOOL)_avFoundationEnabled
+{
+    return _preferences->isAVFoundationEnabled();
+}
+
 #if PLATFORM(MAC)
 - (void)_setJavaEnabledForLocalFiles:(BOOL)enabled
 {
@@ -872,16 +882,6 @@ static WebCore::EditableLinkBehavior toEditableLinkBehavior(_WKEditableLinkBehav
     return _preferences->allowUniversalAccessFromFileURLs();
 }
 
-- (void)_setAVFoundationEnabled:(BOOL)enabled
-{
-    _preferences->setAVFoundationEnabled(enabled);
-}
-
-- (BOOL)_avFoundationEnabled
-{
-    return _preferences->isAVFoundationEnabled();
-}
-
 - (void)_setSuppressesIncrementalRendering:(BOOL)enabled
 {
     _preferences->setSuppressesIncrementalRendering(enabled);
index 52f595f..6cbcd44 100644 (file)
@@ -128,6 +128,8 @@ typedef NS_ENUM(NSInteger, _WKEditableLinkBehavior) {
 
 @property (nonatomic, setter=_setEditableLinkBehavior:) _WKEditableLinkBehavior _editableLinkBehavior WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
+@property (nonatomic, setter=_setAVFoundationEnabled:) BOOL _avFoundationEnabled WK_API_AVAILABLE(macosx(10.10), ios(WK_IOS_TBA));
+
 + (NSArray<_WKExperimentalFeature *> *)_experimentalFeatures WK_API_AVAILABLE(macosx(10.12), ios(10.0));
 - (BOOL)_isEnabledForFeature:(_WKExperimentalFeature *)feature WK_API_AVAILABLE(macosx(10.12), ios(10.0));
 - (void)_setEnabled:(BOOL)value forFeature:(_WKExperimentalFeature *)feature WK_API_AVAILABLE(macosx(10.12), ios(10.0));
@@ -148,7 +150,6 @@ typedef NS_ENUM(NSInteger, _WKEditableLinkBehavior) {
 @property (nonatomic, setter=_setShouldPrintBackgrounds:) BOOL _shouldPrintBackgrounds WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 @property (nonatomic, setter=_setWebSecurityEnabled:) BOOL _webSecurityEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 @property (nonatomic, setter=_setUniversalAccessFromFileURLsAllowed:) BOOL _universalAccessFromFileURLsAllowed WK_API_AVAILABLE(macosx(WK_MAC_TBA));
-@property (nonatomic, setter=_setAVFoundationEnabled:) BOOL _avFoundationEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 @property (nonatomic, setter=_setSuppressesIncrementalRendering:) BOOL _suppressesIncrementalRendering WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 @property (nonatomic, setter=_setAsynchronousPluginInitializationEnabled:) BOOL _asynchronousPluginInitializationEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 @property (nonatomic, setter=_setArtificialPluginInitializationDelayEnabled:) BOOL _artificialPluginInitializationDelayEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA));
index 5a7a16c..e35815e 100644 (file)
@@ -1,3 +1,19 @@
+2018-03-27  Eric Carlson  <eric.carlson@apple.com>
+
+        Make AVFoundationEnabled preference available on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=183876
+        <rdar://problem/38726459>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit/video.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/AVFoundationPreference.mm: Added.
+        (-[PreferenceTestMessageHandler userContentController:didReceiveScriptMessage:]):
+        (TestWebKitAPI::AVFoundationPref::SetUp):
+        (TestWebKitAPI::AVFoundationPref::testWithPreference):
+        (TestWebKitAPI::TEST_F):
+
 2018-03-26  Brent Fulgham  <bfulgham@apple.com>
 
         Warn against cookie access in the WebContent process using ProcessPrivilege assertions
index 87534f8..acc1f86 100644 (file)
@@ -29,6 +29,8 @@
                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 */; };
+               07CD32F62065B5430064A4BE /* AVFoundationPreference.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */; };
+               07CD32F82065B72B0064A4BE /* video.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07CD32F72065B72A0064A4BE /* video.html */; };
                07CE1CF31F06A7E000BF89F5 /* GetUserMediaNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */; };
                07E1F6A21FFC44FA0096C7EC /* getDisplayMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */; };
                07E1F6A31FFC4B760096C7EC /* GetDisplayMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */; };
                                CD758A6F20572EA00071834A /* video-with-paused-audio-and-playing-muted.html in Copy Resources */,
                                CDC8E4961BC6F10800594FEC /* video-without-audio.html in Copy Resources */,
                                CDC8E4971BC6F10800594FEC /* video-without-audio.mp4 in Copy Resources */,
+                               07CD32F82065B72B0064A4BE /* video.html in Copy Resources */,
                                1C2B81861C89259D00A5529F /* webfont.html in Copy Resources */,
                                51714EB41CF8C78C004723C4 /* WebProcessKillIDBCleanup-1.html in Copy Resources */,
                                51714EB51CF8C78C004723C4 /* WebProcessKillIDBCleanup-2.html in Copy Resources */,
                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>"; };
+               07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationPreference.mm; sourceTree = "<group>"; };
+               07CD32F72065B72A0064A4BE /* video.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = video.html; path = Tests/WebKit/video.html; sourceTree = "<group>"; };
                07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetUserMediaNavigation.mm; sourceTree = "<group>"; };
                07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetDisplayMedia.mm; sourceTree = "<group>"; };
                07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = getDisplayMedia.html; path = ../WebKit/getDisplayMedia.html; sourceTree = "<group>"; };
                08FB7794FE84155DC02AAC07 /* TestWebKitAPI */ = {
                        isa = PBXGroup;
                        children = (
+                               07CD32F72065B72A0064A4BE /* video.html */,
                                08FB7795FE84155DC02AAC07 /* Source */,
                                BCB9EB66112366D800A137E0 /* Tests */,
                                BC90957D12554CEA00083756 /* Configurations */,
                                834138C6203261B900F26960 /* AsyncPolicyForNavigationResponse.mm */,
                                754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */,
                                2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */,
+                               07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */,
                                374B7A5E1DF36EEE00ACCB6C /* BundleEditingDelegate.mm */,
                                374B7A5F1DF36EEE00ACCB6C /* BundleEditingDelegatePlugIn.mm */,
                                374B7A621DF3734C00ACCB6C /* BundleEditingDelegateProtocol.h */,
                                7CCE7EB41A411A7E00447C4C /* AttributedString.mm in Sources */,
                                CDC8E48D1BC5CB4500594FEC /* AudioSessionCategoryIOS.mm in Sources */,
                                7C83E0B91D0A64F100FEBCF3 /* AutoLayoutIntegration.mm in Sources */,
+                               07CD32F62065B5430064A4BE /* AVFoundationPreference.mm in Sources */,
                                7CCE7EB51A411A7E00447C4C /* BackForwardList.mm in Sources */,
                                374B7A601DF36EEE00ACCB6C /* BundleEditingDelegate.mm in Sources */,
                                A13EBBB11B87438000097110 /* BundleParameters.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit/video.html b/Tools/TestWebKitAPI/Tests/WebKit/video.html
new file mode 100644 (file)
index 0000000..6cafbd0
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+    <body>
+        <p>
+        <button onclick="test()">Test</button>
+        </p>
+
+        <script>
+
+            let _element;
+            function elementType()
+            {
+                return _element.toString();
+            }
+            
+            function test(elementType)
+            {
+                _element = document.createElement(elementType);
+                _element.onerror = (event) => {
+                    if (window.webkit)
+                      window.webkit.messageHandlers.testHandler.postMessage('error');
+                }
+                _element.oncanplay = (event) => {
+                    if (window.webkit)
+                      window.webkit.messageHandlers.testHandler.postMessage('canplay');
+                }
+                _element.controls = "true"
+                _element.src = "test.mp4";
+
+                document.body.appendChild(_element);
+            }
+
+        </script>
+    </body>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/AVFoundationPreference.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/AVFoundationPreference.mm
new file mode 100644 (file)
index 0000000..0060686
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+
+#if WK_API_ENABLED
+
+#if PLATFORM(COCOA)
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKUIDelegatePrivate.h>
+#import <WebKit/WKWebView.h>
+#import <WebKit/WKWebViewConfiguration.h>
+
+static bool receivedScriptMessage = false;
+static RetainPtr<WKScriptMessage> lastScriptMessage;
+
+@interface PreferenceTestMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation PreferenceTestMessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    lastScriptMessage = message;
+    receivedScriptMessage = true;
+}
+@end
+
+namespace TestWebKitAPI {
+
+class AVFoundationPref : public testing::Test {
+public:
+    virtual void SetUp()
+    {
+        m_configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+        auto handler = adoptNS([[PreferenceTestMessageHandler alloc] init]);
+        [[m_configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    }
+
+    enum class ElementType { Audio, Video };
+    void testWithPreference(ElementType elementType, bool enabled)
+    {
+        receivedScriptMessage = false;
+
+        auto preferences = [m_configuration preferences];
+        preferences._avFoundationEnabled = enabled;
+        auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:m_configuration.get()]);
+        [webView synchronouslyLoadTestPageNamed:@"video"];
+
+        [webView stringByEvaluatingJavaScript:[NSString stringWithFormat:@"test('%s')", elementType == ElementType::Audio ? "audio" : "video"]];
+
+        TestWebKitAPI::Util::run(&receivedScriptMessage);
+        auto type = [webView stringByEvaluatingJavaScript:@"elementType()"];
+
+        if (elementType == ElementType::Audio)
+            EXPECT_STREQ(type.UTF8String, "[object HTMLAudioElement]");
+        else
+            EXPECT_STREQ(type.UTF8String, "[object HTMLVideoElement]");
+
+        if (enabled)
+            EXPECT_STREQ(((NSString *)[lastScriptMessage body]).UTF8String, "canplay");
+        else
+            EXPECT_STREQ(((NSString *)[lastScriptMessage body]).UTF8String, "error");
+    }
+
+private:
+    RetainPtr<WKWebViewConfiguration> m_configuration;
+};
+
+TEST_F(AVFoundationPref, PrefTest)
+{
+    testWithPreference(ElementType::Audio, true);
+    testWithPreference(ElementType::Audio, false);
+    testWithPreference(ElementType::Video, true);
+    testWithPreference(ElementType::Video, false);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(COCOA)
+
+#endif // WK_API_ENABLED