e3cc2d4436eb43a6e3f440ee10369609dc23a7ec
[WebKit-https.git] / Source / WebCore / platform / audio / MediaSession.cpp
1 /*
2  * Copyright (C) 2014 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 #include "config.h"
27 #include "MediaSession.h"
28
29 #if ENABLE(VIDEO)
30 #include "HTMLMediaElement.h"
31 #include "Logging.h"
32 #include "MediaPlayer.h"
33 #include "MediaSessionManager.h"
34
35 namespace WebCore {
36
37 #if !LOG_DISABLED
38 static const char* stateName(MediaSession::State state)
39 {
40 #define CASE(state) case MediaSession::state: return #state
41     switch (state) {
42     CASE(Idle);
43     CASE(Playing);
44     CASE(Paused);
45     CASE(Interrupted);
46     }
47
48     ASSERT_NOT_REACHED();
49     return "";
50 }
51 #endif
52
53 std::unique_ptr<MediaSession> MediaSession::create(MediaSessionClient& client)
54 {
55     return std::make_unique<MediaSession>(client);
56 }
57
58 MediaSession::MediaSession(MediaSessionClient& client)
59     : m_client(client)
60     , m_state(Idle)
61     , m_stateToRestore(Idle)
62     , m_notifyingClient(false)
63 {
64     ASSERT(m_client.mediaType() >= None && m_client.mediaType() <= WebAudio);
65     MediaSessionManager::sharedManager().addSession(*this);
66 }
67
68 MediaSession::~MediaSession()
69 {
70     MediaSessionManager::sharedManager().removeSession(*this);
71 }
72
73 void MediaSession::setState(State state)
74 {
75     LOG(Media, "MediaSession::setState(%p) - %s", this, stateName(state));
76     m_state = state;
77 }
78
79 void MediaSession::beginInterruption(InterruptionType type)
80 {
81     LOG(Media, "MediaSession::beginInterruption(%p), state = %s", this, stateName(m_state));
82
83     if (type == EnteringBackground && client().overrideBackgroundPlaybackRestriction())
84         return;
85
86     m_stateToRestore = state();
87     m_notifyingClient = true;
88     client().pausePlayback();
89     setState(Interrupted);
90     m_notifyingClient = false;
91 }
92
93 void MediaSession::endInterruption(EndInterruptionFlags flags)
94 {
95     LOG(Media, "MediaSession::endInterruption(%p) - flags = %i, stateToRestore = %s", this, (int)flags, stateName(m_stateToRestore));
96
97     State stateToRestore = m_stateToRestore;
98     m_stateToRestore = Idle;
99     setState(Paused);
100
101     if (flags & MayResumePlaying && stateToRestore == Playing) {
102         LOG(Media, "MediaSession::endInterruption - resuming playback");
103         client().resumePlayback();
104     }
105 }
106
107 bool MediaSession::clientWillBeginPlayback()
108 {
109     setState(Playing);
110     MediaSessionManager::sharedManager().sessionWillBeginPlayback(*this);
111     updateClientDataBuffering();
112     return true;
113 }
114
115 bool MediaSession::clientWillPausePlayback()
116 {
117     LOG(Media, "MediaSession::clientWillPausePlayback(%p)- state = %s", this, stateName(m_state));
118     if (state() == Interrupted) {
119         if (!m_notifyingClient) {
120             m_stateToRestore = Paused;
121             LOG(Media, "      setting stateToRestore to \"Paused\"");
122         }
123         return false;
124     }
125     
126     setState(Paused);
127     MediaSessionManager::sharedManager().sessionWillEndPlayback(*this);
128     updateClientDataBuffering();
129     return true;
130 }
131
132 void MediaSession::pauseSession()
133 {
134     LOG(Media, "MediaSession::pauseSession(%p)", this);
135     m_client.pausePlayback();
136 }
137
138 MediaSession::MediaType MediaSession::mediaType() const
139 {
140     return m_client.mediaType();
141 }
142
143 String MediaSession::title() const
144 {
145     return m_client.mediaSessionTitle();
146 }
147
148 double MediaSession::duration() const
149 {
150     return m_client.mediaSessionDuration();
151 }
152
153 double MediaSession::currentTime() const
154 {
155     return m_client.mediaSessionCurrentTime();
156 }
157     
158 bool MediaSession::canReceiveRemoteControlCommands() const
159 {
160     return m_client.canReceiveRemoteControlCommands();
161 }
162
163 void MediaSession::didReceiveRemoteControlCommand(RemoteControlCommandType command)
164 {
165     m_client.didReceiveRemoteControlCommand(command);
166 }
167
168 #if ENABLE(PAGE_VISIBILITY_API)
169 void MediaSession::visibilityChanged()
170 {
171     updateClientDataBuffering();
172 }
173
174 void MediaSession::updateClientDataBuffering()
175 {
176     bool shouldBuffer = m_state == Playing || !m_client.elementIsHidden();
177     m_client.setShouldBufferData(shouldBuffer);
178 }
179 #endif
180
181 String MediaSessionClient::mediaSessionTitle() const
182 {
183     return String();
184 }
185
186 double MediaSessionClient::mediaSessionDuration() const
187 {
188     return MediaPlayer::invalidTime();
189 }
190
191 double MediaSessionClient::mediaSessionCurrentTime() const
192 {
193     return MediaPlayer::invalidTime();
194 }
195
196 }
197 #endif