1/*
2 * Copyright (C) 2013 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#import "config.h"
27
28#if PLATFORM(IOS)
29
30#import "WebVideoFullscreenControllerAVKit.h"
31
32#import "Logging.h"
33#import "WebVideoFullscreenInterfaceAVKit.h"
34#import "WebVideoFullscreenModelMediaElement.h"
35#import <QuartzCore/CoreAnimation.h>
36#import <WebCore/WebCoreThreadRun.h>
37
38using namespace WebCore;
39
40#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
41
42@implementation WebVideoFullscreenController
43- (void)setMediaElement:(WebCore::HTMLMediaElement*)mediaElement
44{
45    UNUSED_PARAM(mediaElement);
46}
47
48- (WebCore::HTMLMediaElement*)mediaElement
49{
50    return nullptr;
51}
52
53- (void)enterFullscreen:(UIView *)view
54{
55    UNUSED_PARAM(view);
56}
57
58- (void)exitFullscreen
59{
60}
61@end
62
63#else
64
65@interface WebVideoFullscreenController (FullscreenObservation)
66- (void)didSetupFullscreen;
67- (void)didEnterFullscreen;
68- (void)didExitFullscreen;
69- (void)didCleanupFullscreen;
70@end
71
72class WebVideoFullscreenControllerChangeObserver : public WebVideoFullscreenChangeObserver {
73    WebVideoFullscreenController* _target;
74public:
75    void setTarget(WebVideoFullscreenController* target) { _target = target; }
76    virtual void didSetupFullscreen() override { [_target didSetupFullscreen]; }
77    virtual void didEnterFullscreen() override { [_target didEnterFullscreen]; }
78    virtual void didExitFullscreen() override { [_target didExitFullscreen]; }
79    virtual void didCleanupFullscreen() override { [_target didCleanupFullscreen]; }
80};
81
82@implementation WebVideoFullscreenController
83{
84    RefPtr<HTMLMediaElement> _mediaElement;
85    RefPtr<WebVideoFullscreenInterfaceAVKit> _interface;
86    RefPtr<WebVideoFullscreenModelMediaElement> _model;
87    WebVideoFullscreenControllerChangeObserver _changeObserver;
88    RetainPtr<PlatformLayer> _videoFullscreenLayer;
89}
90
91- (instancetype)init
92{
93    if (!(self = [super init]))
94        return nil;
95
96    _changeObserver.setTarget(self);
97
98    return self;
99}
100
101- (void)dealloc
102{
103    _mediaElement = nullptr;
104    [super dealloc];
105}
106
107- (void)setMediaElement:(HTMLMediaElement*)mediaElement
108{
109    _mediaElement = mediaElement;
110}
111
112- (HTMLMediaElement*)mediaElement
113{
114    return _mediaElement.get();
115}
116
117- (void)enterFullscreen:(UIView *)view
118{
119    [self retain]; // Balanced by -release in didExitFullscreen:
120
121    _interface = adoptRef(new WebVideoFullscreenInterfaceAVKit);
122    _interface->setWebVideoFullscreenChangeObserver(&_changeObserver);
123    _model = adoptRef(new WebVideoFullscreenModelMediaElement);
124    _model->setWebVideoFullscreenInterface(_interface.get());
125    _interface->setWebVideoFullscreenModel(_model.get());
126    _model->setMediaElement(_mediaElement.get());
127    _videoFullscreenLayer = [CALayer layer];
128    _interface->setupFullscreen(*_videoFullscreenLayer.get(), _mediaElement->clientRect(), view);
129}
130
131- (void)exitFullscreen
132{
133    _interface->exitFullscreen(_mediaElement->screenRect());
134}
135
136- (void)requestHideAndExitFullscreen
137{
138    if (_interface)
139        _interface->requestHideAndExitFullscreen();
140}
141
142- (void)didSetupFullscreen
143{
144    _model->setVideoFullscreenLayer(_videoFullscreenLayer.get());
145    _interface->enterFullscreen();
146}
147
148- (void)didEnterFullscreen
149{
150}
151
152- (void)didExitFullscreen
153{
154    WebThreadRun(^{
155        _model->setVideoFullscreenLayer(nil);
156        _interface->cleanupFullscreen();
157    });
158}
159
160- (void)didCleanupFullscreen
161{
162    WebThreadRun(^{
163        _model->setVideoFullscreenLayer(nil);
164        _interface->setWebVideoFullscreenModel(nullptr);
165        _model->setWebVideoFullscreenInterface(nullptr);
166        _model->setMediaElement(nullptr);
167        _interface->setWebVideoFullscreenChangeObserver(nullptr);
168        _model = nullptr;
169        _interface = nullptr;
170
171        [self release]; // Balance the -retain we did in enterFullscreen:
172    });
173}
174
175@end
176
177#endif // __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
178
179#endif // PLATFORM(IOS)
180