Use Forward.h instead of forward-declaring WTF::String
[WebKit-https.git] / Source / WebCore / platform / ios / VideoFullscreenInterfaceAVKit.h
1 /*
2  * Copyright (C) 2014-2018 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26
27 #pragma once
28
29 #if PLATFORM(IOS)
30
31 #include "EventListener.h"
32 #include "HTMLMediaElementEnums.h"
33 #include "PlatformLayer.h"
34 #include "PlaybackSessionInterfaceAVKit.h"
35 #include "VideoFullscreenModel.h"
36 #include <objc/objc.h>
37 #include <wtf/Forward.h>
38 #include <wtf/Function.h>
39 #include <wtf/RefCounted.h>
40 #include <wtf/RefPtr.h>
41 #include <wtf/RetainPtr.h>
42 #include <wtf/RunLoop.h>
43
44 OBJC_CLASS UIViewController;
45 OBJC_CLASS UIWindow;
46 OBJC_CLASS UIView;
47 OBJC_CLASS CALayer;
48 OBJC_CLASS WebAVPlayerController;
49 OBJC_CLASS WebAVPlayerLayerView;
50 OBJC_CLASS WebAVPlayerLayer;
51 OBJC_CLASS WebAVPlayerViewController;
52 OBJC_CLASS WebAVPlayerViewControllerDelegate;
53 OBJC_CLASS NSError;
54
55 namespace WebCore {
56 class IntRect;
57 class FloatSize;
58 class VideoFullscreenModel;
59 class VideoFullscreenChangeObserver;
60     
61 class WEBCORE_EXPORT VideoFullscreenInterfaceAVKit final
62     : public VideoFullscreenModelClient
63     , public PlaybackSessionModelClient
64     , public ThreadSafeRefCounted<VideoFullscreenInterfaceAVKit> {
65
66 public:
67     static Ref<VideoFullscreenInterfaceAVKit> create(PlaybackSessionInterfaceAVKit&);
68     virtual ~VideoFullscreenInterfaceAVKit();
69     WEBCORE_EXPORT void setVideoFullscreenModel(VideoFullscreenModel*);
70     WEBCORE_EXPORT void setVideoFullscreenChangeObserver(VideoFullscreenChangeObserver*);
71     PlaybackSessionModel* playbackSessionModel() const { return m_playbackSessionInterface->playbackSessionModel(); }
72
73     // VideoFullscreenModelClient
74     WEBCORE_EXPORT void hasVideoChanged(bool) final;
75     WEBCORE_EXPORT void videoDimensionsChanged(const FloatSize&) final;
76
77     // PlaybackSessionModelClient
78     WEBCORE_EXPORT void externalPlaybackChanged(bool enabled, PlaybackSessionModel::ExternalPlaybackTargetType, const String& localizedDeviceName) final;
79
80     WEBCORE_EXPORT void setupFullscreen(UIView&, const IntRect& initialRect, UIView *, HTMLMediaElementEnums::VideoFullscreenMode, bool allowsPictureInPicturePlayback, bool standby);
81     WEBCORE_EXPORT void enterFullscreen();
82     WEBCORE_EXPORT void exitFullscreen(const IntRect& finalRect);
83     WEBCORE_EXPORT void cleanupFullscreen();
84     WEBCORE_EXPORT void invalidate();
85     WEBCORE_EXPORT void requestHideAndExitFullscreen();
86     WEBCORE_EXPORT void preparedToReturnToInline(bool visible, const IntRect& inlineRect);
87 #if ENABLE(FULLSCREEN_API)
88     WEBCORE_EXPORT void setHasVideoContentLayer(bool);
89     WEBCORE_EXPORT void setInlineRect(const IntRect&, bool visible);
90 #endif
91
92     enum class ExitFullScreenReason {
93         DoneButtonTapped,
94         FullScreenButtonTapped,
95         PinchGestureHandled,
96         RemoteControlStopEventReceived,
97         PictureInPictureStarted
98     };
99
100     class Mode {
101         HTMLMediaElementEnums::VideoFullscreenMode m_mode { HTMLMediaElementEnums::VideoFullscreenModeNone };
102
103     public:
104         Mode() = default;
105         Mode(const Mode&) = default;
106         Mode(HTMLMediaElementEnums::VideoFullscreenMode mode) : m_mode(mode) { }
107         void operator=(HTMLMediaElementEnums::VideoFullscreenMode mode) { m_mode = mode; }
108         HTMLMediaElementEnums::VideoFullscreenMode mode() const { return m_mode; }
109
110         void setModeValue(HTMLMediaElementEnums::VideoFullscreenMode mode, bool value) { value ? setMode(mode) : clearMode(mode); }
111         void setMode(HTMLMediaElementEnums::VideoFullscreenMode mode) { m_mode |= mode; }
112         void clearMode(HTMLMediaElementEnums::VideoFullscreenMode mode) { m_mode &= ~mode; }
113         bool hasMode(HTMLMediaElementEnums::VideoFullscreenMode mode) const { return m_mode & mode; }
114
115         bool isPictureInPicture() const { return m_mode == HTMLMediaElementEnums::VideoFullscreenModePictureInPicture; }
116         bool isFullscreen() const { return m_mode == HTMLMediaElementEnums::VideoFullscreenModeStandard; }
117
118         void setPictureInPicture(bool value) { setModeValue(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture, value); }
119         void setFullscreen(bool value) { setModeValue(HTMLMediaElementEnums::VideoFullscreenModeStandard, value); }
120
121         bool hasFullscreen() const { return hasMode(HTMLMediaElementEnums::VideoFullscreenModeStandard); }
122         bool hasPictureInPicture() const { return hasMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture); }
123
124         bool hasVideo() const { return m_mode & (HTMLMediaElementEnums::VideoFullscreenModeStandard | HTMLMediaElementEnums::VideoFullscreenModePictureInPicture); }
125     };
126
127     Mode m_currentMode;
128 #if ENABLE(FULLSCREEN_API)
129     Mode m_targetMode;
130 #endif
131
132     VideoFullscreenModel* model() const { return m_videoFullscreenModel; }
133     bool shouldExitFullscreenWithReason(ExitFullScreenReason);
134     HTMLMediaElementEnums::VideoFullscreenMode mode() const { return m_currentMode.mode(); }
135     bool allowsPictureInPicturePlayback() const { return m_allowsPictureInPicturePlayback; }
136     WEBCORE_EXPORT bool mayAutomaticallyShowVideoPictureInPicture() const;
137     void fullscreenMayReturnToInline(WTF::Function<void(bool)>&& callback);
138     bool wirelessVideoPlaybackDisabled() const;
139     void applicationDidBecomeActive();
140
141     void willStartPictureInPicture();
142     void didStartPictureInPicture();
143     void failedToStartPictureInPicture();
144     void willStopPictureInPicture();
145     void didStopPictureInPicture();
146     void prepareForPictureInPictureStopWithCompletionHandler(void (^)(BOOL));
147 #if ENABLE(FULLSCREEN_API)
148     void exitFullscreenHandler(BOOL success, NSError *);
149     void enterFullscreenHandler(BOOL success, NSError *);
150 #endif
151     bool isPlayingVideoInEnhancedFullscreen() const;
152
153     void setMode(HTMLMediaElementEnums::VideoFullscreenMode);
154     void clearMode(HTMLMediaElementEnums::VideoFullscreenMode);
155     bool hasMode(HTMLMediaElementEnums::VideoFullscreenMode mode) const { return m_currentMode.hasMode(mode); }
156
157 #if PLATFORM(IOS)
158     UIViewController *presentingViewController();
159     UIViewController *fullscreenViewController() const { return m_viewController.get(); }
160     WebAVPlayerLayerView* playerLayerView() const { return m_playerLayerView.get(); }
161 #endif
162
163 protected:
164     WEBCORE_EXPORT VideoFullscreenInterfaceAVKit(PlaybackSessionInterfaceAVKit&);
165
166 #if ENABLE(FULLSCREEN_API)
167     void doSetup();
168     void finalizeSetup();
169     void doExitFullscreen();
170     void returnToStandby();
171 #else
172     void enterPictureInPicture();
173     void enterFullscreenStandard();
174 #endif
175     void doEnterFullscreen();
176     void watchdogTimerFired();
177     WebAVPlayerController *playerController() const;
178
179     Ref<PlaybackSessionInterfaceAVKit> m_playbackSessionInterface;
180     RetainPtr<WebAVPlayerViewControllerDelegate> m_playerViewControllerDelegate;
181     RetainPtr<WebAVPlayerViewController> m_playerViewController;
182     VideoFullscreenModel* m_videoFullscreenModel { nullptr };
183     VideoFullscreenChangeObserver* m_fullscreenChangeObserver { nullptr };
184
185     // These are only used when fullscreen is presented in a separate window.
186     RetainPtr<UIWindow> m_window;
187     RetainPtr<UIViewController> m_viewController;
188     RetainPtr<UIView> m_videoView;
189     RetainPtr<UIView> m_parentView;
190     RetainPtr<UIWindow> m_parentWindow;
191     RetainPtr<WebAVPlayerLayerView> m_playerLayerView;
192     WTF::Function<void(bool)> m_prepareToInlineCallback;
193     RunLoop::Timer<VideoFullscreenInterfaceAVKit> m_watchdogTimer;
194     FloatRect m_inlineRect;
195     bool m_allowsPictureInPicturePlayback { false };
196     bool m_wirelessVideoPlaybackDisabled { true };
197     bool m_shouldReturnToFullscreenWhenStoppingPiP { false };
198     bool m_restoringFullscreenForPictureInPictureStop { false };
199
200 #if ENABLE(FULLSCREEN_API)
201     bool m_setupNeedsInlineRect { false };
202     bool m_exitFullscreenNeedInlineRect { false };
203
204     bool m_finalizeSetupNeedsVideoContentLayer { false };
205     bool m_cleanupNeedsReturnVideoContentLayer { false };
206
207     bool m_returnToStandbyNeedsReturnVideoContentLayer { false };
208     bool m_finalizeSetupNeedsReturnVideoContentLayer { false };
209
210     bool m_exitFullscreenNeedsExitFullscreen { false };
211     bool m_exitFullscreenNeedsExitPictureInPicture { false };
212     bool m_exitFullscreenNeedsReturnContentLayer { false };
213
214     bool m_enterFullscreenNeedsEnterFullscreen { false };
215     bool m_enterFullscreenNeedsExitFullscreen { false };
216     bool m_enterFullscreenNeedsEnterPictureInPicture { false };
217     bool m_enterFullscreenNeedsExitPictureInPicture { false };
218
219     bool m_hasVideoContentLayer { false };
220
221     bool m_hasUpdatedInlineRect { false };
222     bool m_inlineIsVisible { false };
223     bool m_standby { false };
224     bool m_targetStandby { false };
225 #else
226     bool m_exitRequested { false };
227     bool m_exitCompleted { false };
228     bool m_enterRequested { false };
229     bool m_shouldReturnToFullscreenAfterEnteringForeground { false };
230 #endif
231 };
232
233 }
234
235 #endif // PLATFORM(IOS)
236