2fd037fdf913cbd0048195d9fdf0cc7fd15f89ab
[WebKit-https.git] / Source / WebCore / html / HTMLMediaSession.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
28 #if ENABLE(VIDEO)
29
30 #include "HTMLMediaSession.h"
31
32 #include "HTMLMediaElement.h"
33 #include "Logging.h"
34 #include "MediaSessionManager.h"
35 #include "Page.h"
36 #include "ScriptController.h"
37
38 #if PLATFORM(IOS)
39 #include "AudioSession.h"
40 #include "RuntimeApplicationChecksIOS.h"
41 #endif
42
43 namespace WebCore {
44
45 static void initializeAudioSession()
46 {
47 #if PLATFORM(IOS)
48     static bool wasAudioSessionInitialized;
49     if (wasAudioSessionInitialized)
50         return;
51
52     wasAudioSessionInitialized = true;
53     if (!WebCore::applicationIsMobileSafari())
54         return;
55
56     AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
57 #endif
58 }
59
60 std::unique_ptr<HTMLMediaSession> HTMLMediaSession::create(MediaSessionClient& client)
61 {
62     return std::make_unique<HTMLMediaSession>(client);
63 }
64
65 HTMLMediaSession::HTMLMediaSession(MediaSessionClient& client)
66     : MediaSession(client)
67     , m_restrictions(NoRestrictions)
68 {
69     initializeAudioSession();
70 }
71
72 void HTMLMediaSession::addBehaviorRestriction(BehaviorRestrictions restriction)
73 {
74     m_restrictions |= restriction;
75 }
76
77 void HTMLMediaSession::removeBehaviorRestriction(BehaviorRestrictions restriction)
78 {
79     m_restrictions &= ~restriction;
80 }
81
82 bool HTMLMediaSession::playbackPermitted(const HTMLMediaElement&) const
83 {
84     if (m_restrictions & RequireUserGestureForRateChange && !ScriptController::processingUserGesture()) {
85         LOG(Media, "HTMLMediaSession::playbackPermitted - returning FALSE");
86         return false;
87     }
88
89     return true;
90 }
91
92 bool HTMLMediaSession::dataLoadingPermitted(const HTMLMediaElement&) const
93 {
94     if (m_restrictions & RequireUserGestureForLoad && !ScriptController::processingUserGesture()) {
95         LOG(Media, "HTMLMediaSession::dataLoadingPermitted - returning FALSE");
96         return false;
97     }
98
99     return true;
100 }
101
102 bool HTMLMediaSession::fullscreenPermitted(const HTMLMediaElement&) const
103 {
104     if (m_restrictions & RequireUserGestureForFullscreen && !ScriptController::processingUserGesture()) {
105         LOG(Media, "HTMLMediaSession::fullscreenPermitted - returning FALSE");
106         return false;
107     }
108
109     return true;
110 }
111
112 bool HTMLMediaSession::pageAllowsDataLoading(const HTMLMediaElement& element) const
113 {
114     Page* page = element.document().page();
115     if (m_restrictions & RequirePageConsentToLoadMedia && page && !page->canStartMedia()) {
116         LOG(Media, "HTMLMediaSession::pageAllowsDataLoading - returning FALSE");
117         return false;
118     }
119
120     return true;
121 }
122
123 bool HTMLMediaSession::pageAllowsPlaybackAfterResuming(const HTMLMediaElement& element) const
124 {
125     Page* page = element.document().page();
126     if (m_restrictions & RequirePageConsentToResumeMedia && page && !page->canStartMedia()) {
127         LOG(Media, "HTMLMediaSession::pageAllowsPlaybackAfterResuming - returning FALSE");
128         return false;
129     }
130
131     return true;
132 }
133
134 #if ENABLE(IOS_AIRPLAY)
135 bool HTMLMediaSession::showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const
136 {
137     if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
138         LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE");
139         return false;
140     }
141
142     return true;
143 }
144 #endif
145
146 void HTMLMediaSession::clientWillBeginPlayback() const
147 {
148     MediaSessionManager::sharedManager().sessionWillBeginPlayback(*this);
149 }
150
151 bool HTMLMediaSession::requiresFullscreenForVideoPlayback(const HTMLMediaElement& element) const
152 {
153     if (!MediaSessionManager::sharedManager().sessionRestrictsInlineVideoPlayback(*this))
154         return false;
155
156     Settings* settings = element.document().settings();
157     if (!settings || !settings->mediaPlaybackAllowsInline())
158         return true;
159
160     if (element.fastHasAttribute(HTMLNames::webkit_playsinlineAttr))
161         return false;
162
163 #if PLATFORM(IOS)
164     if (applicationIsDumpRenderTree())
165         return false;
166 #endif
167
168     return true;
169 }
170
171 }
172
173 #endif // ENABLE(VIDEO)