[WebKitLegacy] Media playback pauses on scroll
[WebKit-https.git] / Source / WebCore / platform / audio / PlatformMediaSession.h
index 674adac..25c1779 100644 (file)
@@ -26,8 +26,8 @@
 #ifndef PlatformMediaSession_h
 #define PlatformMediaSession_h
 
-#include "MediaProducer.h"
 #include "Timer.h"
+#include <wtf/LoggerHelper.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
@@ -45,7 +45,11 @@ class PlatformMediaSession
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     : public MediaPlaybackTargetClient
 #endif
+#if !RELEASE_LOG_DISABLED
+    , private LoggerHelper
+#endif
 {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
     static std::unique_ptr<PlatformMediaSession> create(PlatformMediaSessionClient&);
 
@@ -55,14 +59,17 @@ public:
     enum MediaType {
         None = 0,
         Video,
+        VideoAudio,
         Audio,
         WebAudio,
+        MediaStreamCapturingAudio,
     };
     MediaType mediaType() const;
     MediaType presentationType() const;
 
     enum State {
         Idle,
+        Autoplaying,
         Playing,
         Paused,
         Interrupted,
@@ -71,30 +78,52 @@ public:
     void setState(State);
 
     enum InterruptionType {
+        NoInterruption,
         SystemSleep,
         EnteringBackground,
         SystemInterruption,
+        SuspendedUnderLock,
+        InvisibleAutoplay,
+        ProcessInactive,
+        PlaybackSuspended,
     };
+    InterruptionType interruptionType() const { return m_interruptionType; }
+
     enum EndInterruptionFlags {
         NoFlags = 0,
         MayResumePlaying = 1 << 0,
     };
+
+    enum Characteristics {
+        HasNothing = 0,
+        HasAudio = 1 << 0,
+        HasVideo = 1 << 1,
+    };
+    typedef unsigned CharacteristicsFlags;
+
+    CharacteristicsFlags characteristics() const;
+    void clientCharacteristicsChanged();
+
     void beginInterruption(InterruptionType);
     void endInterruption(EndInterruptionFlags);
 
-    void applicationWillEnterForeground() const;
-    void applicationWillEnterBackground() const;
-
-    bool clientWillBeginPlayback();
-    bool clientWillPausePlayback();
+    virtual void clientWillBeginAutoplaying();
+    virtual bool clientWillBeginPlayback();
+    virtual bool clientWillPausePlayback();
 
     void pauseSession();
+    void stopSession();
     
-    void visibilityChanged();
-
+#if ENABLE(VIDEO)
+    uint64_t uniqueIdentifier() const;
     String title() const;
     double duration() const;
     double currentTime() const;
+#endif
+
+    typedef union {
+        double asDouble;
+    } RemoteCommandArgument;
 
     enum RemoteControlCommandType {
         NoCommand,
@@ -106,9 +135,11 @@ public:
         EndSeekingBackwardCommand,
         BeginSeekingForwardCommand,
         EndSeekingForwardCommand,
+        SeekToPlaybackPositionCommand,
     };
     bool canReceiveRemoteControlCommands() const;
-    void didReceiveRemoteControlCommand(RemoteControlCommandType);
+    void didReceiveRemoteControlCommand(RemoteControlCommandType, const RemoteCommandArgument* argument = nullptr);
+    bool supportsSeeking() const;
 
     enum DisplayType {
         Normal,
@@ -118,34 +149,60 @@ public:
     DisplayType displayType() const;
 
     bool isHidden() const;
+    bool isSuspended() const;
 
-    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
-    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
+    bool shouldOverrideBackgroundLoadingRestriction() const;
+
+    virtual bool isPlayingToWirelessPlaybackTarget() const { return m_isPlayingToWirelessPlaybackTarget; }
+    void isPlayingToWirelessPlaybackTargetChanged(bool);
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     // MediaPlaybackTargetClient
-    virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override { }
-    virtual void externalOutputDeviceAvailableDidChange(bool) override { }
-    virtual void setShouldPlayToPlaybackTarget(bool) override { }
+    void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override { }
+    void externalOutputDeviceAvailableDidChange(bool) override { }
+    void setShouldPlayToPlaybackTarget(bool) override { }
 #endif
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS_FAMILY)
     virtual bool requiresPlaybackTargetRouteMonitoring() const { return false; }
 #endif
 
+    bool activeAudioSessionRequired();
+    bool canProduceAudio() const;
+    void canProduceAudioChanged();
+
+    virtual void resetPlaybackSessionState() { }
+    String sourceApplicationIdentifier() const;
+
+    virtual bool allowsNowPlayingControlsVisibility() const { return false; }
+
+    bool hasPlayedSinceLastInterruption() const { return m_hasPlayedSinceLastInterruption; }
+    void clearHasPlayedSinceLastInterruption() { m_hasPlayedSinceLastInterruption = false; }
+
 protected:
     PlatformMediaSessionClient& client() const { return m_client; }
 
-private:
-    void clientDataBufferingTimerFired();
-    void updateClientDataBuffering();
+#if !RELEASE_LOG_DISABLED
+    const Logger& logger() const final { return m_logger.get(); }
+    const void* logIdentifier() const override { return reinterpret_cast<const void*>(m_logIdentifier); }
+    const char* logClassName() const override { return "PlatformMediaSession"; }
+    WTFLogChannel& logChannel() const final;
+#endif
 
+private:
     PlatformMediaSessionClient& m_client;
-    Timer m_clientDataBufferingTimer;
     State m_state;
     State m_stateToRestore;
+    InterruptionType m_interruptionType { NoInterruption };
     int m_interruptionCount { 0 };
     bool m_notifyingClient;
+    bool m_isPlayingToWirelessPlaybackTarget { false };
+    bool m_hasPlayedSinceLastInterruption { false };
+
+#if !RELEASE_LOG_DISABLED
+    Ref<const Logger> m_logger;
+    uint64_t m_logIdentifier;
+#endif
 
     friend class PlatformMediaSessionManager;
 };
@@ -153,39 +210,84 @@ private:
 class PlatformMediaSessionClient {
     WTF_MAKE_NONCOPYABLE(PlatformMediaSessionClient);
 public:
-    PlatformMediaSessionClient() { }
+    PlatformMediaSessionClient() = default;
     
     virtual PlatformMediaSession::MediaType mediaType() const = 0;
     virtual PlatformMediaSession::MediaType presentationType() const = 0;
     virtual PlatformMediaSession::DisplayType displayType() const { return PlatformMediaSession::Normal; }
+    virtual PlatformMediaSession::CharacteristicsFlags characteristics() const = 0;
 
+    virtual void resumeAutoplaying() { }
     virtual void mayResumePlayback(bool shouldResume) = 0;
     virtual void suspendPlayback() = 0;
 
+#if ENABLE(VIDEO)
+    virtual uint64_t mediaSessionUniqueIdentifier() const;
     virtual String mediaSessionTitle() const;
     virtual double mediaSessionDuration() const;
     virtual double mediaSessionCurrentTime() const;
+#endif
     
     virtual bool canReceiveRemoteControlCommands() const = 0;
-    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) = 0;
+    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) = 0;
+    virtual bool supportsSeeking() const = 0;
 
-    virtual void setShouldBufferData(bool) { }
-    virtual bool elementIsHidden() const { return false; }
+    virtual bool canProduceAudio() const { return false; }
+    virtual bool isSuspended() const { return false; };
 
-    virtual bool overrideBackgroundPlaybackRestriction() const = 0;
+    virtual bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const = 0;
+    virtual bool shouldOverrideBackgroundLoadingRestriction() const { return false; }
 
     virtual void wirelessRoutesAvailableDidChange() { }
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) { }
-    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
     virtual void setShouldPlayToPlaybackTarget(bool) { }
 
+    virtual bool isPlayingOnSecondScreen() const { return false; }
+
     virtual Document* hostingDocument() const = 0;
+    virtual String sourceApplicationIdentifier() const = 0;
+
+    virtual bool processingUserGestureForMedia() const = 0;
 
 protected:
-    virtual ~PlatformMediaSessionClient() { }
+    virtual ~PlatformMediaSessionClient() = default;
 };
 
+String convertEnumerationToString(PlatformMediaSession::State);
+String convertEnumerationToString(PlatformMediaSession::InterruptionType);
+String convertEnumerationToString(PlatformMediaSession::RemoteControlCommandType);
 }
 
+namespace WTF {
+
+template<typename Type>
+struct LogArgument;
+
+template <>
+struct LogArgument<WebCore::PlatformMediaSession::State> {
+    static String toString(const WebCore::PlatformMediaSession::State state)
+    {
+        return convertEnumerationToString(state);
+    }
+};
+
+template <>
+struct LogArgument<WebCore::PlatformMediaSession::InterruptionType> {
+    static String toString(const WebCore::PlatformMediaSession::InterruptionType state)
+    {
+        return convertEnumerationToString(state);
+    }
+};
+
+template <>
+struct LogArgument<WebCore::PlatformMediaSession::RemoteControlCommandType> {
+    static String toString(const WebCore::PlatformMediaSession::RemoteControlCommandType command)
+    {
+        return convertEnumerationToString(command);
+    }
+};
+
+} // namespace WTF
+
 #endif // PlatformMediaSession_h