WebKit Bugzilla
Attachment 348360 Details for
Bug 189069
: Muted elements do not have their Now Playing status updated when unmuted.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189069-20180828165508.patch (text/plain), 24.84 KB, created by
Jer Noble
on 2018-08-28 16:55:08 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2018-08-28 16:55:08 PDT
Size:
24.84 KB
patch
obsolete
>Subversion Revision: 235089 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index f0cfa7dbd16aee9344b0c2f39df3979c83688041..29bdcc1092e41609801289cf438c302b04ca67d3 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,17 @@ >+2018-08-28 Jer Noble <jer.noble@apple.com> >+ >+ Muted elements do not have their Now Playing status updated when unmuted. >+ https://bugs.webkit.org/show_bug.cgi?id=189069 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Schedule an updateNowPlayingInfo() when an element becomes unmuted. >+ >+ * platform/audio/PlatformMediaSessionManager.h: >+ * platform/audio/mac/MediaSessionManagerMac.h: >+ * platform/audio/mac/MediaSessionManagerMac.mm: >+ (WebCore::MediaSessionManagerMac::sessionCanProduceAudioChanged): >+ > 2018-08-22 Jer Noble <jer.noble@apple.com> > > Refactoring: eliminate raw pointer usage in Fullscreen code >diff --git a/Source/WebCore/platform/audio/PlatformMediaSessionManager.h b/Source/WebCore/platform/audio/PlatformMediaSessionManager.h >index 4c9fe6ef25e8d45bc9c1b8bee02911321339aa00..c7d0bc86fe7767e1534716fbc0f6338ee6e2aaec 100644 >--- a/Source/WebCore/platform/audio/PlatformMediaSessionManager.h >+++ b/Source/WebCore/platform/audio/PlatformMediaSessionManager.h >@@ -98,6 +98,7 @@ public: > virtual void sessionStateChanged(PlatformMediaSession&); > virtual void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) { }; > virtual void clientCharacteristicsChanged(PlatformMediaSession&) { } >+ virtual void sessionCanProduceAudioChanged(PlatformMediaSession&); > > #if PLATFORM(IOS) > virtual void configureWireLessTargetMonitoring() { } >@@ -110,7 +111,6 @@ public: > Vector<PlatformMediaSession*> currentSessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>&); > > void sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession&); >- void sessionCanProduceAudioChanged(PlatformMediaSession&); > > protected: > friend class PlatformMediaSession; >diff --git a/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h b/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h >index 29076950e1acec269cfa74fedc0ef175ac528776..44cd9c7750c10b33f1fe1aae0ad291698eca4bc9 100644 >--- a/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h >+++ b/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h >@@ -55,6 +55,7 @@ private: > void sessionWillEndPlayback(PlatformMediaSession&) override; > void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) override; > void clientCharacteristicsChanged(PlatformMediaSession&) override; >+ void sessionCanProduceAudioChanged(PlatformMediaSession&) override; > > void updateNowPlayingInfo(); > >diff --git a/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm b/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm >index cb83304cf89adcae007d290981d342981d69eb39..19625692fb4fccd46f0b0cc4cf114f2fc63acacd 100644 >--- a/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm >+++ b/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm >@@ -104,6 +104,12 @@ void MediaSessionManagerMac::clientCharacteristicsChanged(PlatformMediaSession&) > LOG(Media, "MediaSessionManagerMac::clientCharacteristicsChanged"); > scheduleUpdateNowPlayingInfo(); > } >+ >+void MediaSessionManagerMac::sessionCanProduceAudioChanged(PlatformMediaSession& session) >+{ >+ PlatformMediaSessionManager::sessionCanProduceAudioChanged(session); >+ scheduleUpdateNowPlayingInfo(); >+} > > PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession() > { >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index cb2ec2b264af8b241d9fd523f875c1e49842c4c8..31e26f154a715a8b13f3c874d80a136b75c8d22d 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,32 @@ >+2018-08-28 Jer Noble <jer.noble@apple.com> >+ >+ Muted elements do not have their Now Playing status updated when unmuted. >+ https://bugs.webkit.org/show_bug.cgi?id=189069 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/NowPlaying.mm: Added. >+ (userInfoHasNowPlayingApplicationPID): >+ (getNowPlayingClient): >+ (getNowPlayingClientPid): >+ (NowPlayingTest::webView): >+ (NowPlayingTest::configuration): >+ (NowPlayingTest::webViewPid): >+ (NowPlayingTest::loadPage): >+ (NowPlayingTest::runScriptWithUserGesture): >+ (NowPlayingTest::runScriptWithoutUserGesture): >+ (NowPlayingTest::executeAndWaitForPlaying): >+ (NowPlayingTest::executeAndWaitForWebViewToBecomeNowPlaying): >+ (NowPlayingTest::observers): >+ (NowPlayingTest::addObserver): >+ (NowPlayingTest::removeObserver): >+ (NowPlayingTest::notificationCallback): >+ (NowPlayingTest::receivedNotification): >+ (NowPlayingTest::performAfterReceivingNotification): >+ (TEST_F): >+ * TestWebKitAPI/Tests/WebKitCocoa/now-playing.html: Added. >+ > 2018-08-20 Thomas Denney <tdenney@apple.com> > > Added Thomas Denney to contributors.json. >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 8f0120d44a67256540385c24f63c8038894a6907..b4a0566b3fffe38ab4daaa9ce65e55ef04499012 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -720,6 +720,7 @@ > 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 */; }; >+ CD2D0D1A213465560018C784 /* NowPlaying.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD2D0D19213465560018C784 /* NowPlaying.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 */; }; >@@ -736,6 +737,7 @@ > CDA3159A1ED548F1009F60D3 /* MediaPlaybackSleepAssertion.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDA315991ED540A5009F60D3 /* MediaPlaybackSleepAssertion.html */; }; > CDA3159D1ED5643F009F60D3 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDA3159C1ED5643F009F60D3 /* IOKit.framework */; }; > CDB4115A1E0B00DB00EAD352 /* video-with-muted-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */; }; >+ CDB5DFFF213610FA00D3E189 /* now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDB5DFFE21360ED800D3E189 /* now-playing.html */; }; > CDBFCC451A9FF45300A7B691 /* FullscreenZoomInitialFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */; }; > CDBFCC461A9FF49E00A7B691 /* FullscreenZoomInitialFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */; }; > CDC8E48D1BC5CB4500594FEC /* AudioSessionCategoryIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC8E4851BC5B19400594FEC /* AudioSessionCategoryIOS.mm */; }; >@@ -1123,6 +1125,7 @@ > 5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */, > C99B675F1E39736F00FC6C80 /* no-autoplay-with-controls.html in Copy Resources */, > 466C3843210637DE006A88DE /* notify-resourceLoadObserver.html in Copy Resources */, >+ CDB5DFFF213610FA00D3E189 /* now-playing.html in Copy Resources */, > 93E2D2761ED7D53200FA76F6 /* offscreen-iframe-of-media-document.html in Copy Resources */, > CEA6CF2819CCF69D0064F5A7 /* open-and-close-window.html in Copy Resources */, > 7CCB99231D3B4A46003922F6 /* open-multiple-external-url.html in Copy Resources */, >@@ -1936,6 +1939,7 @@ > 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>"; }; >+ CD2D0D19213465560018C784 /* NowPlaying.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NowPlaying.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>"; }; >@@ -1959,6 +1963,7 @@ > CDA315991ED540A5009F60D3 /* MediaPlaybackSleepAssertion.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = MediaPlaybackSleepAssertion.html; sourceTree = "<group>"; }; > CDA3159C1ED5643F009F60D3 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; > CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-with-muted-audio.html"; sourceTree = "<group>"; }; >+ CDB5DFFE21360ED800D3E189 /* now-playing.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "now-playing.html"; sourceTree = "<group>"; }; > CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenZoomInitialFrame.html; sourceTree = "<group>"; }; > CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenZoomInitialFrame.mm; sourceTree = "<group>"; }; > CDC2C7141797089D00E627FB /* TimeRanges.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TimeRanges.cpp; sourceTree = "<group>"; }; >@@ -2355,6 +2360,7 @@ > 51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */, > 1ABC3DED1899BE6D004F0626 /* Navigation.mm */, > 5CAE4637201937CD0051610F /* NetworkProcessCrashNonPersistentDataStore.mm */, >+ CD2D0D19213465560018C784 /* NowPlaying.mm */, > 2ECFF5541D9B12F800B55394 /* NowPlayingControlsTests.mm */, > A10F047C1E3AD29C00C95E19 /* NSFileManagerExtras.mm */, > 37A22AA51DCAA27200AFBFC4 /* ObservedRenderingProgressEventsAfterCrash.mm */, >@@ -2721,6 +2727,7 @@ > 9BCD4119206D5ED7001D71BE /* mso-list-on-h4.html */, > 9BF356CC202D44F200F71160 /* mso-list.html */, > 466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */, >+ CDB5DFFE21360ED800D3E189 /* now-playing.html */, > 93E2D2751ED7D51700FA76F6 /* offscreen-iframe-of-media-document.html */, > 7CCB99221D3B44E7003922F6 /* open-multiple-external-url.html */, > CEBCA1341E3A803400C73293 /* page-with-csp-iframe.html */, >@@ -3874,6 +3881,7 @@ > 7CCE7F051A411AE600447C4C /* NewFirstVisuallyNonEmptyLayoutFrames.cpp in Sources */, > 0F5651F71FCE4DDC00310FBC /* NoHistoryItemScrollToFragment.mm in Sources */, > 83F22C6420B355F80034277E /* NoPolicyDelegateResponse.mm in Sources */, >+ CD2D0D1A213465560018C784 /* NowPlaying.mm in Sources */, > 2ECFF5551D9B12F800B55394 /* NowPlayingControlsTests.mm in Sources */, > A10F047E1E3AD29C00C95E19 /* NSFileManagerExtras.mm in Sources */, > 37A22AA71DCAA27200AFBFC4 /* ObservedRenderingProgressEventsAfterCrash.mm in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/NowPlaying.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/NowPlaying.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..dcd3b73962d42af219ffad0726f5dfdca0ee499a >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/NowPlaying.mm >@@ -0,0 +1,274 @@ >+/* >+ * 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_API_ENABLED && PLATFORM(COCOA) >+ >+#import "PlatformUtilities.h" >+#import "TestWKWebView.h" >+#import <WebKit/WKWebViewPrivate.h> >+#import <pal/spi/mac/MediaRemoteSPI.h> >+#import <wtf/Function.h> >+#import <wtf/HashMap.h> >+#import <wtf/HashSet.h> >+#import <wtf/NeverDestroyed.h> >+#import <wtf/SoftLinking.h> >+#import <wtf/text/WTFString.h> >+ >+SOFT_LINK_PRIVATE_FRAMEWORK(MediaRemote) >+SOFT_LINK(MediaRemote, MRMediaRemoteSetWantsNowPlayingNotifications, void, (bool wantsNotifications), (wantsNotifications)) >+SOFT_LINK(MediaRemote, MRMediaRemoteGetNowPlayingClient, void, (dispatch_queue_t queue, void(^completion)(MRNowPlayingClientRef, CFErrorRef)), (queue, completion)) >+SOFT_LINK(MediaRemote, MRNowPlayingClientGetProcessIdentifier, pid_t, (MRNowPlayingClientRef client), (client)) >+SOFT_LINK_CONSTANT(MediaRemote, kMRMediaRemoteNowPlayingApplicationDidChangeNotification, CFStringRef) >+SOFT_LINK_CONSTANT(MediaRemote, kMRMediaRemoteNowPlayingApplicationPIDUserInfoKey, CFStringRef) >+#define MRMediaRemoteSetWantsNowPlayingNotifications softLinkMRMediaRemoteSetWantsNowPlayingNotifications >+#define MRMediaRemoteGetNowPlayingClient softLinkMRMediaRemoteGetNowPlayingClient >+#define MRNowPlayingClientGetProcessIdentifier softLinkMRNowPlayingClientGetProcessIdentifier >+#define kMRMediaRemoteNowPlayingApplicationDidChangeNotification getkMRMediaRemoteNowPlayingApplicationDidChangeNotification() >+#define kMRMediaRemoteNowPlayingApplicationPIDUserInfoKey getkMRMediaRemoteNowPlayingApplicationPIDUserInfoKey() >+ >+static bool userInfoHasNowPlayingApplicationPID(CFDictionaryRef userInfo, int32_t pid) >+{ >+ CFNumberRef nowPlayingPidCF = (CFNumberRef)CFDictionaryGetValue(userInfo, kMRMediaRemoteNowPlayingApplicationPIDUserInfoKey); >+ if (!nowPlayingPidCF) >+ return false; >+ >+ int32_t nowPlayingPid = 0; >+ if (!CFNumberGetValue(nowPlayingPidCF, kCFNumberSInt32Type, &nowPlayingPid)) >+ return false; >+ >+ return pid == nowPlayingPid; >+} >+ >+static RetainPtr<MRNowPlayingClientRef> getNowPlayingClient() >+{ >+ bool gotNowPlaying = false; >+ RetainPtr<MRNowPlayingClientRef> nowPlayingClient; >+ MRMediaRemoteGetNowPlayingClient(dispatch_get_main_queue(), [&] (MRNowPlayingClientRef player, CFErrorRef error) { >+ if (!error && player) >+ nowPlayingClient = player; >+ gotNowPlaying = true; >+ }); >+ TestWebKitAPI::Util::run(&gotNowPlaying); >+ return nowPlayingClient; >+} >+ >+static pid_t getNowPlayingClientPid() >+{ >+ return MRNowPlayingClientGetProcessIdentifier(getNowPlayingClient().get()); >+} >+ >+class NowPlayingTest : public testing::Test { >+public: >+ void SetUp() override >+ { >+ addObserver(*this); >+ >+ _configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ [_configuration setMediaTypesRequiringUserActionForPlayback:WKAudiovisualMediaTypeAudio]; >+ >+ _webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:_configuration.get() addToWindow:YES]); >+ } >+ >+ void TearDown() override >+ { >+ removeObserver(*this); >+ } >+ >+ TestWKWebView* webView() { return _webView.get(); } >+ WKWebViewConfiguration* configuration() { return _configuration.get(); } >+ >+ pid_t webViewPid() { return [_webView _webProcessIdentifier]; } >+ >+ void loadPage(const String& name) >+ { >+ [_webView synchronouslyLoadTestPageNamed:name]; >+ } >+ >+ void runScriptWithUserGesture(const String& script) >+ { >+ bool complete = false; >+ [_webView evaluateJavaScript:script completionHandler:[&] (id, NSError *) { complete = true; }]; >+ TestWebKitAPI::Util::run(&complete); >+ } >+ >+ void runScriptWithoutUserGesture(const String& script) >+ { >+ bool complete = false; >+ [_webView _evaluateJavaScriptWithoutUserGesture:script completionHandler:[&] (id, NSError *) { complete = true; }]; >+ TestWebKitAPI::Util::run(&complete); >+ } >+ >+ void executeAndWaitForPlaying(Function<void()>&& callback) >+ { >+ bool isPlaying = false; >+ [_webView performAfterReceivingMessage:@"playing" action:[&] { isPlaying = true; }]; >+ callback(); >+ TestWebKitAPI::Util::run(&isPlaying); >+ } >+ >+ void executeAndWaitForWebViewToBecomeNowPlaying(Function<void()>&& callback) >+ { >+ bool becameNowPlaying = false; >+ performAfterReceivingNotification(kMRMediaRemoteNowPlayingApplicationDidChangeNotification, [&] (CFDictionaryRef userInfo) -> bool { >+ if (!userInfoHasNowPlayingApplicationPID(userInfo, webViewPid())) >+ return false; >+ >+ becameNowPlaying = true; >+ return true; >+ }); >+ callback(); >+ TestWebKitAPI::Util::run(&becameNowPlaying); >+ } >+ >+private: >+ using ObserverSet = HashSet<NowPlayingTest*>; >+ static ObserverSet& observers() >+ { >+ static NeverDestroyed<ObserverSet> observers { }; >+ return observers.get(); >+ } >+ >+ static void addObserver(NowPlayingTest& test) >+ { >+ observers().add(&test); >+ if (observers().size() == 1) { >+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), nullptr, ¬ificationCallback, kMRMediaRemoteNowPlayingApplicationDidChangeNotification, nullptr, CFNotificationSuspensionBehaviorDeliverImmediately); >+ MRMediaRemoteSetWantsNowPlayingNotifications(true); >+ } >+ } >+ >+ static void removeObserver(NowPlayingTest& test) >+ { >+ observers().remove(&test); >+ if (!observers().size()) { >+ CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(), nullptr, kMRMediaRemoteNowPlayingApplicationDidChangeNotification, nullptr); >+ MRMediaRemoteSetWantsNowPlayingNotifications(false); >+ } >+ } >+ >+ static void notificationCallback(CFNotificationCenterRef center, void *observer, CFNotificationName name, const void *object, CFDictionaryRef userInfo) >+ { >+ ObserverSet observersCopy = observers(); >+ for (auto* observer : observersCopy) >+ observer->receivedNotification(name, userInfo); >+ } >+ >+ void receivedNotification(CFNotificationName name, CFDictionaryRef userInfo) >+ { >+ auto callbackIter = _callbacks.find(name); >+ if (callbackIter == _callbacks.end()) >+ return; >+ auto& callback = callbackIter->value; >+ if (callback(userInfo)) >+ _callbacks.remove(callbackIter); >+ } >+ >+ using NotificationCallback = Function<bool(CFDictionaryRef)>; >+ void performAfterReceivingNotification(CFNotificationName name, NotificationCallback&& callback) >+ { >+ _callbacks.add(name, WTFMove(callback)); >+ } >+ >+ RetainPtr<WKWebViewConfiguration> _configuration; >+ RetainPtr<TestWKWebView> _webView; >+ HashMap<CFNotificationName, NotificationCallback> _callbacks; >+}; >+ >+TEST_F(NowPlayingTest, AudioElement) >+{ >+ executeAndWaitForWebViewToBecomeNowPlaying([&] { >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'audio', hasAudio:true})"); >+ runScriptWithUserGesture("play()"); >+ }); >+ }); >+} >+ >+TEST_F(NowPlayingTest, VideoElementWithAudio) >+{ >+ executeAndWaitForWebViewToBecomeNowPlaying([&] { >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'video', hasAudio:true})"); >+ runScriptWithUserGesture("play()"); >+ }); >+ }); >+} >+ >+TEST_F(NowPlayingTest, VideoElementWithoutAudio) >+{ >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'video', hasAudio:false})"); >+ runScriptWithoutUserGesture("play()"); >+ }); >+ >+ ASSERT_NE(webViewPid(), getNowPlayingClientPid()); >+} >+ >+TEST_F(NowPlayingTest, VideoElementWithMutedAudio) >+{ >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'video', hasAudio:true, muted:true})"); >+ runScriptWithoutUserGesture("play()"); >+ }); >+ ASSERT_NE(webViewPid(), getNowPlayingClientPid()); >+} >+ >+TEST_F(NowPlayingTest, VideoElementWithMutedAudioUnmutedWithUserGesture) >+{ >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'video', hasAudio:true, muted:true})"); >+ runScriptWithoutUserGesture("play()"); >+ }); >+ ASSERT_NE(webViewPid(), getNowPlayingClientPid()); >+ >+ executeAndWaitForWebViewToBecomeNowPlaying([&] { >+ runScriptWithUserGesture("unmute()"); >+ }); >+} >+ >+TEST_F(NowPlayingTest, VideoElementWithoutAudioPlayWithUserGesture) >+{ >+ executeAndWaitForPlaying([&] { >+ loadPage("now-playing"); >+ runScriptWithoutUserGesture("createMediaElement({type:'video', hasAudio:true, muted:true})"); >+ runScriptWithoutUserGesture("play()"); >+ }); >+ ASSERT_NE(webViewPid(), getNowPlayingClientPid()); >+ >+ executeAndWaitForPlaying([&] { >+ runScriptWithUserGesture("play()"); >+ }); >+ >+ ASSERT_NE(webViewPid(), getNowPlayingClientPid()); >+} >+ >+#endif // WK_API_ENABLED && PLATFORM(COCOA) >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/now-playing.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/now-playing.html >new file mode 100644 >index 0000000000000000000000000000000000000000..57f38be4183a530370e1dcdfe7e39f6369023043 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/now-playing.html >@@ -0,0 +1,50 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <script> >+ var mediaElement; >+ function createMediaElement(parameters) { >+ if (parameters.type === 'video') >+ mediaElement = document.createElement('video'); >+ else if (parameters.type === 'audio') >+ mediaElement = document.createElement('audio'); >+ else >+ throw 'Necessary parameter not provided'; >+ >+ if (parameters.autoplay) >+ mediaElement.autoplay = true; >+ >+ if (parameters.muted) >+ mediaElement.muted = true; >+ >+ if (parameters.controls) >+ mediaElement.controls = true; >+ >+ if (parameters.hasAudio) >+ mediaElement.src = 'video-with-audio.mp4'; >+ else >+ mediaElement.src = 'video-without-audio.mp4'; >+ >+ document.body.appendChild(mediaElement); >+ } >+ >+ function playing() { >+ window.webkit.messageHandlers.testHandler.postMessage('playing'); >+ } >+ >+ function notPlaying() { >+ window.webkit.messageHandlers.testHandler.postMessage('not playing'); >+ } >+ >+ function play() { >+ mediaElement.play().then(playing, notPlaying); >+ } >+ >+ function unmute() { >+ mediaElement.muted = false; >+ } >+ </script> >+</head> >+<body> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189069
:
348360
|
348406
|
348414
|
348437