Video playback is using more power
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2018 23:49:11 +0000 (23:49 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2018 23:49:11 +0000 (23:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188452
Source/WebCore:

<rdar://problem/42298937>

Reviewed by Eric Carlson.

Test: TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm

When the meaning of PlatformMediaSession::Video changed to "video-only", we failed to update
MediaSessionManagerCocoa::updateSessionState() to use the new PlatformMediaSession::VideoAudio
enum, so Video-only sessions were getting the higher audio buffer size (where it's not needed)
and Video-and-Audio sessions were getting the default value.

To enable testing, add a preferredAudioBufferSize property to Internals. Also, the getter for
AudioSession::preferredBufferSize was using the wrong CoreAudio property address, and was
always returning 0.

* platform/audio/AudioSession.h:
* platform/audio/cocoa/MediaSessionManagerCocoa.cpp:
(MediaSessionManagerCocoa::updateSessionState):
* platform/audio/mac/AudioSessionMac.cpp:
(WebCore::AudioSession::preferredBufferSize const):
* testing/Internals.cpp:
(WebCore::Internals::preferredAudioBufferSize const):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Reviewed by Eric Carlson.

* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _setLowPowerVideoAudioBufferSizeEnabled:]):
(-[WKPreferences _lowPowerVideoAudioBufferSizeEnabled]):

Tools:

<rdar://problem/42298937>

Reviewed by Eric Carlson.

* TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm:
(PreferredAudioBufferSize::createView):
(PreferredAudioBufferSize::preferredAudioBufferSize const):
(TEST_F):

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

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/audio/AudioSession.h
Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.cpp
Source/WebCore/platform/audio/mac/AudioSessionMac.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
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/WebKitCocoa/PreferredAudioBufferSize.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/audio-with-web-audio.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/video-with-audio-and-web-audio.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/web-audio-only.html [new file with mode: 0644]

index 994a056..088eb61 100644 (file)
@@ -1,3 +1,32 @@
+2018-08-09  Jer Noble  <jer.noble@apple.com>
+
+        Video playback is using more power
+        https://bugs.webkit.org/show_bug.cgi?id=188452
+        <rdar://problem/42298937>
+
+        Reviewed by Eric Carlson.
+
+        Test: TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm
+
+        When the meaning of PlatformMediaSession::Video changed to "video-only", we failed to update
+        MediaSessionManagerCocoa::updateSessionState() to use the new PlatformMediaSession::VideoAudio
+        enum, so Video-only sessions were getting the higher audio buffer size (where it's not needed)
+        and Video-and-Audio sessions were getting the default value.
+
+        To enable testing, add a preferredAudioBufferSize property to Internals. Also, the getter for
+        AudioSession::preferredBufferSize was using the wrong CoreAudio property address, and was
+        always returning 0.
+
+        * platform/audio/AudioSession.h:
+        * platform/audio/cocoa/MediaSessionManagerCocoa.cpp:
+        (MediaSessionManagerCocoa::updateSessionState):
+        * platform/audio/mac/AudioSessionMac.cpp:
+        (WebCore::AudioSession::preferredBufferSize const):
+        * testing/Internals.cpp:
+        (WebCore::Internals::preferredAudioBufferSize const):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2018-08-09  Saam Barati  <sbarati@apple.com>
 
         memoryFootprint should return size_t not optional<size_t>
index 2df2050..f2f4f95 100644 (file)
@@ -73,7 +73,7 @@ public:
 
     bool tryToSetActive(bool);
 
-    size_t preferredBufferSize() const;
+    WEBCORE_EXPORT size_t preferredBufferSize() const;
     void setPreferredBufferSize(size_t);
 
     class MutedStateObserver {
index 5da5127..03a96bd 100644 (file)
@@ -48,7 +48,7 @@ void MediaSessionManagerCocoa::updateSessionState()
     // while having a large enough buffer so that the audio rendering remains stable, hence a computation based on sample rate.
     else if (has(PlatformMediaSession::MediaStreamCapturingAudio))
         AudioSession::sharedSession().setPreferredBufferSize(AudioSession::sharedSession().sampleRate() / 50);
-    else if ((has(PlatformMediaSession::Video) || has(PlatformMediaSession::Audio)) && DeprecatedGlobalSettings::lowPowerVideoAudioBufferSizeEnabled()) {
+    else if ((has(PlatformMediaSession::VideoAudio) || has(PlatformMediaSession::Audio)) && DeprecatedGlobalSettings::lowPowerVideoAudioBufferSizeEnabled()) {
         // FIXME: <http://webkit.org/b/116725> Figure out why enabling the code below
         // causes media LayoutTests to fail on 10.8.
 
index 6b595ef..79ab9f4 100644 (file)
@@ -147,7 +147,7 @@ size_t AudioSession::preferredBufferSize() const
     UInt32 bufferSizeSize = sizeof(bufferSize);
 
     AudioObjectPropertyAddress preferredBufferSizeAddress = {
-        kAudioDevicePropertyBufferFrameSizeRange,
+        kAudioDevicePropertyBufferFrameSize,
         kAudioObjectPropertyScopeGlobal,
         kAudioObjectPropertyElementMaster };
     OSStatus result = AudioObjectGetPropertyData(defaultDevice(), &preferredBufferSizeAddress, 0, 0, &bufferSizeSize, &bufferSize);
index 0b348e8..13b7b70 100644 (file)
@@ -4462,6 +4462,14 @@ String Internals::audioSessionCategory() const
     return emptyString();
 }
 
+double Internals::preferredAudioBufferSize() const
+{
+#if USE(AUDIO_SESSION)
+    return AudioSession::sharedSession().preferredBufferSize();
+#endif
+    return 0;
+}
+
 void Internals::clearCacheStorageMemoryRepresentation(DOMPromiseDeferred<void>&& promise)
 {
     auto* document = contextDocument();
index 3884efd..7e32be8 100644 (file)
@@ -662,6 +662,7 @@ public:
 #endif
 
     String audioSessionCategory() const;
+    double preferredAudioBufferSize() const;
 
     void clearCacheStorageMemoryRepresentation(DOMPromiseDeferred<void>&&);
     void cacheStorageEngineRepresentation(DOMPromiseDeferred<IDLDOMString>&&);
index 750c6f9..01148b9 100644 (file)
@@ -630,6 +630,7 @@ enum CompositingPolicy {
     void setConsoleMessageListener(StringCallback callback);
 
     DOMString audioSessionCategory();
+    double preferredAudioBufferSize();
 
     [Conditional=SERVICE_WORKER] Promise<boolean> hasServiceWorkerRegistration(DOMString scopeURL);
     [Conditional=SERVICE_WORKER] void terminateServiceWorker(ServiceWorker worker);
index ec3a54b..ee319b1 100644 (file)
@@ -1,3 +1,14 @@
+2018-08-09  Jer Noble  <jer.noble@apple.com>
+
+        Video playback is using more power
+        https://bugs.webkit.org/show_bug.cgi?id=188452
+
+        Reviewed by Eric Carlson.
+
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _setLowPowerVideoAudioBufferSizeEnabled:]):
+        (-[WKPreferences _lowPowerVideoAudioBufferSizeEnabled]):
+
 2018-08-09  Alex Christensen  <achristensen@webkit.org>
 
         Fix URLSchemeHandler.SyncXHR API test after r234735.
index aeffa3d..be43285 100644 (file)
@@ -772,6 +772,16 @@ static WebCore::EditableLinkBehavior toEditableLinkBehavior(_WKEditableLinkBehav
     return _preferences->punchOutWhiteBackgroundsInDarkMode();
 }
 
+- (void)_setLowPowerVideoAudioBufferSizeEnabled:(BOOL)enabled
+{
+    _preferences->setLowPowerVideoAudioBufferSizeEnabled(enabled);
+}
+
+- (BOOL)_lowPowerVideoAudioBufferSizeEnabled
+{
+    return _preferences->lowPowerVideoAudioBufferSizeEnabled();
+}
+
 #if PLATFORM(MAC)
 - (void)_setJavaEnabledForLocalFiles:(BOOL)enabled
 {
index edc96ad..3879e35 100644 (file)
@@ -139,6 +139,7 @@ typedef NS_ENUM(NSInteger, _WKEditableLinkBehavior) {
 @property (nonatomic, setter=_setStorageAccessPromptsEnabled:) BOOL _storageAccessPromptsEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setColorFilterEnabled:) BOOL _colorFilterEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setPunchOutWhiteBackgroundsInDarkMode:) BOOL _punchOutWhiteBackgroundsInDarkMode WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setLowPowerVideoAudioBufferSizeEnabled:) BOOL _lowPowerVideoAudioBufferSizeEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if !TARGET_OS_IPHONE
 @property (nonatomic, setter=_setWebGLEnabled:) BOOL _webGLEnabled WK_API_AVAILABLE(macosx(10.13.4));
index c1f88dd..e2b359a 100644 (file)
@@ -1,3 +1,16 @@
+2018-08-09  Jer Noble  <jer.noble@apple.com>
+
+        Video playback is using more power
+        https://bugs.webkit.org/show_bug.cgi?id=188452
+        <rdar://problem/42298937>
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm:
+        (PreferredAudioBufferSize::createView):
+        (PreferredAudioBufferSize::preferredAudioBufferSize const):
+        (TEST_F):
+
 2018-08-09  Alex Christensen  <achristensen@webkit.org>
 
         REGRESSION(234640) Loading stalls in environments without SafariSafeBrowsing framework
index 432ab38..198eb7d 100644 (file)
                CA38459620AE17A900990D3B /* LocalStorageDatabaseTracker.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA38459520AE012E00990D3B /* LocalStorageDatabaseTracker.mm */; };
                CD0BD0A61F79924D001AB2CF /* ContextMenuImgWithVideo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */; };
                CD0BD0A81F79982D001AB2CF /* ContextMenuImgWithVideo.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */; };
+               CD227E44211A4D5D00D285AF /* PreferredAudioBufferSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */; };
                CD321B041E3A85FA00EB21C8 /* video-with-muted-audio-and-webaudio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD321B031E3A84B700EB21C8 /* video-with-muted-audio-and-webaudio.html */; };
+               CD577799211CE0E4001B371E /* web-audio-only.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD577798211CDE8F001B371E /* web-audio-only.html */; };
+               CD57779C211CE91F001B371E /* audio-with-web-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD57779A211CE6B7001B371E /* audio-with-web-audio.html */; };
+               CD57779D211CE91F001B371E /* video-with-audio-and-web-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD57779B211CE6CE001B371E /* video-with-audio-and-web-audio.html */; };
                CD59F53419E9110D00CF1835 /* file-with-mse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53219E910AA00CF1835 /* file-with-mse.html */; };
                CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53319E910BC00CF1835 /* test-mse.mp4 */; };
                CD758A6F20572EA00071834A /* video-with-paused-audio-and-playing-muted.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD758A6E20572D540071834A /* video-with-paused-audio-and-playing-muted.html */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               CD57779C211CE91F001B371E /* audio-with-web-audio.html in Copy Resources */,
+                               CD57779D211CE91F001B371E /* video-with-audio-and-web-audio.html in Copy Resources */,
+                               CD577799211CE0E4001B371E /* web-audio-only.html in Copy Resources */,
                                1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
                                379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
                                1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */,
                CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuImgWithVideo.mm; sourceTree = "<group>"; };
                CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = ContextMenuImgWithVideo.html; sourceTree = "<group>"; };
                CD225C071C45A69200140761 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = "<group>"; };
+               CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PreferredAudioBufferSize.mm; sourceTree = "<group>"; };
                CD321B031E3A84B700EB21C8 /* video-with-muted-audio-and-webaudio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-with-muted-audio-and-webaudio.html"; sourceTree = "<group>"; };
                CD5393C71757BA9700C07123 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MD5.cpp; sourceTree = "<group>"; };
                CD5393C91757BAC400C07123 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = "<group>"; };
                CD5451E919E41F9D0016936F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSParser.cpp; sourceTree = "<group>"; };
                CD5497B315857F0C00B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; };
+               CD577798211CDE8F001B371E /* web-audio-only.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-audio-only.html"; sourceTree = "<group>"; };
+               CD57779A211CE6B7001B371E /* audio-with-web-audio.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "audio-with-web-audio.html"; sourceTree = "<group>"; };
+               CD57779B211CE6CE001B371E /* video-with-audio-and-web-audio.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "video-with-audio-and-web-audio.html"; sourceTree = "<group>"; };
                CD59F53219E910AA00CF1835 /* file-with-mse.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "file-with-mse.html"; sourceTree = "<group>"; };
                CD59F53319E910BC00CF1835 /* test-mse.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "test-mse.mp4"; sourceTree = "<group>"; };
                CD758A6E20572D540071834A /* video-with-paused-audio-and-playing-muted.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-with-paused-audio-and-playing-muted.html"; sourceTree = "<group>"; };
                                3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
                                83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
                                C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
+                               CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */,
                                7C1AF7931E8DCBAB002645B9 /* PrepareForMoveToWindow.mm */,
                                518C1152205B04F9001FF4AE /* ProcessSwapOnNavigation.mm */,
                                5798E2AF1CAF5C2800C5CBA0 /* ProvisionalURLNotChange.mm */,
                                51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */,
                                5120C83B1E674E350025B250 /* WebsiteDataStoreCustomPaths.html */,
                                2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */,
+                               CD577798211CDE8F001B371E /* web-audio-only.html */,
+                               CD57779A211CE6B7001B371E /* audio-with-web-audio.html */,
+                               CD57779B211CE6CE001B371E /* video-with-audio-and-web-audio.html */,
                        );
                        name = Resources;
                        sourceTree = "<group>";
                                CD78E11D1DB7EA660014A2DE /* FullscreenDelegate.mm in Sources */,
                                7C83E0BD1D0A650C00FEBCF3 /* FullscreenTopContentInset.mm in Sources */,
                                CDBFCC451A9FF45300A7B691 /* FullscreenZoomInitialFrame.mm in Sources */,
+                               CD227E44211A4D5D00D285AF /* PreferredAudioBufferSize.mm in Sources */,
                                83DB79691EF63B3C00BFA5E5 /* Function.cpp in Sources */,
                                7CCE7EF81A411AE600447C4C /* Geolocation.cpp in Sources */,
                                631EFFF61E7B5E8D00D2EBB8 /* Geolocation.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm
new file mode 100644 (file)
index 0000000..05dd87f
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#if WK_HAVE_C_SPI && WK_API_ENABLED
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestWKWebView.h"
+#import "WebCoreTestSupport.h"
+#import <JavaScriptCore/JSContext.h>
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKUIDelegatePrivate.h>
+#import <WebKit/_WKFullscreenDelegate.h>
+#import <wtf/RetainPtr.h>
+
+class PreferredAudioBufferSize : public testing::Test {
+public:
+    void SetUp() override
+    {
+        configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+        WKRetainPtr<WKContextRef> context(AdoptWK, TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+        configuration.get().processPool = (WKProcessPool *)context.get();
+        configuration.get().preferences._lowPowerVideoAudioBufferSizeEnabled = YES;
+    }
+
+    void createView()
+    {
+        webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+    }
+
+    double preferredAudioBufferSize() const
+    {
+        return [webView stringByEvaluatingJavaScript:@"window.internals.preferredAudioBufferSize()"].doubleValue;
+    }
+
+    RetainPtr<WKWebViewConfiguration> configuration;
+    RetainPtr<TestWKWebView> webView;
+};
+
+TEST_F(PreferredAudioBufferSize, Empty)
+{
+    createView();
+    [webView synchronouslyLoadHTMLString:@""];
+    EXPECT_EQ(512, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, AudioElement)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"audio-only"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(4096, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, WebAudio)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"web-audio-only"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(128, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, VideoOnly)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"video-without-audio"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(512, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, VideoWithAudio)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"video-with-audio"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(4096, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, AudioWithWebAudio)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"audio-with-web-audio"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(128, preferredAudioBufferSize());
+}
+
+TEST_F(PreferredAudioBufferSize, VideoWithAudioAndWebAudio)
+{
+    createView();
+    [webView synchronouslyLoadTestPageNamed:@"video-with-audio-and-web-audio"];
+    [webView waitForMessage:@"playing"];
+    EXPECT_EQ(128, preferredAudioBufferSize());
+}
+
+#endif // WK_HAVE_C_SPI && WK_API_ENABLED
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/audio-with-web-audio.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/audio-with-web-audio.html
new file mode 100644 (file)
index 0000000..a32661f
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+        window.addEventListener('load', async event => {
+            let context = new webkitAudioContext();
+            let node = context.createBufferSource();
+            node.connect(context.destination);
+
+            let audio = new Audio();
+            audio.src = "video-with-audio.mp4";
+            
+            Promise.all([context.resume(), audio.play()]).then(() => {
+                window.webkit.messageHandlers.testHandler.postMessage('playing');
+            }, () => {
+                window.webkit.messageHandlers.testHandler.postMessage('not playing');
+            });
+        });
+    </script>
+</head>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/video-with-audio-and-web-audio.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/video-with-audio-and-web-audio.html
new file mode 100644 (file)
index 0000000..33485d9
--- /dev/null
@@ -0,0 +1,22 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+        window.addEventListener('load', event => {
+            let context = new webkitAudioContext();
+            let node = context.createBufferSource();
+            node.connect(context.destination);
+
+            let video = document.querySelector('video');
+            
+            Promise.all([context.resume(), video.play()]).then(() => {
+                window.webkit.messageHandlers.testHandler.postMessage('playing');
+            }, () => {
+                window.webkit.messageHandlers.testHandler.postMessage('not playing');
+            });
+        });
+    </script>
+</head>
+    <video src="video-with-audio.mp4"></video>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-audio-only.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-audio-only.html
new file mode 100644 (file)
index 0000000..2167c9d
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+    window.addEventListener('load', async event => {
+        var context = new webkitAudioContext();
+        context.addEventListener('statechange', statechange);
+        node = context.createBufferSource();
+        node.connect(context.destination);
+        context.resume();
+    });
+    
+    function statechange(event) {
+        var context = event.target;
+        var message = context.state === 'running' ? 'playing' : 'not playing';
+        window.webkit.messageHandlers.testHandler.postMessage(message);
+    }
+    </script>
+</head>
+</html>
+