Diff
Modified: trunk/Source/WTF/ChangeLog (236010 => 236011)
--- trunk/Source/WTF/ChangeLog 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WTF/ChangeLog 2018-09-14 18:17:42 UTC (rev 236011)
@@ -1,3 +1,15 @@
+2018-09-14 Ryan Haddad <[email protected]>
+
+ Unreviewed, rolling out r235990.
+
+ Introduced TestWebKitAPI.NowPlayingTest timeouts on iOS
+
+ Reverted changeset:
+
+ "Enable USE_MEDIAREMOTE on iOS"
+ https://bugs.webkit.org/show_bug.cgi?id=189096
+ https://trac.webkit.org/changeset/235990
+
2018-09-13 Jer Noble <[email protected]>
Enable USE_MEDIAREMOTE on iOS
Modified: trunk/Source/WTF/wtf/Platform.h (236010 => 236011)
--- trunk/Source/WTF/wtf/Platform.h 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WTF/wtf/Platform.h 2018-09-14 18:17:42 UTC (rev 236011)
@@ -1303,7 +1303,7 @@
#endif
#endif
-#if PLATFORM(MAC) || PLATFORM(IOS)
+#if PLATFORM(MAC)
#define USE_MEDIAREMOTE 1
#endif
Modified: trunk/Source/WebCore/ChangeLog (236010 => 236011)
--- trunk/Source/WebCore/ChangeLog 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/ChangeLog 2018-09-14 18:17:42 UTC (rev 236011)
@@ -1,3 +1,15 @@
+2018-09-14 Ryan Haddad <[email protected]>
+
+ Unreviewed, rolling out r235990.
+
+ Introduced TestWebKitAPI.NowPlayingTest timeouts on iOS
+
+ Reverted changeset:
+
+ "Enable USE_MEDIAREMOTE on iOS"
+ https://bugs.webkit.org/show_bug.cgi?id=189096
+ https://trac.webkit.org/changeset/235990
+
2018-09-14 Jer Noble <[email protected]>
Turn SourceBufferChangeTypeEnabled on by default
Modified: trunk/Source/WebCore/SourcesCocoa.txt (236010 => 236011)
--- trunk/Source/WebCore/SourcesCocoa.txt 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2018-09-14 18:17:42 UTC (rev 236011)
@@ -159,7 +159,7 @@
platform/audio/AudioSession.cpp
-platform/audio/cocoa/MediaSessionManagerCocoa.mm
+platform/audio/cocoa/MediaSessionManagerCocoa.cpp
platform/audio/cocoa/WebAudioBufferList.cpp
platform/audio/ios/AudioDestinationIOS.cpp @no-unify
@@ -176,6 +176,7 @@
platform/audio/mac/AudioSessionMac.cpp
platform/audio/mac/CARingBuffer.cpp
platform/audio/mac/FFTFrameMac.cpp
+platform/audio/mac/MediaSessionManagerMac.mm
platform/cf/CFURLExtras.cpp
platform/cf/FileSystemCF.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (236010 => 236011)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-14 18:17:42 UTC (rev 236011)
@@ -3965,7 +3965,6 @@
CD063F831E23FA8900812BE3 /* InitDataRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = CD063F811E23FA8900812BE3 /* InitDataRegistry.h */; };
CD0EEE0E14743F39003EAFA2 /* AudioDestinationIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0EEE0B14743E35003EAFA2 /* AudioDestinationIOS.cpp */; };
CD127DEE14F3098400E84779 /* WebCoreFullScreenWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = CD127DEA14F3097900E84779 /* WebCoreFullScreenWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
- CD17A45D213740810079EC7B /* UnifiedSource62-mm.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD17A459213740160079EC7B /* UnifiedSource62-mm.mm */; };
CD19A2681A13E700008D650E /* DiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19A2671A13E700008D650E /* DiagnosticLoggingClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
CD19FEA81F573972000C42FB /* ImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19FEA61F573972000C42FB /* ImageDecoder.h */; };
CD19FEAE1F574B6D000C42FB /* ImageDecoderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19FEAC1F574B6D000C42FB /* ImageDecoderAVFObjC.h */; };
@@ -5440,6 +5439,7 @@
07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTarget.h; sourceTree = "<group>"; };
07E9E12D18F5E2760011A3A4 /* InbandMetadataTextTrackPrivateAVF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandMetadataTextTrackPrivateAVF.h; sourceTree = "<group>"; };
07E9E12F18F62B370011A3A4 /* InbandMetadataTextTrackPrivateAVF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandMetadataTextTrackPrivateAVF.cpp; sourceTree = "<group>"; };
+ 07EDC3ED1AACB75D00983EB5 /* MediaSessionManagerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaSessionManagerMac.mm; sourceTree = "<group>"; };
07EE76E91BE96DB000F89133 /* MockRealtimeVideoSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockRealtimeVideoSource.cpp; sourceTree = "<group>"; };
07EE76EA1BE96DB000F89133 /* MockRealtimeVideoSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockRealtimeVideoSource.h; sourceTree = "<group>"; };
07EE76ED1BEA619800F89133 /* MockRealtimeVideoSourceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockRealtimeVideoSourceMac.h; sourceTree = "<group>"; };
@@ -13187,7 +13187,6 @@
CD0EEE0B14743E35003EAFA2 /* AudioDestinationIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDestinationIOS.cpp; sourceTree = "<group>"; };
CD127DEA14F3097900E84779 /* WebCoreFullScreenWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenWindow.h; sourceTree = "<group>"; };
CD127DEB14F3097900E84779 /* WebCoreFullScreenWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenWindow.mm; sourceTree = "<group>"; };
- CD17A459213740160079EC7B /* UnifiedSource62-mm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UnifiedSource62-mm.mm"; sourceTree = "<group>"; };
CD19A2671A13E700008D650E /* DiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingClient.h; sourceTree = "<group>"; };
CD19FEA61F573972000C42FB /* ImageDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageDecoder.h; sourceTree = "<group>"; };
CD19FEA71F573972000C42FB /* ImageDecoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoder.cpp; sourceTree = "<group>"; };
@@ -13252,7 +13251,7 @@
CD641EB11818F5ED00EE4C41 /* MediaSourcePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSourcePrivate.h; sourceTree = "<group>"; };
CD641EB21818F5ED00EE4C41 /* SourceBufferPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceBufferPrivate.h; sourceTree = "<group>"; };
CD641EC7181ED60100EE4C41 /* MediaSample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaSample.h; sourceTree = "<group>"; };
- CD669D661D232DFF004D1866 /* MediaSessionManagerCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MediaSessionManagerCocoa.mm; path = cocoa/MediaSessionManagerCocoa.mm; sourceTree = "<group>"; };
+ CD669D671D232E10004D1866 /* MediaSessionManagerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSessionManagerMac.h; sourceTree = "<group>"; };
CD78A2EC1F75648600DE371B /* CDMInstanceFairPlayStreamingAVFObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDMInstanceFairPlayStreamingAVFObjC.mm; sourceTree = "<group>"; };
CD78A2EE1F75648600DE371B /* CDMInstanceFairPlayStreamingAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDMInstanceFairPlayStreamingAVFObjC.h; sourceTree = "<group>"; };
CD7D33411C7A123F00041293 /* PixelBufferConformerCV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PixelBufferConformerCV.cpp; sourceTree = "<group>"; };
@@ -18244,7 +18243,6 @@
538EC8791F993F31004D22A8 /* UnifiedSource60.cpp */,
DE5F863A1FA2AF07006DB63B /* UnifiedSource61-mm.mm */,
538EC87E1F993F33004D22A8 /* UnifiedSource61.cpp */,
- CD17A459213740160079EC7B /* UnifiedSource62-mm.mm */,
538EC85A1F993F20004D22A8 /* UnifiedSource62.cpp */,
538EC8611F993F24004D22A8 /* UnifiedSource63.cpp */,
538EC8421F993F14004D22A8 /* UnifiedSource64.cpp */,
@@ -26937,6 +26935,8 @@
CDC734121977896C0046BFC5 /* CARingBuffer.cpp */,
CDC734131977896C0046BFC5 /* CARingBuffer.h */,
FD3160BA12B0272A00C1A359 /* FFTFrameMac.cpp */,
+ CD669D671D232E10004D1866 /* MediaSessionManagerMac.h */,
+ 07EDC3ED1AACB75D00983EB5 /* MediaSessionManagerMac.mm */,
);
path = mac;
sourceTree = "<group>";
@@ -31325,7 +31325,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "set -e\n\ncd $SRCROOT\n\nif [ \"${DEPLOYMENT_LOCATION}\" == \"YES\" ]; then\nBUILD_SCRIPTS_DIR=\"${SDKROOT}${WK_ALTERNATE_WEBKIT_SDK_PATH}/usr/local/include/wtf/Scripts\"\nelse\nBUILD_SCRIPTS_DIR=\"${BUILT_PRODUCTS_DIR}/usr/local/include/wtf/Scripts\"\nfi\n\nUnifiedSourceCppFileCount=530\nUnifiedSourceMmFileCount=62\n\necho \"Using unified source list files: Sources.txt, SourcesCocoa.txt\"\n\n/usr/bin/env ruby \"${BUILD_SCRIPTS_DIR}/generate-unified-source-bundles.rb\" \"--derived-sources-path\" \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\" \"--source-tree-path\" \"${SRCROOT}\" \"--feature-flags\" \"${FEATURE_DEFINES}\" \"--max-cpp-bundle-count\" \"${UnifiedSourceCppFileCount}\" \"--max-obj-c-bundle-count\" \"${UnifiedSourceMmFileCount}\" \"Sources.txt\" \"SourcesCocoa.txt\
" > /dev/null\n";
+ shellScript = "set -e\n\ncd $SRCROOT\n\nif [ \"${DEPLOYMENT_LOCATION}\" == \"YES\" ]; then\nBUILD_SCRIPTS_DIR=\"${SDKROOT}${WK_ALTERNATE_WEBKIT_SDK_PATH}/usr/local/include/wtf/Scripts\"\nelse\nBUILD_SCRIPTS_DIR=\"${BUILT_PRODUCTS_DIR}/usr/local/include/wtf/Scripts\"\nfi\n\nUnifiedSourceCppFileCount=530\nUnifiedSourceMmFileCount=61\n\necho \"Using unified source list files: Sources.txt, SourcesCocoa.txt\"\n\n/usr/bin/env ruby \"${BUILD_SCRIPTS_DIR}/generate-unified-source-bundles.rb\" \"--derived-sources-path\" \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\" \"--source-tree-path\" \"${SRCROOT}\" \"--feature-flags\" \"${FEATURE_DEFINES}\" \"--max-cpp-bundle-count\" \"${UnifiedSourceCppFileCount}\" \"--max-obj-c-bundle-count\" \"${UnifiedSourceMmFileCount}\" \"Sources.txt\" \"SourcesCocoa.txt\&
quot; > /dev/null\n";
};
5D0D540D0E9862F60029E223 /* Check For Weak VTables and Externals */ = {
isa = PBXShellScriptBuildPhase;
@@ -31750,7 +31750,6 @@
DE5F86591FA2AF24006DB63B /* UnifiedSource61-mm.mm in Sources */,
538EC8AE1F993F9D004D22A8 /* UnifiedSource61.cpp in Sources */,
538EC8AF1F993F9D004D22A8 /* UnifiedSource62.cpp in Sources */,
- CD17A45D213740810079EC7B /* UnifiedSource62-mm.mm in Sources */,
538EC8B01F993F9D004D22A8 /* UnifiedSource63.cpp in Sources */,
538EC8B11F993F9D004D22A8 /* UnifiedSource64.cpp in Sources */,
538EC8B21F993F9D004D22A8 /* UnifiedSource65.cpp in Sources */,
Added: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.cpp (0 => 236011)
--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.cpp (rev 0)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.cpp 2018-09-14 18:17:42 UTC (rev 236011)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013-2014 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"
+#include "MediaSessionManagerCocoa.h"
+
+#if USE(AUDIO_SESSION)
+
+#include "AudioSession.h"
+#include "DeprecatedGlobalSettings.h"
+#include "Logging.h"
+#include <wtf/Function.h>
+
+using namespace WebCore;
+
+static const size_t kWebAudioBufferSize = 128;
+static const size_t kLowPowerVideoBufferSize = 4096;
+
+void MediaSessionManagerCocoa::updateSessionState()
+{
+ LOG(Media, "PlatformMediaSessionManager::scheduleUpdateSessionState() - types: Video(%d), Audio(%d), WebAudio(%d)", count(PlatformMediaSession::Video), count(PlatformMediaSession::Audio), count(PlatformMediaSession::WebAudio));
+
+ if (has(PlatformMediaSession::WebAudio))
+ AudioSession::sharedSession().setPreferredBufferSize(kWebAudioBufferSize);
+ // In case of audio capture, we want to grab 20 ms chunks to limit the latency so that it is not noticeable by users
+ // 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::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.
+
+ size_t bufferSize;
+ if (audioHardwareListener() && audioHardwareListener()->outputDeviceSupportsLowPowerMode())
+ bufferSize = kLowPowerVideoBufferSize;
+ else
+ bufferSize = kWebAudioBufferSize;
+
+ AudioSession::sharedSession().setPreferredBufferSize(bufferSize);
+ }
+
+ if (!DeprecatedGlobalSettings::shouldManageAudioSessionCategory())
+ return;
+
+ bool hasWebAudioType = false;
+ bool hasAudibleAudioOrVideoMediaType = false;
+ bool hasAudioCapture = anyOfSessions([&hasWebAudioType, &hasAudibleAudioOrVideoMediaType] (PlatformMediaSession& session, size_t) mutable {
+ auto type = session.mediaType();
+ if (type == PlatformMediaSession::WebAudio)
+ hasWebAudioType = true;
+ if ((type == PlatformMediaSession::VideoAudio || type == PlatformMediaSession::Audio) && session.canProduceAudio() && session.hasPlayedSinceLastInterruption())
+ hasAudibleAudioOrVideoMediaType = true;
+ if (session.isPlayingToWirelessPlaybackTarget())
+ hasAudibleAudioOrVideoMediaType = true;
+ return (type == PlatformMediaSession::MediaStreamCapturingAudio);
+ });
+
+ if (hasAudioCapture)
+ AudioSession::sharedSession().setCategory(AudioSession::PlayAndRecord);
+ else if (hasAudibleAudioOrVideoMediaType)
+ AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
+ else if (hasWebAudioType)
+ AudioSession::sharedSession().setCategory(AudioSession::AmbientSound);
+ else
+ AudioSession::sharedSession().setCategory(AudioSession::None);
+}
+
+void MediaSessionManagerCocoa::beginInterruption(PlatformMediaSession::InterruptionType type)
+{
+ if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
+ forEachSession([] (PlatformMediaSession& session, size_t) {
+ session.clearHasPlayedSinceLastInterruption();
+ });
+ }
+
+ PlatformMediaSessionManager::beginInterruption(type);
+}
+
+#endif // USE(AUDIO_SESSION)
Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h (236010 => 236011)
--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h 2018-09-14 18:17:42 UTC (rev 236011)
@@ -27,7 +27,6 @@
#if PLATFORM(COCOA)
-#include "GenericTaskQueue.h"
#include "PlatformMediaSessionManager.h"
namespace WebCore {
@@ -34,42 +33,8 @@
class MediaSessionManagerCocoa : public PlatformMediaSessionManager {
public:
- virtual ~MediaSessionManagerCocoa() = default;
-
void updateSessionState() override;
void beginInterruption(PlatformMediaSession::InterruptionType) override;
-
- 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; }
- bool registeredAsNowPlayingApplication() const final { return m_registeredAsNowPlayingApplication; }
-
-protected:
- void scheduleUpdateNowPlayingInfo() override;
- void updateNowPlayingInfo();
- void removeSession(PlatformMediaSession&) override;
-
- bool sessionWillBeginPlayback(PlatformMediaSession&) override;
- void sessionWillEndPlayback(PlatformMediaSession&) override;
- void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) override;
- void clientCharacteristicsChanged(PlatformMediaSession&) override;
- void sessionCanProduceAudioChanged(PlatformMediaSession&) override;
-
- PlatformMediaSession* nowPlayingEligibleSession();
-
-private:
- bool m_nowPlayingActive { false };
- bool m_registeredAsNowPlayingApplication { false };
-
- // For testing purposes only.
- String m_lastUpdatedNowPlayingTitle;
- double m_lastUpdatedNowPlayingDuration { NAN };
- double m_lastUpdatedNowPlayingElapsedTime { NAN };
- uint64_t m_lastUpdatedNowPlayingInfoUniqueIdentifier { 0 };
-
- GenericTaskQueue<Timer> m_nowPlayingUpdateTaskQueue;
};
}
Deleted: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (236010 => 236011)
--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm 2018-09-14 18:17:42 UTC (rev 236011)
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2013-2014 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"
-#include "MediaSessionManagerCocoa.h"
-
-#if USE(AUDIO_SESSION) && PLATFORM(COCOA)
-
-#include "AudioSession.h"
-#include "DeprecatedGlobalSettings.h"
-#include "HTMLMediaElement.h"
-#include "Logging.h"
-#include "MediaPlayer.h"
-#include "PlatformMediaSession.h"
-#include <wtf/BlockObjCExceptions.h>
-#include <wtf/Function.h>
-
-#include "MediaRemoteSoftLink.h"
-
-using namespace WebCore;
-
-static const size_t kWebAudioBufferSize = 128;
-static const size_t kLowPowerVideoBufferSize = 4096;
-
-#if PLATFORM(MAC)
-static MediaSessionManagerCocoa* platformMediaSessionManager = nullptr;
-
-PlatformMediaSessionManager& PlatformMediaSessionManager::sharedManager()
-{
- if (!platformMediaSessionManager)
- platformMediaSessionManager = new MediaSessionManagerCocoa;
- return *platformMediaSessionManager;
-}
-
-PlatformMediaSessionManager* PlatformMediaSessionManager::sharedManagerIfExists()
-{
- return platformMediaSessionManager;
-}
-#endif
-
-void MediaSessionManagerCocoa::updateSessionState()
-{
- LOG(Media, "PlatformMediaSessionManager::scheduleUpdateSessionState() - types: Video(%d), Audio(%d), WebAudio(%d)", count(PlatformMediaSession::Video), count(PlatformMediaSession::Audio), count(PlatformMediaSession::WebAudio));
-
- if (has(PlatformMediaSession::WebAudio))
- AudioSession::sharedSession().setPreferredBufferSize(kWebAudioBufferSize);
- // In case of audio capture, we want to grab 20 ms chunks to limit the latency so that it is not noticeable by users
- // 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::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.
-
- size_t bufferSize;
- if (audioHardwareListener() && audioHardwareListener()->outputDeviceSupportsLowPowerMode())
- bufferSize = kLowPowerVideoBufferSize;
- else
- bufferSize = kWebAudioBufferSize;
-
- AudioSession::sharedSession().setPreferredBufferSize(bufferSize);
- }
-
- if (!DeprecatedGlobalSettings::shouldManageAudioSessionCategory())
- return;
-
- bool hasWebAudioType = false;
- bool hasAudibleAudioOrVideoMediaType = false;
- bool hasAudioCapture = anyOfSessions([&hasWebAudioType, &hasAudibleAudioOrVideoMediaType] (PlatformMediaSession& session, size_t) mutable {
- auto type = session.mediaType();
- if (type == PlatformMediaSession::WebAudio)
- hasWebAudioType = true;
- if ((type == PlatformMediaSession::VideoAudio || type == PlatformMediaSession::Audio) && session.canProduceAudio() && session.hasPlayedSinceLastInterruption())
- hasAudibleAudioOrVideoMediaType = true;
- if (session.isPlayingToWirelessPlaybackTarget())
- hasAudibleAudioOrVideoMediaType = true;
- return (type == PlatformMediaSession::MediaStreamCapturingAudio);
- });
-
- if (hasAudioCapture)
- AudioSession::sharedSession().setCategory(AudioSession::PlayAndRecord);
- else if (hasAudibleAudioOrVideoMediaType)
- AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
- else if (hasWebAudioType)
- AudioSession::sharedSession().setCategory(AudioSession::AmbientSound);
- else
- AudioSession::sharedSession().setCategory(AudioSession::None);
-}
-
-void MediaSessionManagerCocoa::beginInterruption(PlatformMediaSession::InterruptionType type)
-{
- if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
- forEachSession([] (PlatformMediaSession& session, size_t) {
- session.clearHasPlayedSinceLastInterruption();
- });
- }
-
- PlatformMediaSessionManager::beginInterruption(type);
-}
-
-void MediaSessionManagerCocoa::scheduleUpdateNowPlayingInfo()
-{
- if (!m_nowPlayingUpdateTaskQueue.hasPendingTasks())
- m_nowPlayingUpdateTaskQueue.enqueueTask(std::bind(&MediaSessionManagerCocoa::updateNowPlayingInfo, this));
-}
-
-bool MediaSessionManagerCocoa::sessionWillBeginPlayback(PlatformMediaSession& session)
-{
- if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
- return false;
-
- LOG(Media, "MediaSessionManagerCocoa::sessionWillBeginPlayback");
- scheduleUpdateNowPlayingInfo();
- return true;
-}
-
-void MediaSessionManagerCocoa::sessionDidEndRemoteScrubbing(const PlatformMediaSession&)
-{
- scheduleUpdateNowPlayingInfo();
-}
-
-void MediaSessionManagerCocoa::removeSession(PlatformMediaSession& session)
-{
- PlatformMediaSessionManager::removeSession(session);
- LOG(Media, "MediaSessionManagerCocoa::removeSession");
- scheduleUpdateNowPlayingInfo();
-}
-
-void MediaSessionManagerCocoa::sessionWillEndPlayback(PlatformMediaSession& session)
-{
- PlatformMediaSessionManager::sessionWillEndPlayback(session);
- LOG(Media, "MediaSessionManagerCocoa::sessionWillEndPlayback");
- updateNowPlayingInfo();
-}
-
-void MediaSessionManagerCocoa::clientCharacteristicsChanged(PlatformMediaSession&)
-{
- LOG(Media, "MediaSessionManagerCocoa::clientCharacteristicsChanged");
- scheduleUpdateNowPlayingInfo();
-}
-
-void MediaSessionManagerCocoa::sessionCanProduceAudioChanged(PlatformMediaSession& session)
-{
- PlatformMediaSessionManager::sessionCanProduceAudioChanged(session);
- scheduleUpdateNowPlayingInfo();
-}
-
-PlatformMediaSession* MediaSessionManagerCocoa::nowPlayingEligibleSession()
-{
- if (auto element = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
- return &element->mediaSession();
-
- return nullptr;
-}
-
-void MediaSessionManagerCocoa::updateNowPlayingInfo()
-{
-#if USE(MEDIAREMOTE)
- if (!isMediaRemoteFrameworkAvailable())
- return;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- const PlatformMediaSession* currentSession = this->nowPlayingEligibleSession();
-
- LOG(Media, "MediaSessionManagerCocoa::updateNowPlayingInfo - currentSession = %p", currentSession);
-
- if (!currentSession) {
- if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
- MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
-
- LOG(Media, "MediaSessionManagerCocoa::updateNowPlayingInfo - clearing now playing info");
-
- MRMediaRemoteSetCanBeNowPlayingApplication(false);
- m_registeredAsNowPlayingApplication = false;
-
- MRMediaRemoteSetNowPlayingInfo(nullptr);
- m_nowPlayingActive = false;
- 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
- if (error)
- LOG(Media, "MediaSessionManagerCocoa::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
-#endif
- });
-
- return;
- }
-
- if (!m_registeredAsNowPlayingApplication) {
- m_registeredAsNowPlayingApplication = true;
- MRMediaRemoteSetCanBeNowPlayingApplication(true);
- }
-
- String title = currentSession->title();
- double duration = currentSession->supportsSeeking() ? currentSession->duration() : MediaPlayer::invalidTime();
- double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
- auto info = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
- if (!title.isEmpty()) {
- CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoTitle, title.createCFString().get());
- m_lastUpdatedNowPlayingTitle = title;
- }
-
- if (std::isfinite(duration) && duration != MediaPlayer::invalidTime()) {
- auto cfDuration = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &duration));
- CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoDuration, cfDuration.get());
- m_lastUpdatedNowPlayingDuration = duration;
- }
-
- auto cfRate = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate));
- CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate.get());
-
- m_lastUpdatedNowPlayingInfoUniqueIdentifier = currentSession->uniqueIdentifier();
- 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()) {
- auto cfCurrentTime = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, ¤tTime));
- CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoElapsedTime, cfCurrentTime.get());
- m_lastUpdatedNowPlayingElapsedTime = currentTime;
- }
-
- LOG(Media, "MediaSessionManagerCocoa::updateNowPlayingInfo - title = \"%s\", rate = %f, duration = %f, now = %f",
- title.utf8().data(), rate, duration, currentTime);
-
- String parentApplication = currentSession->sourceApplicationIdentifier();
- if (canLoad_MediaRemote_MRMediaRemoteSetParentApplication() && !parentApplication.isEmpty())
- MRMediaRemoteSetParentApplication(MRMediaRemoteGetLocalOrigin(), parentApplication.createCFString().get());
-
- m_nowPlayingActive = currentSession->allowsNowPlayingControlsVisibility();
- MRPlaybackState playbackState = (currentSession->state() == PlatformMediaSession::Playing) ? kMRPlaybackStatePlaying : kMRPlaybackStatePaused;
- MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), playbackState, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
-#if LOG_DISABLED
- UNUSED_PARAM(error);
-#else
- LOG(Media, "MediaSessionManagerCocoa::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(playing) failed with error %ud", error);
-#endif
- });
- MRMediaRemoteSetNowPlayingInfo(info.get());
-
- if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility()) {
- MRNowPlayingClientVisibility visibility = currentSession->allowsNowPlayingControlsVisibility() ? MRNowPlayingClientVisibilityAlwaysVisible : MRNowPlayingClientVisibilityNeverVisible;
- MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), visibility);
- }
- END_BLOCK_OBJC_EXCEPTIONS
-#endif // USE(MEDIAREMOTE)
-}
-
-#endif // USE(AUDIO_SESSION)
Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h (236010 => 236011)
--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h 2018-09-14 18:17:42 UTC (rev 236011)
@@ -53,11 +53,34 @@
MediaSessionManageriOS();
+ void removeSession(PlatformMediaSession&) override;
+
+ bool sessionWillBeginPlayback(PlatformMediaSession&) override;
+ void sessionWillEndPlayback(PlatformMediaSession&) override;
+ void clientCharacteristicsChanged(PlatformMediaSession&) override;
+
+ void updateNowPlayingInfo();
+
void resetRestrictions() override;
void configureWireLessTargetMonitoring() override;
+ bool hasActiveNowPlayingSession() const final { return m_nowPlayingActive; }
+ 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; }
+ bool registeredAsNowPlayingApplication() const final { return m_nowPlayingActive; }
+
+ PlatformMediaSession* nowPlayingEligibleSession();
+
RetainPtr<WebMediaSessionHelper> m_objcObserver;
+ double m_reportedRate { 0 };
+ double m_reportedDuration { 0 };
+ double m_reportedCurrentTime { 0 };
+ uint64_t m_lastUpdatedNowPlayingInfoUniqueIdentifier { 0 };
+ String m_reportedTitle;
+ bool m_nowPlayingActive { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm (236010 => 236011)
--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2018-09-14 17:03:35 UTC (rev 236010)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2018-09-14 18:17:42 UTC (rev 236011)
@@ -43,6 +43,12 @@
#import <wtf/RetainPtr.h>
#import <wtf/SoftLinking.h>
+#if HAVE(MEDIA_PLAYER)
+#import <MediaPlayer/MPMediaItem.h>
+#import <MediaPlayer/MPNowPlayingInfoCenter.h>
+#import <pal/spi/ios/MediaPlayerSPI.h>
+#endif
+
SOFT_LINK_FRAMEWORK(AVFoundation)
SOFT_LINK_CLASS(AVFoundation, AVAudioSession)
SOFT_LINK_CONSTANT(AVFoundation, AVAudioSessionInterruptionNotification, NSString *)
@@ -72,6 +78,22 @@
#define UIApplicationDidBecomeActiveNotification getUIApplicationDidBecomeActiveNotification()
#define UIApplicationDidEnterBackgroundNotification getUIApplicationDidEnterBackgroundNotification()
+#if HAVE(MEDIA_PLAYER)
+SOFT_LINK_FRAMEWORK(MediaPlayer)
+SOFT_LINK_CLASS(MediaPlayer, MPNowPlayingInfoCenter)
+SOFT_LINK_CONSTANT(MediaPlayer, MPMediaItemPropertyTitle, NSString *)
+SOFT_LINK_CONSTANT(MediaPlayer, MPMediaItemPropertyPlaybackDuration, NSString *)
+SOFT_LINK_CONSTANT(MediaPlayer, MPNowPlayingInfoPropertyElapsedPlaybackTime, NSString *)
+SOFT_LINK_CONSTANT(MediaPlayer, MPNowPlayingInfoPropertyPlaybackRate, NSString *)
+SOFT_LINK_CONSTANT(MediaPlayer, kMRMediaRemoteNowPlayingInfoUniqueIdentifier, NSString *)
+
+#define MPMediaItemPropertyTitle getMPMediaItemPropertyTitle()
+#define MPMediaItemPropertyPlaybackDuration getMPMediaItemPropertyPlaybackDuration()
+#define MPNowPlayingInfoPropertyElapsedPlaybackTime getMPNowPlayingInfoPropertyElapsedPlaybackTime()
+#define MPNowPlayingInfoPropertyPlaybackRate getMPNowPlayingInfoPropertyPlaybackRate()
+#define kMRMediaRemoteNowPlayingInfoUniqueIdentifier getkMRMediaRemoteNowPlayingInfoUniqueIdentifier()
+#endif // HAVE(MEDIA_PLAYER)
+
WEBCORE_EXPORT NSString* WebUIApplicationWillResignActiveNotification = @"WebUIApplicationWillResignActiveNotification";
WEBCORE_EXPORT NSString* WebUIApplicationWillEnterForegroundNotification = @"WebUIApplicationWillEnterForegroundNotification";
WEBCORE_EXPORT NSString* WebUIApplicationDidBecomeActiveNotification = @"WebUIApplicationDidBecomeActiveNotification";
@@ -182,6 +204,104 @@
#endif
}
+bool MediaSessionManageriOS::sessionWillBeginPlayback(PlatformMediaSession& session)
+{
+ if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
+ return false;
+
+ LOG(Media, "MediaSessionManageriOS::sessionWillBeginPlayback");
+ updateNowPlayingInfo();
+ return true;
+}
+
+void MediaSessionManageriOS::removeSession(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::removeSession(session);
+ LOG(Media, "MediaSessionManageriOS::removeSession");
+ updateNowPlayingInfo();
+}
+
+void MediaSessionManageriOS::sessionWillEndPlayback(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::sessionWillEndPlayback(session);
+ LOG(Media, "MediaSessionManageriOS::sessionWillEndPlayback");
+ updateNowPlayingInfo();
+}
+
+void MediaSessionManageriOS::clientCharacteristicsChanged(PlatformMediaSession&)
+{
+ LOG(Media, "MediaSessionManageriOS::clientCharacteristicsChanged");
+ updateNowPlayingInfo();
+}
+
+PlatformMediaSession* MediaSessionManageriOS::nowPlayingEligibleSession()
+{
+ return findSession([] (PlatformMediaSession& session, size_t) {
+ PlatformMediaSession::MediaType type = session.mediaType();
+ if (type != PlatformMediaSession::VideoAudio && type != PlatformMediaSession::Audio)
+ return false;
+
+ if (session.characteristics() & PlatformMediaSession::HasAudio)
+ return true;
+
+ return false;
+ });
+}
+
+void MediaSessionManageriOS::updateNowPlayingInfo()
+{
+#if HAVE(MEDIA_PLAYER)
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ MPNowPlayingInfoCenter *nowPlaying = (MPNowPlayingInfoCenter *)[getMPNowPlayingInfoCenterClass() defaultCenter];
+ const PlatformMediaSession* currentSession = this->nowPlayingEligibleSession();
+
+ LOG(Media, "MediaSessionManageriOS::updateNowPlayingInfo - currentSession = %p", currentSession);
+
+ if (!currentSession) {
+ if (m_nowPlayingActive) {
+ LOG(Media, "MediaSessionManageriOS::updateNowPlayingInfo - clearing now playing info");
+ [nowPlaying setNowPlayingInfo:nil];
+ m_nowPlayingActive = false;
+ }
+
+ return;
+ }
+
+ String title = currentSession->title();
+ double duration = currentSession->duration();
+ double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
+ double currentTime = currentSession->currentTime();
+ if (m_reportedTitle == title && m_reportedRate == rate && m_reportedDuration == duration) {
+ LOG(Media, "MediaSessionManageriOS::updateNowPlayingInfo - nothing new to show");
+ return;
+ }
+
+ m_reportedRate = rate;
+ m_reportedDuration = duration;
+ m_reportedTitle = title;
+ m_reportedCurrentTime = currentTime;
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = currentSession->uniqueIdentifier();
+
+ auto info = adoptNS([[NSMutableDictionary alloc] init]);
+ if (!title.isEmpty())
+ info.get()[MPMediaItemPropertyTitle] = static_cast<NSString *>(title);
+ if (std::isfinite(duration) && duration != MediaPlayer::invalidTime())
+ info.get()[MPMediaItemPropertyPlaybackDuration] = @(duration);
+ info.get()[MPNowPlayingInfoPropertyPlaybackRate] = @(rate);
+ info.get()[kMRMediaRemoteNowPlayingInfoUniqueIdentifier] = @(title.impl() ? title.impl()->hash() : 0);
+
+ if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime())
+ info.get()[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(currentTime);
+
+ LOG(Media, "MediaSessionManageriOS::updateNowPlayingInfo - title = \"%s\", rate = %f, duration = %f, now = %f",
+ title.utf8().data(), rate, duration, currentTime);
+
+ m_nowPlayingActive = true;
+ [nowPlaying setNowPlayingInfo:info.get()];
+ END_BLOCK_OBJC_EXCEPTIONS
+#endif // HAVE(MEDIA_PLAYER)
+}
+
void MediaSessionManageriOS::externalOutputDeviceAvailableDidChange()
{
BEGIN_BLOCK_OBJC_EXCEPTIONS
Copied: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h (from rev 236010, trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h) (0 => 236011)
--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h (rev 0)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h 2018-09-14 18:17:42 UTC (rev 236011)
@@ -0,0 +1,79 @@
+/*
+ * 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
+ * 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.
+ */
+
+#pragma once
+
+#if PLATFORM(MAC)
+
+#include "GenericTaskQueue.h"
+#include "MediaSessionManagerCocoa.h"
+
+namespace WebCore {
+
+class MediaSessionManagerMac : public MediaSessionManagerCocoa {
+public:
+ virtual ~MediaSessionManagerMac();
+
+ 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; }
+ bool registeredAsNowPlayingApplication() const final { return m_registeredAsNowPlayingApplication; }
+
+private:
+ friend class PlatformMediaSessionManager;
+
+ MediaSessionManagerMac();
+
+ void scheduleUpdateNowPlayingInfo() override;
+ void removeSession(PlatformMediaSession&) override;
+
+ bool sessionWillBeginPlayback(PlatformMediaSession&) override;
+ void sessionWillEndPlayback(PlatformMediaSession&) override;
+ void sessionDidEndRemoteScrubbing(const PlatformMediaSession&) override;
+ void clientCharacteristicsChanged(PlatformMediaSession&) override;
+ void sessionCanProduceAudioChanged(PlatformMediaSession&) override;
+
+ void updateNowPlayingInfo();
+
+ PlatformMediaSession* nowPlayingEligibleSession();
+
+ bool m_nowPlayingActive { false };
+ bool m_isInBackground { false };
+ bool m_registeredAsNowPlayingApplication { false };
+
+ // For testing purposes only.
+ String m_lastUpdatedNowPlayingTitle;
+ double m_lastUpdatedNowPlayingDuration { NAN };
+ double m_lastUpdatedNowPlayingElapsedTime { NAN };
+ uint64_t m_lastUpdatedNowPlayingInfoUniqueIdentifier { 0 };
+
+ GenericTaskQueue<Timer> m_nowPlayingUpdateTaskQueue;
+};
+
+} // namespace WebCore
+
+#endif // PLATFORM(MAC)
Copied: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (from rev 236010, trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm) (0 => 236011)
--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (rev 0)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm 2018-09-14 18:17:42 UTC (rev 236011)
@@ -0,0 +1,224 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "MediaSessionManagerMac.h"
+
+#if PLATFORM(MAC)
+
+#import "HTMLMediaElement.h"
+#import "Logging.h"
+#import "MediaPlayer.h"
+#import "PlatformMediaSession.h"
+#import <wtf/BlockObjCExceptions.h>
+
+#import "MediaRemoteSoftLink.h"
+
+using namespace WebCore;
+
+namespace WebCore {
+
+static MediaSessionManagerMac* platformMediaSessionManager = nullptr;
+
+PlatformMediaSessionManager& PlatformMediaSessionManager::sharedManager()
+{
+ if (!platformMediaSessionManager)
+ platformMediaSessionManager = new MediaSessionManagerMac;
+ return *platformMediaSessionManager;
+}
+
+PlatformMediaSessionManager* PlatformMediaSessionManager::sharedManagerIfExists()
+{
+ return platformMediaSessionManager;
+}
+
+MediaSessionManagerMac::MediaSessionManagerMac()
+ : MediaSessionManagerCocoa()
+{
+ resetRestrictions();
+}
+
+MediaSessionManagerMac::~MediaSessionManagerMac()
+{
+}
+
+void MediaSessionManagerMac::scheduleUpdateNowPlayingInfo()
+{
+ if (!m_nowPlayingUpdateTaskQueue.hasPendingTasks())
+ m_nowPlayingUpdateTaskQueue.enqueueTask(std::bind(&MediaSessionManagerMac::updateNowPlayingInfo, this));
+}
+
+bool MediaSessionManagerMac::sessionWillBeginPlayback(PlatformMediaSession& session)
+{
+ if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
+ return false;
+
+ LOG(Media, "MediaSessionManagerMac::sessionWillBeginPlayback");
+ scheduleUpdateNowPlayingInfo();
+ return true;
+}
+
+void MediaSessionManagerMac::sessionDidEndRemoteScrubbing(const PlatformMediaSession&)
+{
+ scheduleUpdateNowPlayingInfo();
+}
+
+void MediaSessionManagerMac::removeSession(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::removeSession(session);
+ LOG(Media, "MediaSessionManagerMac::removeSession");
+ scheduleUpdateNowPlayingInfo();
+}
+
+void MediaSessionManagerMac::sessionWillEndPlayback(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::sessionWillEndPlayback(session);
+ LOG(Media, "MediaSessionManagerMac::sessionWillEndPlayback");
+ updateNowPlayingInfo();
+}
+
+void MediaSessionManagerMac::clientCharacteristicsChanged(PlatformMediaSession&)
+{
+ LOG(Media, "MediaSessionManagerMac::clientCharacteristicsChanged");
+ scheduleUpdateNowPlayingInfo();
+}
+
+void MediaSessionManagerMac::sessionCanProduceAudioChanged(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::sessionCanProduceAudioChanged(session);
+ scheduleUpdateNowPlayingInfo();
+}
+
+PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession()
+{
+ if (auto element = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+ return &element->mediaSession();
+
+ return nullptr;
+}
+
+void MediaSessionManagerMac::updateNowPlayingInfo()
+{
+#if USE(MEDIAREMOTE)
+ if (!isMediaRemoteFrameworkAvailable())
+ return;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ const PlatformMediaSession* currentSession = this->nowPlayingEligibleSession();
+
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - currentSession = %p", currentSession);
+
+ if (!currentSession) {
+ if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
+ MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
+
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
+
+ MRMediaRemoteSetCanBeNowPlayingApplication(false);
+ m_registeredAsNowPlayingApplication = false;
+
+ MRMediaRemoteSetNowPlayingInfo(nullptr);
+ m_nowPlayingActive = false;
+ 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
+ if (error)
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
+#endif
+ });
+
+ return;
+ }
+
+ if (!m_registeredAsNowPlayingApplication) {
+ m_registeredAsNowPlayingApplication = true;
+ MRMediaRemoteSetCanBeNowPlayingApplication(true);
+ }
+
+ String title = currentSession->title();
+ double duration = currentSession->supportsSeeking() ? currentSession->duration() : MediaPlayer::invalidTime();
+ double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
+ auto info = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ if (!title.isEmpty()) {
+ CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoTitle, title.createCFString().get());
+ m_lastUpdatedNowPlayingTitle = title;
+ }
+
+ if (std::isfinite(duration) && duration != MediaPlayer::invalidTime()) {
+ auto cfDuration = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &duration));
+ CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoDuration, cfDuration.get());
+ m_lastUpdatedNowPlayingDuration = duration;
+ }
+
+ auto cfRate = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate));
+ CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate.get());
+
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = currentSession->uniqueIdentifier();
+ 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()) {
+ auto cfCurrentTime = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, ¤tTime));
+ CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoElapsedTime, cfCurrentTime.get());
+ m_lastUpdatedNowPlayingElapsedTime = currentTime;
+ }
+
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - title = \"%s\", rate = %f, duration = %f, now = %f",
+ title.utf8().data(), rate, duration, currentTime);
+
+ String parentApplication = currentSession->sourceApplicationIdentifier();
+ if (canLoad_MediaRemote_MRMediaRemoteSetParentApplication() && !parentApplication.isEmpty())
+ MRMediaRemoteSetParentApplication(MRMediaRemoteGetLocalOrigin(), parentApplication.createCFString().get());
+
+ m_nowPlayingActive = currentSession->allowsNowPlayingControlsVisibility();
+ MRPlaybackState playbackState = (currentSession->state() == PlatformMediaSession::Playing) ? kMRPlaybackStatePlaying : kMRPlaybackStatePaused;
+ MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), playbackState, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
+#if LOG_DISABLED
+ UNUSED_PARAM(error);
+#else
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(playing) failed with error %ud", error);
+#endif
+ });
+ MRMediaRemoteSetNowPlayingInfo(info.get());
+
+ if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility()) {
+ MRNowPlayingClientVisibility visibility = currentSession->allowsNowPlayingControlsVisibility() ? MRNowPlayingClientVisibilityAlwaysVisible : MRNowPlayingClientVisibilityNeverVisible;
+ MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), visibility);
+ }
+ END_BLOCK_OBJC_EXCEPTIONS
+#endif // USE(MEDIAREMOTE)
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(MAC)