Title: [266121] trunk
Revision
266121
Author
[email protected]
Date
2020-08-25 09:15:32 -0700 (Tue, 25 Aug 2020)

Log Message

[macOS] Update audio arbitration manager when audio transport changes
https://bugs.webkit.org/show_bug.cgi?id=215781
<rdar://problem/65920613>

Reviewed by Jer Noble.

Source/WebCore:

No new tests, updated AudioRoutingArbitration API test.

* platform/audio/AudioSession.cpp:
(WebCore::AudioSession::audioOutputDeviceChanged): Add empty method.
(WebCore::setIsPlayingToBluetoothOverride): Ditto.
* platform/audio/AudioSession.h:

* platform/audio/cocoa/MediaSessionManagerCocoa.h:
* platform/audio/cocoa/MediaSessionManagerCocoa.mm:
(WebCore::MediaSessionManagerCocoa::audioOutputDeviceChanged): Call AudioSession::audioOutputDeviceChanged.

* platform/audio/mac/AudioSessionMac.mm:
(WebCore::defaultDeviceTransportIsBluetooth): New.
(WebCore::AudioSession::audioOutputDeviceChanged): Clear m_private->playingToBluetooth
if bluetooth transport has changed since the last arbitration update.
(WebCore::AudioSession::setIsPlayingToBluetoothOverride): Allow override of bluetooth
transport for testing.
(WebCore::AudioSession::setCategory): Update routing arbitration if audio session category
or bluetooth transport changes.

* testing/Internals.cpp:
(WebCore::Internals::setIsPlayingToBluetoothOverride):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

* UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _audioRoutingArbitrationUpdateTime]):

* UIProcess/Media/AudioSessionRoutingArbitratorProxy.h:
(WebKit::AudioSessionRoutingArbitratorProxy::arbitrationUpdateTime const):

* UIProcess/Media/cocoa/AudioSessionRoutingArbitratorProxyCocoa.mm:
(WebKit::AudioSessionRoutingArbitratorProxy::beginRoutingArbitrationWithCategory):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/AudioRoutingArbitration.mm:
(AudioRoutingArbitration::statusShouldBecomeEqualTo): Add message string to help
debugging when the test fails.
* TestWebKitAPI/Tests/WebKitLegacy/ios/video-with-audio.html:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (266120 => 266121)


--- trunk/Source/WebCore/ChangeLog	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/ChangeLog	2020-08-25 16:15:32 UTC (rev 266121)
@@ -1,3 +1,36 @@
+2020-08-25  Eric Carlson  <[email protected]>
+
+        [macOS] Update audio arbitration manager when audio transport changes
+        https://bugs.webkit.org/show_bug.cgi?id=215781
+        <rdar://problem/65920613>
+
+        Reviewed by Jer Noble.
+
+        No new tests, updated AudioRoutingArbitration API test.
+
+        * platform/audio/AudioSession.cpp:
+        (WebCore::AudioSession::audioOutputDeviceChanged): Add empty method.
+        (WebCore::setIsPlayingToBluetoothOverride): Ditto.
+        * platform/audio/AudioSession.h:
+
+        * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+        * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+        (WebCore::MediaSessionManagerCocoa::audioOutputDeviceChanged): Call AudioSession::audioOutputDeviceChanged.
+
+        * platform/audio/mac/AudioSessionMac.mm:
+        (WebCore::defaultDeviceTransportIsBluetooth): New.
+        (WebCore::AudioSession::audioOutputDeviceChanged): Clear m_private->playingToBluetooth
+        if bluetooth transport has changed since the last arbitration update.
+        (WebCore::AudioSession::setIsPlayingToBluetoothOverride): Allow override of bluetooth
+        transport for testing.
+        (WebCore::AudioSession::setCategory): Update routing arbitration if audio session category
+        or bluetooth transport changes.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::setIsPlayingToBluetoothOverride):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2020-08-25  Youenn Fablet  <[email protected]>
 
         Generated bindings for derived dictionaries are not regenerated when the base dictionary changes

Modified: trunk/Source/WebCore/platform/audio/AudioSession.cpp (266120 => 266121)


--- trunk/Source/WebCore/platform/audio/AudioSession.cpp	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/platform/audio/AudioSession.cpp	2020-08-25 16:15:32 UTC (rev 266121)
@@ -163,6 +163,19 @@
 
 #endif // !PLATFORM(COCOA)
 
+#if !PLATFORM(MAC)
+void AudioSession::audioOutputDeviceChanged()
+{
+    notImplemented();
+}
+
+void AudioSession::setIsPlayingToBluetoothOverride(Optional<bool>)
+{
+    notImplemented();
+}
+#endif // !PLATFORM(COCOA)
+
+
 String convertEnumerationToString(RouteSharingPolicy enumerationValue)
 {
     static const NeverDestroyed<String> values[] = {

Modified: trunk/Source/WebCore/platform/audio/AudioSession.h (266120 => 266121)


--- trunk/Source/WebCore/platform/audio/AudioSession.h	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/platform/audio/AudioSession.h	2020-08-25 16:15:32 UTC (rev 266121)
@@ -97,6 +97,9 @@
     void addMutedStateObserver(MutedStateObserver*);
     void removeMutedStateObserver(MutedStateObserver*);
 
+    void audioOutputDeviceChanged();
+    void setIsPlayingToBluetoothOverride(Optional<bool>);
+
     virtual bool isMuted() const;
     virtual void handleMutedStateChange();
 

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h (266120 => 266121)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2020-08-25 16:15:32 UTC (rev 266121)
@@ -96,7 +96,7 @@
     // AudioHardwareListenerClient
     void audioHardwareDidBecomeActive() final { }
     void audioHardwareDidBecomeInactive() final { }
-    void audioOutputDeviceChanged() final { updateSessionState(); }
+    void audioOutputDeviceChanged() final;
 
     // PAL::SystemSleepListener
     void systemWillSleep() final { processSystemWillSleep(); }

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (266120 => 266121)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2020-08-25 16:15:32 UTC (rev 266121)
@@ -366,6 +366,12 @@
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
+void MediaSessionManagerCocoa::audioOutputDeviceChanged()
+{
+    AudioSession::sharedSession().audioOutputDeviceChanged();
+    updateSessionState();
+}
+
 } // namespace WebCore
 
 #endif // USE(AUDIO_SESSION) && PLATFORM(COCOA)

Modified: trunk/Source/WebCore/platform/audio/mac/AudioSessionMac.mm (266120 => 266121)


--- trunk/Source/WebCore/platform/audio/mac/AudioSessionMac.mm	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/platform/audio/mac/AudioSessionMac.mm	2020-08-25 16:15:32 UTC (rev 266121)
@@ -54,6 +54,28 @@
     return deviceID;
 }
 
+#if ENABLE(ROUTING_ARBITRATION)
+static Optional<bool> isPlayingToBluetoothOverride;
+
+static float defaultDeviceTransportIsBluetooth()
+{
+    if (isPlayingToBluetoothOverride)
+        return *isPlayingToBluetoothOverride;
+
+    static const AudioObjectPropertyAddress audioDeviceTransportTypeProperty = {
+        kAudioDevicePropertyTransportType,
+        kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster,
+    };
+    UInt32 transportType = kAudioDeviceTransportTypeUnknown;
+    UInt32 transportSize = sizeof(transportType);
+    if (AudioObjectGetPropertyData(defaultDevice(), &audioDeviceTransportTypeProperty, 0, 0, &transportSize, &transportType))
+        return false;
+
+    return transportType == kAudioDeviceTransportTypeBluetooth || transportType == kAudioDeviceTransportTypeBluetoothLE;
+}
+#endif
+
 class AudioSessionPrivate {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -62,6 +84,8 @@
     AudioSession::CategoryType category { AudioSession::None };
 #if ENABLE(ROUTING_ARBITRATION)
     bool setupArbitrationOngoing { false };
+    Optional<bool> playingToBluetooth;
+    Optional<bool> playingToBluetoothOverride;
 #endif
     AudioSession::CategoryType m_categoryOverride;
     bool inRoutingArbitration { false };
@@ -79,11 +103,32 @@
     return m_private->category;
 }
 
+void AudioSession::audioOutputDeviceChanged()
+{
+#if ENABLE(ROUTING_ARBITRATION)
+    if (!m_private->playingToBluetooth || *m_private->playingToBluetooth == defaultDeviceTransportIsBluetooth())
+        return;
+
+    m_private->playingToBluetooth = WTF::nullopt;
+#endif
+}
+
+void AudioSession::setIsPlayingToBluetoothOverride(Optional<bool> value)
+{
+#if ENABLE(ROUTING_ARBITRATION)
+    isPlayingToBluetoothOverride = value;
+#else
+    UNUSED_PARAM(value);
+#endif
+}
+
 void AudioSession::setCategory(CategoryType category, RouteSharingPolicy)
 {
 #if ENABLE(ROUTING_ARBITRATION)
-    if (category == m_private->category)
+    bool playingToBluetooth = defaultDeviceTransportIsBluetooth();
+    if (category == m_private->category && m_private->playingToBluetooth && *m_private->playingToBluetooth == playingToBluetooth)
         return;
+
     m_private->category = category;
 
     if (m_private->setupArbitrationOngoing) {
@@ -105,6 +150,7 @@
     using RoutingArbitrationError = AudioSessionRoutingArbitrationClient::RoutingArbitrationError;
     using DefaultRouteChanged = AudioSessionRoutingArbitrationClient::DefaultRouteChanged;
 
+    m_private->playingToBluetooth = playingToBluetooth;
     m_private->setupArbitrationOngoing = true;
     m_routingArbitrationClient->beginRoutingArbitrationWithCategory(m_private->category, [this] (RoutingArbitrationError error, DefaultRouteChanged defaultRouteChanged) {
         m_private->setupArbitrationOngoing = false;

Modified: trunk/Source/WebCore/testing/Internals.cpp (266120 => 266121)


--- trunk/Source/WebCore/testing/Internals.cpp	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/testing/Internals.cpp	2020-08-25 16:15:32 UTC (rev 266121)
@@ -4936,6 +4936,17 @@
 
 #endif
 
+ExceptionOr<void> Internals::setIsPlayingToBluetoothOverride(Optional<bool> isPlaying)
+{
+#if ENABLE(ROUTING_ARBITRATION)
+    AudioSession::sharedSession().setIsPlayingToBluetoothOverride(isPlaying);
+    return { };
+#else
+    UNUSED_PARAM(isPlaying);
+    return Exception { NotSupportedError };
+#endif
+}
+
 void Internals::reportBacktrace()
 {
     WTFReportBacktrace();

Modified: trunk/Source/WebCore/testing/Internals.h (266120 => 266121)


--- trunk/Source/WebCore/testing/Internals.h	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/testing/Internals.h	2020-08-25 16:15:32 UTC (rev 266121)
@@ -623,6 +623,8 @@
     double privatePlayerVolume(const HTMLMediaElement&);
 #endif
 
+    ExceptionOr<void> setIsPlayingToBluetoothOverride(Optional<bool>);
+
     bool isSelectPopupVisible(HTMLSelectElement&);
 
     ExceptionOr<String> captionsStyleSheetOverride();

Modified: trunk/Source/WebCore/testing/Internals.idl (266120 => 266121)


--- trunk/Source/WebCore/testing/Internals.idl	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebCore/testing/Internals.idl	2020-08-25 16:15:32 UTC (rev 266121)
@@ -651,6 +651,8 @@
     [Conditional=VIDEO] DOMString elementBufferingPolicy(HTMLMediaElement media);
     [Conditional=VIDEO] double privatePlayerVolume(HTMLMediaElement media);
 
+    [MayThrowException] void setIsPlayingToBluetoothOverride(optional boolean? isPlaying = null);
+
     [Conditional=LEGACY_ENCRYPTED_MEDIA] void initializeMockCDM();
     [Conditional=ENCRYPTED_MEDIA] MockCDMFactory registerMockCDM();
     void enableMockMediaCapabilities();

Modified: trunk/Source/WebKit/ChangeLog (266120 => 266121)


--- trunk/Source/WebKit/ChangeLog	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebKit/ChangeLog	2020-08-25 16:15:32 UTC (rev 266121)
@@ -1,3 +1,21 @@
+2020-08-25  Eric Carlson  <[email protected]>
+
+        [macOS] Update audio arbitration manager when audio transport changes
+        https://bugs.webkit.org/show_bug.cgi?id=215781
+        <rdar://problem/65920613>
+
+        Reviewed by Jer Noble.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+        * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+        (-[WKWebView _audioRoutingArbitrationUpdateTime]):
+
+        * UIProcess/Media/AudioSessionRoutingArbitratorProxy.h:
+        (WebKit::AudioSessionRoutingArbitratorProxy::arbitrationUpdateTime const):
+
+        * UIProcess/Media/cocoa/AudioSessionRoutingArbitratorProxyCocoa.mm:
+        (WebKit::AudioSessionRoutingArbitratorProxy::beginRoutingArbitrationWithCategory):
+
 2020-08-25  Youenn Fablet  <[email protected]>
 
         Add support for MediaRecorder bitrate options

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (266120 => 266121)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2020-08-25 16:15:32 UTC (rev 266121)
@@ -74,4 +74,5 @@
 
 - (BOOL)_hasSleepDisabler;
 - (WKWebViewAudioRoutingArbitrationStatus)_audioRoutingArbitrationStatus;
+- (double)_audioRoutingArbitrationUpdateTime;
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (266120 => 266121)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2020-08-25 16:15:32 UTC (rev 266121)
@@ -262,4 +262,13 @@
 #endif
 }
 
+- (double)_audioRoutingArbitrationUpdateTime
+{
+#if ENABLE(ROUTING_ARBITRATION)
+    return _page->process().audioSessionRoutingArbitrator().arbitrationUpdateTime().secondsSinceEpoch().seconds();
+#else
+    return 0;
+#endif
+}
+
 @end

Modified: trunk/Source/WebKit/UIProcess/Media/AudioSessionRoutingArbitratorProxy.h (266120 => 266121)


--- trunk/Source/WebKit/UIProcess/Media/AudioSessionRoutingArbitratorProxy.h	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebKit/UIProcess/Media/AudioSessionRoutingArbitratorProxy.h	2020-08-25 16:15:32 UTC (rev 266121)
@@ -29,6 +29,7 @@
 
 #include "MessageReceiver.h"
 #include <WebCore/AudioSession.h>
+#include <wtf/WallTime.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebKit {
@@ -59,6 +60,7 @@
     };
 
     ArbitrationStatus arbitrationStatus() const { return m_arbitrationStatus; }
+    WallTime arbitrationUpdateTime() const { return m_arbitrationUpdateTime; }
 
 private:
     // IPC::MessageReceiver
@@ -71,6 +73,7 @@
     WebProcessProxy& m_process;
     WebCore::AudioSession::CategoryType m_category { WebCore::AudioSession::None };
     ArbitrationStatus m_arbitrationStatus { ArbitrationStatus::None };
+    WallTime m_arbitrationUpdateTime;
 };
 
 }

Modified: trunk/Source/WebKit/UIProcess/Media/cocoa/AudioSessionRoutingArbitratorProxyCocoa.mm (266120 => 266121)


--- trunk/Source/WebKit/UIProcess/Media/cocoa/AudioSessionRoutingArbitratorProxyCocoa.mm	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Source/WebKit/UIProcess/Media/cocoa/AudioSessionRoutingArbitratorProxyCocoa.mm	2020-08-25 16:15:32 UTC (rev 266121)
@@ -178,6 +178,7 @@
 {
     m_category = category;
     m_arbitrationStatus = ArbitrationStatus::Pending;
+    m_arbitrationUpdateTime = WallTime::now();
     SharedArbitrator::sharedInstance().beginRoutingArbitrationForArbitrator(*this, [weakThis = makeWeakPtr(*this), callback = WTFMove(callback)] (RoutingArbitrationError error, DefaultRouteChanged routeChanged) mutable {
         if (weakThis)
             weakThis->m_arbitrationStatus = error == RoutingArbitrationError::None ? ArbitrationStatus::Active : ArbitrationStatus::None;

Modified: trunk/Tools/ChangeLog (266120 => 266121)


--- trunk/Tools/ChangeLog	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Tools/ChangeLog	2020-08-25 16:15:32 UTC (rev 266121)
@@ -1,3 +1,16 @@
+2020-08-25  Eric Carlson  <[email protected]>
+
+        [macOS] Update audio arbitration manager when audio transport changes
+        https://bugs.webkit.org/show_bug.cgi?id=215781
+        <rdar://problem/65920613>
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/AudioRoutingArbitration.mm:
+        (AudioRoutingArbitration::statusShouldBecomeEqualTo): Add message string to help
+        debugging when the test fails.
+        * TestWebKitAPI/Tests/WebKitLegacy/ios/video-with-audio.html:
+
 2020-08-25  Youenn Fablet  <[email protected]>
 
         Generated bindings for derived dictionaries are not regenerated when the base dictionary changes

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioRoutingArbitration.mm (266120 => 266121)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioRoutingArbitration.mm	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioRoutingArbitration.mm	2020-08-25 16:15:32 UTC (rev 266121)
@@ -33,6 +33,7 @@
 #import <WebKit/WKWebViewConfigurationPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/WKWebViewPrivateForTesting.h>
+#import <wtf/WallTime.h>
 
 class AudioRoutingArbitration : public testing::Test {
 public:
@@ -41,6 +42,8 @@
     void SetUp() final
     {
         auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+        WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+        configuration.get().processPool = (WKProcessPool *)context.get();
         configuration.get()._mediaDataLoadsAutomatically = YES;
         configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
         webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration.get() addToWindow:YES]);
@@ -56,7 +59,7 @@
         [webView _close];
     }
 
-    void statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatus status)
+    void statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatus status, const char* message)
     {
         int tries = 0;
         do {
@@ -66,54 +69,86 @@
             TestWebKitAPI::Util::sleep(0.1);
         } while (++tries <= 100);
 
-        EXPECT_EQ(status, [webView _audioRoutingArbitrationStatus]);
+        EXPECT_EQ(status, [webView _audioRoutingArbitrationStatus]) << message;
     }
 };
 
 TEST_F(AudioRoutingArbitration, Basic)
 {
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Basic");
 }
 
 TEST_F(AudioRoutingArbitration, Mute)
 {
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Mute 1");
 
     [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').muted = true"];
 
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone, "Mute 2");
 
     [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').muted = false"];
 
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Mute 3");
 }
 
 TEST_F(AudioRoutingArbitration, Navigation)
 {
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Navigation 1");
 
     [webView synchronouslyLoadHTMLString:@"<html>no contents</html>"];
 
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone, "Navigation 2");
 }
 
 TEST_F(AudioRoutingArbitration, Deletion)
 {
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Deletion 1");
 
     [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').parentNode.innerHTML = ''"];
 
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone, "Deletion 2");
 }
 
 TEST_F(AudioRoutingArbitration, Close)
 {
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Close 1");
 
     [webView _close];
 
-    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone);
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusNone, "Close 2");
 }
 
+TEST_F(AudioRoutingArbitration, Updating)
+{
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Updating 1");
 
+    [webView evaluateJavaScript:@"document.querySelector('video').pause()" completionHandler:nil];
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Updating 2");
+
+    auto start = WallTime::now().secondsSinceEpoch().seconds();
+    auto arbitrationUpdateTime = [webView _audioRoutingArbitrationUpdateTime];
+    ASSERT_TRUE(arbitrationUpdateTime < start);
+
+    [webView evaluateJavaScript:@"document.querySelector('video').play()" completionHandler:nil];
+    EXPECT_EQ(arbitrationUpdateTime, [webView _audioRoutingArbitrationUpdateTime]) << "Arbitration was unexpectedly updated";
+    statusShouldBecomeEqualTo(WKWebViewAudioRoutingArbitrationStatusActive, "Updating 3");
+
+    [webView evaluateJavaScript:@"document.querySelector('video').pause()" completionHandler:nil];
+    [webView stringByEvaluatingJavaScript:@"window.internals.setIsPlayingToBluetoothOverride(true)"];
+
+    [webView evaluateJavaScript:@"document.querySelector('video').play()" completionHandler:nil];
+
+    int tries = 0;
+    do {
+        if ([webView _audioRoutingArbitrationUpdateTime] > arbitrationUpdateTime)
+            break;
+
+        TestWebKitAPI::Util::sleep(0.1);
+    } while (++tries <= 100);
+
+    EXPECT_LT(arbitrationUpdateTime, [webView _audioRoutingArbitrationUpdateTime]) << "Arbitration was not updated";
+
+    [webView stringByEvaluatingJavaScript:@"window.internals.setIsPlayingToBluetoothOverride()"];
+}
+
 #endif

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitLegacy/ios/video-with-audio.html (266120 => 266121)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitLegacy/ios/video-with-audio.html	2020-08-25 16:08:21 UTC (rev 266120)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitLegacy/ios/video-with-audio.html	2020-08-25 16:15:32 UTC (rev 266121)
@@ -2,8 +2,6 @@
 <html>
 <head>
     <script>
-    var timeout;
-
     function go() {
         var video = document.getElementsByTagName('video')[0];
         video.play().then(playing).catch(notPlaying);
@@ -29,6 +27,16 @@
         } catch(e) { }
     }
 
+    function pause() {
+        let video = document.getElementsByTagName('video')[0];
+        video.addEventListener("pause", paused, { once: true });
+        video.pause();
+    }
+
+    function play() {
+        go();
+    }
+
     document.addEventListener('pageshow', go);
    </script>
 </head>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to