Implement the Remote Playback API.
[WebKit-https.git] / Source / WebCore / platform / audio / PlatformMediaSession.h
1 /*
2  * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef PlatformMediaSession_h
27 #define PlatformMediaSession_h
28
29 #include "Timer.h"
30 #include <wtf/LoggerHelper.h>
31 #include <wtf/Noncopyable.h>
32 #include <wtf/WeakPtr.h>
33 #include <wtf/text/WTFString.h>
34
35 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
36 #include "MediaPlaybackTargetClient.h"
37 #endif
38
39 namespace WebCore {
40
41 class Document;
42 class MediaPlaybackTarget;
43 class PlatformMediaSessionClient;
44
45 class PlatformMediaSession
46     : public CanMakeWeakPtr<PlatformMediaSession>
47 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
48     , public MediaPlaybackTargetClient
49 #endif
50 #if !RELEASE_LOG_DISABLED
51     , private LoggerHelper
52 #endif
53 {
54     WTF_MAKE_FAST_ALLOCATED;
55 public:
56     static std::unique_ptr<PlatformMediaSession> create(PlatformMediaSessionClient&);
57
58     PlatformMediaSession(PlatformMediaSessionClient&);
59     virtual ~PlatformMediaSession();
60
61     enum MediaType {
62         None = 0,
63         Video,
64         VideoAudio,
65         Audio,
66         WebAudio,
67         MediaStreamCapturingAudio,
68     };
69     MediaType mediaType() const;
70     MediaType presentationType() const;
71
72     enum State {
73         Idle,
74         Autoplaying,
75         Playing,
76         Paused,
77         Interrupted,
78     };
79     State state() const { return m_state; }
80     void setState(State);
81
82     enum InterruptionType {
83         NoInterruption,
84         SystemSleep,
85         EnteringBackground,
86         SystemInterruption,
87         SuspendedUnderLock,
88         InvisibleAutoplay,
89         ProcessInactive,
90         PlaybackSuspended,
91     };
92     InterruptionType interruptionType() const { return m_interruptionType; }
93
94     enum EndInterruptionFlags {
95         NoFlags = 0,
96         MayResumePlaying = 1 << 0,
97     };
98
99     enum Characteristics {
100         HasNothing = 0,
101         HasAudio = 1 << 0,
102         HasVideo = 1 << 1,
103     };
104     typedef unsigned CharacteristicsFlags;
105
106     CharacteristicsFlags characteristics() const;
107     void clientCharacteristicsChanged();
108
109     void beginInterruption(InterruptionType);
110     void endInterruption(EndInterruptionFlags);
111
112     virtual void clientWillBeginAutoplaying();
113     virtual bool clientWillBeginPlayback();
114     virtual bool clientWillPausePlayback();
115
116     void pauseSession();
117     void stopSession();
118
119     virtual void suspendBuffering() { }
120     virtual void resumeBuffering() { }
121     
122 #if ENABLE(VIDEO)
123     uint64_t uniqueIdentifier() const;
124     String title() const;
125     double duration() const;
126     double currentTime() const;
127 #endif
128
129     typedef union {
130         double asDouble;
131     } RemoteCommandArgument;
132
133     enum RemoteControlCommandType {
134         NoCommand,
135         PlayCommand,
136         PauseCommand,
137         StopCommand,
138         TogglePlayPauseCommand,
139         BeginSeekingBackwardCommand,
140         EndSeekingBackwardCommand,
141         BeginSeekingForwardCommand,
142         EndSeekingForwardCommand,
143         SeekToPlaybackPositionCommand,
144     };
145     bool canReceiveRemoteControlCommands() const;
146     void didReceiveRemoteControlCommand(RemoteControlCommandType, const RemoteCommandArgument* argument = nullptr);
147     bool supportsSeeking() const;
148
149     enum DisplayType {
150         Normal,
151         Fullscreen,
152         Optimized,
153     };
154     DisplayType displayType() const;
155
156     bool isHidden() const;
157     bool isSuspended() const;
158
159     bool shouldOverrideBackgroundLoadingRestriction() const;
160
161     virtual bool isPlayingToWirelessPlaybackTarget() const { return m_isPlayingToWirelessPlaybackTarget; }
162     void isPlayingToWirelessPlaybackTargetChanged(bool);
163
164 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
165     // MediaPlaybackTargetClient
166     void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override { }
167     void externalOutputDeviceAvailableDidChange(bool) override { }
168     void setShouldPlayToPlaybackTarget(bool) override { }
169     void playbackTargetPickerWasDismissed() override { }
170 #endif
171
172 #if PLATFORM(IOS_FAMILY)
173     virtual bool requiresPlaybackTargetRouteMonitoring() const { return false; }
174 #endif
175
176     bool activeAudioSessionRequired() const;
177     bool canProduceAudio() const;
178     void canProduceAudioChanged();
179
180     virtual void resetPlaybackSessionState() { }
181     String sourceApplicationIdentifier() const;
182
183     virtual bool allowsNowPlayingControlsVisibility() const { return false; }
184
185     bool hasPlayedSinceLastInterruption() const { return m_hasPlayedSinceLastInterruption; }
186     void clearHasPlayedSinceLastInterruption() { m_hasPlayedSinceLastInterruption = false; }
187
188 #if !RELEASE_LOG_DISABLED
189     const Logger& logger() const final { return m_logger.get(); }
190     const void* logIdentifier() const override { return m_logIdentifier; }
191     const char* logClassName() const override { return "PlatformMediaSession"; }
192     WTFLogChannel& logChannel() const final;
193 #endif
194
195     bool canPlayConcurrently(const PlatformMediaSession&) const;
196     bool shouldOverridePauseDuringRouteChange() const;
197
198 protected:
199     PlatformMediaSessionClient& client() const { return m_client; }
200
201 private:
202     PlatformMediaSessionClient& m_client;
203     State m_state;
204     State m_stateToRestore;
205     InterruptionType m_interruptionType { NoInterruption };
206     int m_interruptionCount { 0 };
207     bool m_notifyingClient;
208     bool m_isPlayingToWirelessPlaybackTarget { false };
209     bool m_hasPlayedSinceLastInterruption { false };
210
211 #if !RELEASE_LOG_DISABLED
212     Ref<const Logger> m_logger;
213     const void* m_logIdentifier;
214 #endif
215
216     friend class PlatformMediaSessionManager;
217 };
218
219 class PlatformMediaSessionClient {
220     WTF_MAKE_NONCOPYABLE(PlatformMediaSessionClient);
221 public:
222     PlatformMediaSessionClient() = default;
223     
224     virtual PlatformMediaSession::MediaType mediaType() const = 0;
225     virtual PlatformMediaSession::MediaType presentationType() const = 0;
226     virtual PlatformMediaSession::DisplayType displayType() const { return PlatformMediaSession::Normal; }
227     virtual PlatformMediaSession::CharacteristicsFlags characteristics() const = 0;
228
229     virtual void resumeAutoplaying() { }
230     virtual void mayResumePlayback(bool shouldResume) = 0;
231     virtual void suspendPlayback() = 0;
232
233 #if ENABLE(VIDEO)
234     virtual uint64_t mediaSessionUniqueIdentifier() const;
235     virtual String mediaSessionTitle() const;
236     virtual double mediaSessionDuration() const;
237     virtual double mediaSessionCurrentTime() const;
238 #endif
239     
240     virtual bool canReceiveRemoteControlCommands() const = 0;
241     virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) = 0;
242     virtual bool supportsSeeking() const = 0;
243
244     virtual bool canProduceAudio() const { return false; }
245     virtual bool isSuspended() const { return false; };
246
247     virtual bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const = 0;
248     virtual bool shouldOverrideBackgroundLoadingRestriction() const { return false; }
249
250     virtual void wirelessRoutesAvailableDidChange() { }
251     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) { }
252     virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
253     virtual void setShouldPlayToPlaybackTarget(bool) { }
254     virtual void playbackTargetPickerWasDismissed() { }
255
256     virtual bool isPlayingOnSecondScreen() const { return false; }
257
258     virtual Document* hostingDocument() const = 0;
259     virtual String sourceApplicationIdentifier() const = 0;
260
261     virtual bool processingUserGestureForMedia() const = 0;
262
263     virtual bool hasMediaStreamSource() const { return false; }
264
265     virtual void processIsSuspendedChanged() { }
266
267     virtual bool shouldOverridePauseDuringRouteChange() const { return false; }
268
269 protected:
270     virtual ~PlatformMediaSessionClient() = default;
271 };
272
273 String convertEnumerationToString(PlatformMediaSession::State);
274 String convertEnumerationToString(PlatformMediaSession::InterruptionType);
275 String convertEnumerationToString(PlatformMediaSession::RemoteControlCommandType);
276 }
277
278 namespace WTF {
279
280 template<typename Type>
281 struct LogArgument;
282
283 template <>
284 struct LogArgument<WebCore::PlatformMediaSession::State> {
285     static String toString(const WebCore::PlatformMediaSession::State state)
286     {
287         return convertEnumerationToString(state);
288     }
289 };
290
291 template <>
292 struct LogArgument<WebCore::PlatformMediaSession::InterruptionType> {
293     static String toString(const WebCore::PlatformMediaSession::InterruptionType state)
294     {
295         return convertEnumerationToString(state);
296     }
297 };
298
299 template <>
300 struct LogArgument<WebCore::PlatformMediaSession::RemoteControlCommandType> {
301     static String toString(const WebCore::PlatformMediaSession::RemoteControlCommandType command)
302     {
303         return convertEnumerationToString(command);
304     }
305 };
306
307 } // namespace WTF
308
309 #endif // PlatformMediaSession_h