NowPlayingInfo should contain a unique identifier
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Oct 2017 22:44:18 +0000 (22:44 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Oct 2017 22:44:18 +0000 (22:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178872

Reviewed by Jer Noble.

Source/WebCore:

Updated TestWebKitAPI/Tests/WebKitCocoa/NowPlayingControlsTests.mm.

* platform/audio/PlatformMediaSessionManager.h:
(WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingInfoUniqueIdentifier const): New.

* platform/audio/ios/MediaSessionManagerIOS.h:
* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Ditto.

* platform/audio/mac/MediaSessionManagerMac.h:
* platform/audio/mac/MediaSessionManagerMac.mm:
(WebCore::MediaSessionManagerMac::updateNowPlayingInfo): Ditto. Don't leak CFString.

* platform/mac/MediaRemoteSoftLink.cpp: Softlink kMRMediaRemoteNowPlayingInfoUniqueIdentifier.
* platform/mac/MediaRemoteSoftLink.h:

Source/WebKit:

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _requestActiveNowPlayingSessionInfo:]): Take a completion handler.
(-[WKWebView _requestActiveNowPlayingSessionInfo]): Deleted.
(-[WKWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/PageClient.h:

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestActiveNowPlayingSessionInfo): Ditto.
(WebKit::WebPageProxy::nowPlayingInfoCallback): Lookup and call completion handler.
(WebKit::WebPageProxy::handleActiveNowPlayingSessionInfoResponse const): Deleted.
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:

* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse): Deleted.

* UIProcess/mac/PageClientImplMac.h:
* UIProcess/mac/PageClientImplMac.mm:
(WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse): Deleted.

* WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::requestActiveNowPlayingSessionInfo): Take callback ID. Pass unique ID.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/NowPlayingControlsTests.mm:
(-[NowPlayingTestWebView hasActiveNowPlayingSession]): Use completion handler.
(TestWebKitAPI::TEST): Cleanup tests. Use new API.
(-[NowPlayingTestWebView waitForNowPlayingInfoToChange]): Deleted.

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

24 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/audio/PlatformMediaSessionManager.h
Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h
Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm
Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h
Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm
Source/WebCore/platform/mac/MediaRemoteSoftLink.cpp
Source/WebCore/platform/mac/MediaRemoteSoftLink.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/ios/PageClientImplIOS.h
Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit/UIProcess/mac/PageClientImplMac.h
Source/WebKit/UIProcess/mac/PageClientImplMac.mm
Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/NowPlayingControlsTests.mm

index 6905e42..b9fd9f8 100644 (file)
@@ -1,3 +1,26 @@
+2017-10-26  Eric Carlson  <eric.carlson@apple.com>
+
+        NowPlayingInfo should contain a unique identifier
+        https://bugs.webkit.org/show_bug.cgi?id=178872
+
+        Reviewed by Jer Noble.
+
+        Updated TestWebKitAPI/Tests/WebKitCocoa/NowPlayingControlsTests.mm.
+
+        * platform/audio/PlatformMediaSessionManager.h:
+        (WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingInfoUniqueIdentifier const): New.
+
+        * platform/audio/ios/MediaSessionManagerIOS.h:
+        * platform/audio/ios/MediaSessionManagerIOS.mm:
+        (WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Ditto.
+
+        * platform/audio/mac/MediaSessionManagerMac.h:
+        * platform/audio/mac/MediaSessionManagerMac.mm:
+        (WebCore::MediaSessionManagerMac::updateNowPlayingInfo): Ditto. Don't leak CFString.
+
+        * platform/mac/MediaRemoteSoftLink.cpp: Softlink kMRMediaRemoteNowPlayingInfoUniqueIdentifier.
+        * platform/mac/MediaRemoteSoftLink.h:
+
 2017-10-26  Keith Miller  <keith_miller@apple.com>
 
         Unreviewed, iOS build fix.
index 3ebfaa2..f518207 100644 (file)
@@ -60,6 +60,7 @@ public:
     WEBCORE_EXPORT virtual String lastUpdatedNowPlayingTitle() const { return emptyString(); }
     WEBCORE_EXPORT virtual double lastUpdatedNowPlayingDuration() const { return NAN; }
     WEBCORE_EXPORT virtual double lastUpdatedNowPlayingElapsedTime() const { return NAN; }
+    WEBCORE_EXPORT virtual uint64_t lastUpdatedNowPlayingInfoUniqueIdentifier() const { return 0; }
 
     bool willIgnoreSystemInterruptions() const { return m_willIgnoreSystemInterruptions; }
     void setWillIgnoreSystemInterruptions(bool ignore) { m_willIgnoreSystemInterruptions = ignore; }
index f8bdf51..5da2de9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -72,6 +72,7 @@ private:
     String lastUpdatedNowPlayingTitle() const final { return m_reportedTitle; }
     double lastUpdatedNowPlayingDuration() const final { return m_reportedDuration; }
     double lastUpdatedNowPlayingElapsedTime() const final { return m_reportedCurrentTime; }
+    uint64_t lastUpdatedNowPlayingInfoUniqueIdentifier() const final { return m_lastUpdatedNowPlayingInfoUniqueIdentifier; }
 
     PlatformMediaSession* nowPlayingEligibleSession();
     
@@ -79,6 +80,7 @@ private:
     double m_reportedRate { 0 };
     double m_reportedDuration { 0 };
     double m_reportedCurrentTime { 0 };
+    uint64_t m_lastUpdatedNowPlayingInfoUniqueIdentifier { 0 };
     String m_reportedTitle;
     bool m_nowPlayingActive { false };
 };
index af52950..e876d1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -79,13 +79,14 @@ SOFT_LINK_POINTER(MediaPlayer, MPMediaItemPropertyPlaybackDuration, NSString *)
 SOFT_LINK_POINTER(MediaPlayer, MPNowPlayingInfoPropertyElapsedPlaybackTime, NSString *)
 SOFT_LINK_POINTER(MediaPlayer, MPNowPlayingInfoPropertyPlaybackRate, NSString *)
 SOFT_LINK_POINTER(MediaPlayer, MPVolumeViewWirelessRoutesAvailableDidChangeNotification, NSString *)
-
+SOFT_LINK_POINTER(MediaPlayer, kMRMediaRemoteNowPlayingInfoUniqueIdentifier, NSString *)
 
 #define MPMediaItemPropertyTitle getMPMediaItemPropertyTitle()
 #define MPMediaItemPropertyPlaybackDuration getMPMediaItemPropertyPlaybackDuration()
 #define MPNowPlayingInfoPropertyElapsedPlaybackTime getMPNowPlayingInfoPropertyElapsedPlaybackTime()
 #define MPNowPlayingInfoPropertyPlaybackRate getMPNowPlayingInfoPropertyPlaybackRate()
 #define MPVolumeViewWirelessRoutesAvailableDidChangeNotification getMPVolumeViewWirelessRoutesAvailableDidChangeNotification()
+#define kMRMediaRemoteNowPlayingInfoUniqueIdentifier getkMRMediaRemoteNowPlayingInfoUniqueIdentifier()
 
 WEBCORE_EXPORT NSString* WebUIApplicationWillResignActiveNotification = @"WebUIApplicationWillResignActiveNotification";
 WEBCORE_EXPORT NSString* WebUIApplicationWillEnterForegroundNotification = @"WebUIApplicationWillEnterForegroundNotification";
@@ -270,6 +271,7 @@ void MediaSessionManageriOS::updateNowPlayingInfo()
     if (std::isfinite(duration) && duration != MediaPlayer::invalidTime())
         info.get()[MPMediaItemPropertyPlaybackDuration] = @(duration);
     info.get()[MPNowPlayingInfoPropertyPlaybackRate] = @(rate);
+    info.get()[kMRMediaRemoteNowPlayingInfoUniqueIdentifier] = @(title.existingHash());
 
     if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime())
         info.get()[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(currentTime);
index cc53d85..f2bd573 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,10 +36,11 @@ class MediaSessionManagerMac : public PlatformMediaSessionManager {
 public:
     virtual ~MediaSessionManagerMac();
 
-    bool hasActiveNowPlayingSession() const override { return m_nowPlayingActive; }
-    String lastUpdatedNowPlayingTitle() const override { return m_lastUpdatedNowPlayingTitle; }
-    double lastUpdatedNowPlayingDuration() const override { return m_lastUpdatedNowPlayingDuration; }
-    double lastUpdatedNowPlayingElapsedTime() const override { return m_lastUpdatedNowPlayingElapsedTime; }
+    bool hasActiveNowPlayingSession() const final { return m_nowPlayingActive; }
+    String lastUpdatedNowPlayingTitle() const final { return m_lastUpdatedNowPlayingTitle; }
+    double lastUpdatedNowPlayingDuration() const final { return m_lastUpdatedNowPlayingDuration; }
+    double lastUpdatedNowPlayingElapsedTime() const final { return m_lastUpdatedNowPlayingElapsedTime; }
+    uint64_t lastUpdatedNowPlayingInfoUniqueIdentifier() const final { return m_lastUpdatedNowPlayingInfoUniqueIdentifier; }
 
 private:
     friend class PlatformMediaSessionManager;
@@ -65,6 +66,7 @@ private:
     String m_lastUpdatedNowPlayingTitle;
     double m_lastUpdatedNowPlayingDuration { NAN };
     double m_lastUpdatedNowPlayingElapsedTime { NAN };
+    uint64_t m_lastUpdatedNowPlayingInfoUniqueIdentifier { 0 };
 
     GenericTaskQueue<Timer> m_nowPlayingUpdateTaskQueue;
 };
index f05f027..724eba8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -141,11 +141,13 @@ void MediaSessionManagerMac::updateNowPlayingInfo()
         m_lastUpdatedNowPlayingTitle = emptyString();
         m_lastUpdatedNowPlayingDuration = NAN;
         m_lastUpdatedNowPlayingElapsedTime = NAN;
+        m_lastUpdatedNowPlayingInfoUniqueIdentifier = 0;
         MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
 #if LOG_DISABLED
             UNUSED_PARAM(error);
 #else
-            LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
+            if (error)
+                LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
 #endif
         });
 
@@ -173,8 +175,12 @@ void MediaSessionManagerMac::updateNowPlayingInfo()
         m_lastUpdatedNowPlayingDuration = duration;
     }
 
-    auto cfRate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate);
-    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate);
+    auto cfRate = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate));
+    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate.get());
+
+    m_lastUpdatedNowPlayingInfoUniqueIdentifier = title.existingHash();
+    auto cfIdentifier = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &m_lastUpdatedNowPlayingInfoUniqueIdentifier));
+    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoUniqueIdentifier, cfIdentifier.get());
 
     double currentTime = currentSession->currentTime();
     if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime() && currentSession->supportsSeeking()) {
index 415a784..ce02431 100644 (file)
@@ -50,6 +50,7 @@ SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfo
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoElapsedTime, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoPlaybackRate, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteOptionPlaybackPosition, CFStringRef);
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoUniqueIdentifier, CFStringRef);
 
 #endif // USE(MEDIAREMOTE)
 
index 03b0dc0..dbacbba 100644 (file)
@@ -68,6 +68,8 @@ SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfo
 #define kMRMediaRemoteNowPlayingInfoPlaybackRate get_MediaRemote_kMRMediaRemoteNowPlayingInfoPlaybackRate()
 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteOptionPlaybackPosition, CFStringRef);
 #define kMRMediaRemoteOptionPlaybackPosition get_MediaRemote_kMRMediaRemoteOptionPlaybackPosition()
+SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoUniqueIdentifier, CFStringRef);
+#define kMRMediaRemoteNowPlayingInfoUniqueIdentifier get_MediaRemote_kMRMediaRemoteNowPlayingInfoUniqueIdentifier()
 
 #endif // USE(MEDIAREMOTE)
 
index bdef5d7..f34f9c2 100644 (file)
@@ -1,3 +1,37 @@
+2017-10-26  Eric Carlson  <eric.carlson@apple.com>
+
+        NowPlayingInfo should contain a unique identifier
+        https://bugs.webkit.org/show_bug.cgi?id=178872
+
+        Reviewed by Jer Noble.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _requestActiveNowPlayingSessionInfo:]): Take a completion handler.
+        (-[WKWebView _requestActiveNowPlayingSessionInfo]): Deleted.
+        (-[WKWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/PageClient.h:
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestActiveNowPlayingSessionInfo): Ditto.
+        (WebKit::WebPageProxy::nowPlayingInfoCallback): Lookup and call completion handler.
+        (WebKit::WebPageProxy::handleActiveNowPlayingSessionInfoResponse const): Deleted.
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse): Deleted.
+
+        * UIProcess/mac/PageClientImplMac.h:
+        * UIProcess/mac/PageClientImplMac.mm:
+        (WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse): Deleted.
+
+        * WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
+        (WebKit::WebPage::requestActiveNowPlayingSessionInfo): Take callback ID. Pass unique ID.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2017-10-26  Andy Estes  <aestes@apple.com>
 
         [Payment Request] Enable Payment Request whenever Apple Pay is enabled
index 0662916..0a6ad87 100644 (file)
@@ -5936,15 +5936,19 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
 
 #endif // PLATFORM(MAC)
 
-- (void)_requestActiveNowPlayingSessionInfo
+- (void)_requestActiveNowPlayingSessionInfo:(void(^)(BOOL, NSString*, double, double, NSInteger))callback
 {
-    if (_page)
-        _page->requestActiveNowPlayingSessionInfo();
-}
+    if (!_page) {
+        callback(NO, @"", std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), 0);
+        return;
+    }
 
-- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
-{
-    // Overridden by subclasses.
+    auto handler = makeBlockPtr(callback);
+    auto localCallback = WebKit::NowPlayingInfoCallback::create([handler](bool active, String title, double duration, double elapsedTime, uint64_t uniqueIdentifier, WebKit::CallbackBase::Error) {
+        handler(active, title, duration, elapsedTime, uniqueIdentifier);
+    });
+
+    _page->requestActiveNowPlayingSessionInfo(WTFMove(localCallback));
 }
 
 - (void)_setPageScale:(CGFloat)scale withOrigin:(CGPoint)origin
index a66b1b4..5ed2b2c 100644 (file)
@@ -433,8 +433,7 @@ typedef NS_OPTIONS(NSInteger, _WKRectEdge) {
 - (void)_setFooterBannerHeight:(int)height WK_API_AVAILABLE(macosx(10.12.3));
 #endif
 
-- (void)_requestActiveNowPlayingSessionInfo WK_API_AVAILABLE(macosx(10.12.3), ios(10.3));
-- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime WK_API_AVAILABLE(macosx(10.12.3), ios(10.3));
+- (void)_requestActiveNowPlayingSessionInfo:(void(^)(BOOL, NSString*, double, double, NSInteger))callback WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_MAC_TBA));
 
 - (void)_setPageScale:(CGFloat)scale withOrigin:(CGPoint)origin WK_API_AVAILABLE(ios(10.3));
 - (CGFloat)_pageScale WK_API_AVAILABLE(ios(10.3));
index c778632..04710fd 100644 (file)
@@ -279,10 +279,6 @@ public:
     virtual void setEditableElementIsFocused(bool) = 0;
 #endif // PLATFORM(MAC)
 
-#if PLATFORM(COCOA)
-    virtual void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) = 0;
-#endif
-
 #if PLATFORM(IOS)
     virtual void commitPotentialTapFailed() = 0;
     virtual void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color&, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius) = 0;
index f8ac186..dcbb528 100644 (file)
@@ -6712,14 +6712,28 @@ bool WebPageProxy::isPlayingVideoInEnhancedFullscreen() const
 #endif
 
 #if PLATFORM(COCOA)
-void WebPageProxy::requestActiveNowPlayingSessionInfo()
+void WebPageProxy::requestActiveNowPlayingSessionInfo(Ref<NowPlayingInfoCallback>&& callback)
 {
-    m_process->send(Messages::WebPage::RequestActiveNowPlayingSessionInfo(), m_pageID);
+    if (!isValid()) {
+        callback->invalidate();
+        return;
+    }
+
+    auto callbackID = callback->callbackID();
+    m_callbacks.put(WTFMove(callback));
+
+    m_process->send(Messages::WebPage::RequestActiveNowPlayingSessionInfo(callbackID), m_pageID);
 }
 
-void WebPageProxy::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) const
+void WebPageProxy::nowPlayingInfoCallback(bool hasActiveSession, const String& title, double duration, double elapsedTime, uint64_t uniqueIdentifier, CallbackID callbackID)
 {
-    m_pageClient.handleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime);
+    auto callback = m_callbacks.take<NowPlayingInfoCallback>(callbackID);
+    if (!callback) {
+        // FIXME: Log error or assert.
+        return;
+    }
+
+    callback->performCallbackWithReturnValue(hasActiveSession, title, duration, elapsedTime, uniqueIdentifier);
 }
 #endif
 
index e4d1839..8165257 100644 (file)
@@ -276,6 +276,7 @@ using DrawToPDFCallback = GenericCallback<const IPC::DataReference&>;
 
 #if PLATFORM(COCOA)
 typedef GenericCallback<const WebCore::MachSendRight&> MachSendRightCallback;
+typedef GenericCallback<bool, String, double, double, uint64_t> NowPlayingInfoCallback;
 #endif
 
 class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
@@ -1085,8 +1086,8 @@ public:
 #endif
 
 #if PLATFORM(COCOA)
-    void requestActiveNowPlayingSessionInfo();
-    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) const;
+    void requestActiveNowPlayingSessionInfo(Ref<NowPlayingInfoCallback>&&);
+    void nowPlayingInfoCallback(bool, const String&, double, double, uint64_t, CallbackID);
 #endif
 
 #if ENABLE(MEDIA_SESSION)
index 7f03c77..5be914b 100644 (file)
@@ -195,6 +195,7 @@ messages -> WebPageProxy {
 #endif
 #if PLATFORM(COCOA)
     MachSendRightCallback(WebCore::MachSendRight sendRight, WebKit::CallbackID callbackID)
+    NowPlayingInfoCallback(bool active, String title, double duration, double elapsedTime, uint64_t uniqueIdentifier, WebKit::CallbackID callbackID)
 #endif
 
     PageScaleFactorDidChange(double scaleFactor)
@@ -491,10 +492,6 @@ messages -> WebPageProxy {
     DidHandleAcceptedCandidate()
 #endif
 
-#if PLATFORM(COCOA)
-    HandleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, String title, double duration, double elapsedTime)
-#endif
-
     SetIsUsingHighPerformanceWebGL(bool isUsingHighPerformanceWebGL)
 
     StartURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceRequest request)
index d42d567..5f0b049 100644 (file)
@@ -195,8 +195,6 @@ private:
 
     WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override;
 
-    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) override;
-
 #if USE(QUICK_LOOK)
     void requestPasswordForQuickLookDocument(const String& fileName, WTF::Function<void(const String&)>&&) override;
 #endif
index be2f5a1..d239b9e 100644 (file)
@@ -798,11 +798,6 @@ void PageClientImpl::didChangeDataInteractionCaretRect(const IntRect& previousCa
 }
 #endif
 
-void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime)
-{
-    [m_webView _handleActiveNowPlayingSessionInfoResponse:hasActiveSession title:nsStringFromWebCoreString(title) duration:duration elapsedTime:elapsedTime];
-}
-
 #if USE(QUICK_LOOK)
 void PageClientImpl::requestPasswordForQuickLookDocument(const String& fileName, WTF::Function<void(const String&)>&& completionHandler)
 {
index 54a9694..b31395a 100644 (file)
@@ -210,7 +210,6 @@ private:
     void didFailLoadForMainFrame() override;
     void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override;
     void handleControlledElementIDResponse(const String&) override;
-    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) override;
 
     void didPerformImmediateActionHitTest(const WebHitTestResultData&, bool contentPreventsDefault, API::Object*) override;
     void* immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult>, uint64_t, RefPtr<API::Object>) override;
index b25c32f..f16d90d 100644 (file)
@@ -789,13 +789,6 @@ void PageClientImpl::handleControlledElementIDResponse(const String& identifier)
 #endif
 }
 
-void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime)
-{
-#if WK_API_ENABLED
-    [m_webView _handleActiveNowPlayingSessionInfoResponse:hasActiveSession title:nsStringFromWebCoreString(title) duration:duration elapsedTime:elapsedTime];
-#endif
-}
-
 void PageClientImpl::didChangeBackgroundColor()
 {
     notImplemented();
index d40a0d7..65cfcab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,20 +41,22 @@ void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParamet
     m_dataDetectionContext = loadParameters.dataDetectionContext;
 }
 
-void WebPage::requestActiveNowPlayingSessionInfo()
+void WebPage::requestActiveNowPlayingSessionInfo(CallbackID callbackID)
 {
     bool hasActiveSession = false;
     String title = emptyString();
     double duration = NAN;
     double elapsedTime = NAN;
+    uint64_t uniqueIdentifier = 0;
     if (auto* sharedManager = WebCore::PlatformMediaSessionManager::sharedManagerIfExists()) {
         hasActiveSession = sharedManager->hasActiveNowPlayingSession();
         title = sharedManager->lastUpdatedNowPlayingTitle();
         duration = sharedManager->lastUpdatedNowPlayingDuration();
         elapsedTime = sharedManager->lastUpdatedNowPlayingElapsedTime();
+        uniqueIdentifier = sharedManager->lastUpdatedNowPlayingInfoUniqueIdentifier();
     }
 
-    send(Messages::WebPageProxy::HandleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime));
+    send(Messages::WebPageProxy::NowPlayingInfoCallback(hasActiveSession, title, duration, elapsedTime, uniqueIdentifier, callbackID));
 }
 
 } // namespace WebKit
index b84857b..a92a175 100644 (file)
@@ -1263,7 +1263,7 @@ private:
 #endif
 
 #if PLATFORM(COCOA)
-    void requestActiveNowPlayingSessionInfo();
+    void requestActiveNowPlayingSessionInfo(CallbackID);
 #endif
 
     void setShouldDispatchFakeMouseMoveEvents(bool dispatch) { m_shouldDispatchFakeMouseMoveEvents = dispatch; }
index 6baaa32..461098b 100644 (file)
@@ -437,7 +437,7 @@ messages -> WebPage LegacyReceiver {
 #endif
 
 #if PLATFORM(COCOA)
-    RequestActiveNowPlayingSessionInfo()
+    RequestActiveNowPlayingSessionInfo(WebKit::CallbackID callbackID)
 #endif
 
     SetShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents)
index 063e111..99bd8e0 100644 (file)
@@ -1,5 +1,17 @@
 2017-10-26  Eric Carlson  <eric.carlson@apple.com>
 
+        NowPlayingInfo should contain a unique identifier
+        https://bugs.webkit.org/show_bug.cgi?id=178872
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/NowPlayingControlsTests.mm:
+        (-[NowPlayingTestWebView hasActiveNowPlayingSession]): Use completion handler.
+        (TestWebKitAPI::TEST): Cleanup tests. Use new API.
+        (-[NowPlayingTestWebView waitForNowPlayingInfoToChange]): Deleted.
+
+2017-10-26  Eric Carlson  <eric.carlson@apple.com>
+
         [MediaStream] Clear cached gUM prompt state
         https://bugs.webkit.org/show_bug.cgi?id=178754
         <rdar://problem/32742356>
index 2ca1ddd..b5b35e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,6 +38,7 @@
 @property (readonly) NSString *lastUpdatedTitle;
 @property (readonly) double lastUpdatedDuration;
 @property (readonly) double lastUpdatedElapsedTime;
+@property (readonly) NSInteger lastUniqueIdentifier;
 @end
 
 @implementation NowPlayingTestWebView {
 - (BOOL)hasActiveNowPlayingSession
 {
     _receivedNowPlayingInfoResponse = false;
-    [self _requestActiveNowPlayingSessionInfo];
+
+    auto completionHandler = [retainedSelf = retainPtr(self), self](BOOL active, NSString *title, double duration, double elapsedTime, NSInteger uniqueIdentifier) {
+        _hasActiveNowPlayingSession = active;
+        _lastUpdatedTitle = [title copy];
+        _lastUpdatedDuration = duration;
+        _lastUniqueIdentifier = uniqueIdentifier;
+
+        _receivedNowPlayingInfoResponse = true;
+    };
+
+    [self _requestActiveNowPlayingSessionInfo:completionHandler];
+
     TestWebKitAPI::Util::run(&_receivedNowPlayingInfoResponse);
 
     return _hasActiveNowPlayingSession;
     }
 }
 
-- (void)waitForNowPlayingInfoToChange
-{
-    BOOL initialHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
-    NSString *initialTitle = self.lastUpdatedTitle;
-    double initialDuration = self.lastUpdatedDuration;
-    double initialElapsedTime = self.lastUpdatedElapsedTime;
-    while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
-        BOOL currentlyHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
-        if (initialHasActiveNowPlayingSession != currentlyHasActiveNowPlayingSession)
-            break;
-
-        if (initialDuration != self.lastUpdatedDuration)
-            break;
-
-        if (initialElapsedTime != self.lastUpdatedElapsedTime)
-            break;
-
-        if (![initialTitle isEqualToString:self.lastUpdatedTitle] && self.lastUpdatedTitle != initialTitle)
-            break;
-    }
-}
-
 - (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
 {
     _hasActiveNowPlayingSession = hasActiveSession;
@@ -111,76 +101,98 @@ TEST(NowPlayingControlsTests, NowPlayingControlsDoNotShowForForegroundPage)
 {
     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration];
+    auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
     [webView loadTestPageNamed:@"large-video-test-now-playing"];
     [webView waitForMessage:@"playing"];
 
     [webView setWindowVisible:YES];
-    [webView.window makeKeyWindow];
+    [webView.get().window makeKeyWindow];
     [webView expectHasActiveNowPlayingSession:NO];
 
-    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
-    ASSERT_EQ(10, webView.lastUpdatedDuration);
-    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
+    ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
+    ASSERT_EQ(10, webView.get().lastUpdatedDuration);
+    ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
 }
 
 TEST(NowPlayingControlsTests, NowPlayingControlsShowForBackgroundPage)
 {
     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration];
+    auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
     [webView loadTestPageNamed:@"large-video-test-now-playing"];
     [webView waitForMessage:@"playing"];
 
     [webView setWindowVisible:NO];
-    [webView.window resignKeyWindow];
+    [webView.get().window resignKeyWindow];
     [webView expectHasActiveNowPlayingSession:YES];
 
-    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
-    ASSERT_EQ(10, webView.lastUpdatedDuration);
-    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
+    ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
+    ASSERT_EQ(10, webView.get().lastUpdatedDuration);
+    ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
 }
 
 TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingKeepsSessionActive)
 {
     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration];
+    auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
     [webView loadTestPageNamed:@"large-video-test-now-playing"];
     [webView waitForMessage:@"playing"];
 
     [webView setWindowVisible:NO];
-    [webView.window resignKeyWindow];
+    [webView.get().window resignKeyWindow];
 
     [webView expectHasActiveNowPlayingSession:YES];
 
     [webView setWindowVisible:YES];
-    [webView.window makeKeyWindow];
+    [webView.get().window makeKeyWindow];
 
     [webView expectHasActiveNowPlayingSession:NO];
 
-    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
-    ASSERT_EQ(10, webView.lastUpdatedDuration);
-    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
+    ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
+    ASSERT_EQ(10, webView.get().lastUpdatedDuration);
+    ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
 }
 
 TEST(NowPlayingControlsTests, NowPlayingControlsClearInfoAfterSessionIsNoLongerValid)
 {
     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration];
+    auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration]);
     [webView loadTestPageNamed:@"large-video-test-now-playing"];
     [webView waitForMessage:@"playing"];
 
+    BOOL initialHasActiveNowPlayingSession = webView.get().hasActiveNowPlayingSession;
+    NSString *initialTitle = webView.get().lastUpdatedTitle;
+    double initialDuration = webView.get().lastUpdatedDuration;
+    double initialElapsedTime = webView.get().lastUpdatedElapsedTime;
+    NSInteger initialUniqueIdentifier = webView.get().lastUniqueIdentifier;
+
     [webView stringByEvaluatingJavaScript:@"document.querySelector('video').muted = true"];
     [webView setWindowVisible:NO];
-    [webView.window resignKeyWindow];
+    [webView.get().window resignKeyWindow];
+
+    while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
+        if (initialHasActiveNowPlayingSession != webView.get().hasActiveNowPlayingSession)
+            break;
+
+        if (initialUniqueIdentifier != webView.get().lastUniqueIdentifier)
+            break;
+
+        if (initialDuration != webView.get().lastUpdatedDuration)
+            break;
 
-    [webView waitForNowPlayingInfoToChange];
+        if (initialElapsedTime != webView.get().lastUpdatedElapsedTime)
+            break;
+
+        if (![initialTitle isEqualToString:webView.get().lastUpdatedTitle])
+            break;
+    }
 
-    ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
-    ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
-    ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
+    ASSERT_STREQ("", webView.get().lastUpdatedTitle.UTF8String);
+    ASSERT_TRUE(isnan(webView.get().lastUpdatedDuration));
+    ASSERT_TRUE(isnan(webView.get().lastUpdatedElapsedTime));
+    ASSERT_TRUE(!webView.get().lastUniqueIdentifier);
 }
 #endif // PLATFORM(MAC)
 
@@ -190,14 +202,14 @@ TEST(NowPlayingControlsTests, DISABLED_NowPlayingControlsIOS)
 {
     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration];
+    auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration]);
     [webView loadTestPageNamed:@"large-video-test-now-playing"];
     [webView waitForMessage:@"playing"];
 
     [webView expectHasActiveNowPlayingSession:YES];
-    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
-    ASSERT_EQ(10, webView.lastUpdatedDuration);
-    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
+    ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
+    ASSERT_EQ(10, webView.get().lastUpdatedDuration);
+    ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
 }
 #endif