401bd40eb9a5955a6ac52a0d5a10ec2a7e087cf6
[WebKit-https.git] / Source / WebCore / html / MediaElementSession.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 #pragma once
27
28 #if ENABLE(VIDEO)
29
30 #include "MediaPlayer.h"
31 #include "MediaProducer.h"
32 #include "PlatformMediaSession.h"
33 #include "SuccessOr.h"
34 #include "Timer.h"
35 #include <wtf/TypeCasts.h>
36
37 namespace WebCore {
38
39 enum class MediaSessionMainContentPurpose {
40     MediaControls,
41     Autoplay
42 };
43
44 enum class MediaPlaybackDenialReason {
45     UserGestureRequired,
46     FullscreenRequired,
47     PageConsentRequired,
48 };
49
50 class Document;
51 class HTMLMediaElement;
52 class SourceBuffer;
53
54 class MediaElementSession final : public PlatformMediaSession {
55     WTF_MAKE_FAST_ALLOCATED;
56 public:
57     explicit MediaElementSession(HTMLMediaElement&);
58     virtual ~MediaElementSession() = default;
59
60     void registerWithDocument(Document&);
61     void unregisterWithDocument(Document&);
62
63     SuccessOr<MediaPlaybackDenialReason> playbackPermitted(const HTMLMediaElement&) const;
64     bool autoplayPermitted() const;
65     bool dataLoadingPermitted(const HTMLMediaElement&) const;
66     bool fullscreenPermitted(const HTMLMediaElement&) const;
67     bool pageAllowsDataLoading(const HTMLMediaElement&) const;
68     bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
69
70 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
71     void showPlaybackTargetPicker(const HTMLMediaElement&);
72     bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
73
74     bool wirelessVideoPlaybackDisabled(const HTMLMediaElement&) const;
75     void setWirelessVideoPlaybackDisabled(const HTMLMediaElement&, bool);
76
77     void setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement&, bool);
78
79     bool canPlayToWirelessPlaybackTarget() const override;
80     bool isPlayingToWirelessPlaybackTarget() const override;
81
82     void mediaStateDidChange(const HTMLMediaElement&, MediaProducer::MediaStateFlags);
83 #endif
84
85     bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
86     WEBCORE_EXPORT bool allowsPictureInPicture(const HTMLMediaElement&) const;
87     MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&) const;
88     bool allowsAutomaticMediaDataLoading(const HTMLMediaElement&) const;
89
90     void mediaEngineUpdated(const HTMLMediaElement&);
91
92     void resetPlaybackSessionState() override;
93
94     // Restrictions to modify default behaviors.
95     enum BehaviorRestrictionFlags : unsigned {
96         NoRestrictions = 0,
97         RequireUserGestureForLoad = 1 << 0,
98         RequireUserGestureForVideoRateChange = 1 << 1,
99         RequireUserGestureForFullscreen = 1 << 2,
100         RequirePageConsentToLoadMedia = 1 << 3,
101         RequirePageConsentToResumeMedia = 1 << 4,
102         RequireUserGestureForAudioRateChange = 1 << 5,
103         RequireUserGestureToShowPlaybackTargetPicker = 1 << 6,
104         WirelessVideoPlaybackDisabled =  1 << 7,
105         RequireUserGestureToAutoplayToExternalDevice = 1 << 8,
106         MetadataPreloadingNotPermitted = 1 << 9,
107         AutoPreloadingNotPermitted = 1 << 10,
108         InvisibleAutoplayNotPermitted = 1 << 11,
109         OverrideUserGestureRequirementForMainContent = 1 << 12,
110         RequireUserGestureToControlControlsManager = 1 << 13,
111         RequirePlaybackToControlControlsManager = 1 << 14,
112         RequireUserGestureForVideoDueToLowPowerMode = 1 << 15,
113         AllRestrictions = ~NoRestrictions,
114     };
115     typedef unsigned BehaviorRestrictions;
116
117     WEBCORE_EXPORT BehaviorRestrictions behaviorRestrictions() const { return m_restrictions; }
118     WEBCORE_EXPORT void addBehaviorRestriction(BehaviorRestrictions);
119     WEBCORE_EXPORT void removeBehaviorRestriction(BehaviorRestrictions);
120     bool hasBehaviorRestriction(BehaviorRestrictions restriction) const { return restriction & m_restrictions; }
121
122 #if ENABLE(MEDIA_SOURCE)
123     size_t maximumMediaSourceBufferSize(const SourceBuffer&) const;
124 #endif
125
126     HTMLMediaElement& element() const { return m_element; }
127
128     bool wantsToObserveViewportVisibilityForMediaControls() const;
129     bool wantsToObserveViewportVisibilityForAutoplay() const;
130
131     enum class PlaybackControlsPurpose { ControlsManager, NowPlaying };
132     bool canShowControlsManager(PlaybackControlsPurpose) const;
133     bool isLargeEnoughForMainContent(MediaSessionMainContentPurpose) const;
134     double mostRecentUserInteractionTime() const;
135
136     bool allowsPlaybackControlsForAutoplayingAudio() const;
137     bool allowsNowPlayingControlsVisibility() const override;
138
139     static bool isMediaElementSessionMediaType(MediaType type)
140     {
141         return type == Video
142             || type == Audio
143             || type == VideoAudio;
144     }
145
146 private:
147
148 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
149     void targetAvailabilityChangedTimerFired();
150
151     // MediaPlaybackTargetClient
152     void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
153     void externalOutputDeviceAvailableDidChange(bool) override;
154     void setShouldPlayToPlaybackTarget(bool) override;
155 #endif
156 #if PLATFORM(IOS)
157     bool requiresPlaybackTargetRouteMonitoring() const override;
158 #endif
159     bool updateIsMainContent() const;
160     void mainContentCheckTimerFired();
161
162     HTMLMediaElement& m_element;
163     BehaviorRestrictions m_restrictions;
164
165 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
166     mutable Timer m_targetAvailabilityChangedTimer;
167     RefPtr<MediaPlaybackTarget> m_playbackTarget;
168     bool m_shouldPlayToPlaybackTarget { false };
169     mutable bool m_hasPlaybackTargets { false };
170 #endif
171 #if PLATFORM(IOS)
172     bool m_hasPlaybackTargetAvailabilityListeners { false };
173 #endif
174
175     double m_mostRecentUserInteractionTime { 0 };
176
177     mutable bool m_isMainContent { false };
178     Timer m_mainContentCheckTimer;
179 };
180
181 } // namespace WebCore
182
183 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MediaElementSession)
184 static bool isType(const WebCore::PlatformMediaSession& session) { return WebCore::MediaElementSession::isMediaElementSessionMediaType(session.mediaType()); }
185 SPECIALIZE_TYPE_TRAITS_END()
186
187 #endif // ENABLE(VIDEO)