[FreeType] Incorrect application of glyph positioning in the Y direction
[WebKit-https.git] / Source / WebCore / platform / mac / PlaybackSessionInterfaceMac.mm
1 /*
2  * Copyright (C) 2016-2019 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 #import "config.h"
27 #import "PlaybackSessionInterfaceMac.h"
28
29 #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
30
31 #import "IntRect.h"
32 #import "MediaSelectionOption.h"
33 #import "PlaybackSessionModel.h"
34 #import "TimeRanges.h"
35 #import "WebPlaybackControlsManager.h"
36 #import <AVFoundation/AVTime.h>
37 #import <pal/avfoundation/MediaTimeAVFoundation.h>
38 #import <pal/spi/cocoa/AVKitSPI.h>
39
40 #import <pal/cf/CoreMediaSoftLink.h>
41
42 SOFTLINK_AVKIT_FRAMEWORK()
43 SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming)
44
45 namespace WebCore {
46
47 Ref<PlaybackSessionInterfaceMac> PlaybackSessionInterfaceMac::create(PlaybackSessionModel& model)
48 {
49     auto interface = adoptRef(*new PlaybackSessionInterfaceMac(model));
50     model.addClient(interface);
51     return interface;
52 }
53
54 PlaybackSessionInterfaceMac::PlaybackSessionInterfaceMac(PlaybackSessionModel& model)
55     : m_playbackSessionModel(makeWeakPtr(model))
56 {
57 }
58
59 PlaybackSessionInterfaceMac::~PlaybackSessionInterfaceMac()
60 {
61     invalidate();
62 }
63
64 PlaybackSessionModel* PlaybackSessionInterfaceMac::playbackSessionModel() const
65 {
66     return m_playbackSessionModel.get();
67 }
68
69 void PlaybackSessionInterfaceMac::durationChanged(double duration)
70 {
71 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
72     WebPlaybackControlsManager* controlsManager = playBackControlsManager();
73
74     controlsManager.contentDuration = duration;
75
76     // FIXME: We take this as an indication that playback is ready, but that is not necessarily true.
77     controlsManager.hasEnabledAudio = YES;
78     controlsManager.hasEnabledVideo = YES;
79 #else
80     UNUSED_PARAM(duration);
81 #endif
82 }
83
84 void PlaybackSessionInterfaceMac::currentTimeChanged(double currentTime, double anchorTime)
85 {
86 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
87     WebPlaybackControlsManager* controlsManager = playBackControlsManager();
88     updatePlaybackControlsManagerTiming(currentTime, anchorTime, controlsManager.rate, controlsManager.playing);
89 #else
90     UNUSED_PARAM(currentTime);
91     UNUSED_PARAM(anchorTime);
92 #endif
93 }
94
95 void PlaybackSessionInterfaceMac::rateChanged(bool isPlaying, float playbackRate)
96 {
97 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
98     WebPlaybackControlsManager* controlsManager = playBackControlsManager();
99     [controlsManager setRate:isPlaying ? playbackRate : 0.];
100     [controlsManager setPlaying:isPlaying];
101     updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], playbackRate, isPlaying);
102 #else
103     UNUSED_PARAM(isPlaying);
104     UNUSED_PARAM(playbackRate);
105 #endif
106 }
107
108 void PlaybackSessionInterfaceMac::beginScrubbing()
109 {
110 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
111     updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], 0, false);
112 #endif
113     if (auto* model = playbackSessionModel())
114         model->beginScrubbing();
115 }
116
117 void PlaybackSessionInterfaceMac::endScrubbing()
118 {
119     if (auto* model = playbackSessionModel())
120         model->endScrubbing();
121 }
122
123 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
124 static RetainPtr<NSMutableArray> timeRangesToArray(const TimeRanges& timeRanges)
125 {
126     RetainPtr<NSMutableArray> rangeArray = adoptNS([[NSMutableArray alloc] init]);
127
128     for (unsigned i = 0; i < timeRanges.length(); i++) {
129         const PlatformTimeRanges& ranges = timeRanges.ranges();
130         CMTimeRange range = PAL::CMTimeRangeMake(PAL::toCMTime(ranges.start(i)), PAL::toCMTime(ranges.end(i)));
131         [rangeArray addObject:[NSValue valueWithCMTimeRange:range]];
132     }
133
134     return rangeArray;
135 }
136 #endif
137
138 void PlaybackSessionInterfaceMac::seekableRangesChanged(const TimeRanges& timeRanges, double, double)
139 {
140 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
141     [playBackControlsManager() setSeekableTimeRanges:timeRangesToArray(timeRanges).get()];
142 #else
143     UNUSED_PARAM(timeRanges);
144 #endif
145 }
146
147 void PlaybackSessionInterfaceMac::audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
148 {
149 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
150     [playBackControlsManager() setAudioMediaSelectionOptions:options withSelectedIndex:static_cast<NSUInteger>(selectedIndex)];
151 #else
152     UNUSED_PARAM(options);
153     UNUSED_PARAM(selectedIndex);
154 #endif
155 }
156
157 void PlaybackSessionInterfaceMac::legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
158 {
159 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
160     [playBackControlsManager() setLegibleMediaSelectionOptions:options withSelectedIndex:static_cast<NSUInteger>(selectedIndex)];
161 #else
162     UNUSED_PARAM(options);
163     UNUSED_PARAM(selectedIndex);
164 #endif
165 }
166
167 void PlaybackSessionInterfaceMac::audioMediaSelectionIndexChanged(uint64_t selectedIndex)
168 {
169 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
170     [playBackControlsManager() setAudioMediaSelectionIndex:selectedIndex];
171 #else
172     UNUSED_PARAM(selectedIndex);
173 #endif
174 }
175
176 void PlaybackSessionInterfaceMac::legibleMediaSelectionIndexChanged(uint64_t selectedIndex)
177 {
178 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
179     [playBackControlsManager() setLegibleMediaSelectionIndex:selectedIndex];
180 #else
181     UNUSED_PARAM(selectedIndex);
182 #endif
183 }
184
185 void PlaybackSessionInterfaceMac::isPictureInPictureSupportedChanged(bool)
186 {
187 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
188     updatePlaybackControlsManagerCanTogglePictureInPicture();
189 #endif
190 }
191
192 void PlaybackSessionInterfaceMac::externalPlaybackChanged(bool, PlaybackSessionModel::ExternalPlaybackTargetType, const String&)
193 {
194 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
195     updatePlaybackControlsManagerCanTogglePictureInPicture();
196 #endif
197 }
198
199 void PlaybackSessionInterfaceMac::invalidate()
200 {
201     if (!m_playbackSessionModel)
202         return;
203
204     m_playbackSessionModel->removeClient(*this);
205     m_playbackSessionModel = nullptr;
206 }
207
208 void PlaybackSessionInterfaceMac::ensureControlsManager()
209 {
210 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
211     playBackControlsManager();
212 #endif
213 }
214
215 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
216
217 WebPlaybackControlsManager *PlaybackSessionInterfaceMac::playBackControlsManager()
218 {
219     return m_playbackControlsManager.getAutoreleased();
220 }
221
222 void PlaybackSessionInterfaceMac::setPlayBackControlsManager(WebPlaybackControlsManager *manager)
223 {
224     m_playbackControlsManager = manager;
225
226     if (!manager || !m_playbackSessionModel)
227         return;
228
229     NSTimeInterval anchorTimeStamp = ![manager rate] ? NAN : [[NSProcessInfo processInfo] systemUptime];
230     manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:m_playbackSessionModel->currentTime() anchorTimeStamp:anchorTimeStamp rate:0];
231     double duration = m_playbackSessionModel->duration();
232     manager.contentDuration = duration;
233     manager.hasEnabledAudio = duration > 0;
234     manager.hasEnabledVideo = duration > 0;
235     manager.rate = m_playbackSessionModel->isPlaying() ? m_playbackSessionModel->playbackRate() : 0.;
236     manager.seekableTimeRanges = timeRangesToArray(m_playbackSessionModel->seekableRanges()).get();
237     manager.canTogglePlayback = YES;
238     manager.playing = m_playbackSessionModel->isPlaying();
239     [manager setAudioMediaSelectionOptions:m_playbackSessionModel->audioMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->audioMediaSelectedIndex())];
240     [manager setLegibleMediaSelectionOptions:m_playbackSessionModel->legibleMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->legibleMediaSelectedIndex())];
241 }
242
243 void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerCanTogglePictureInPicture()
244 {
245     PlaybackSessionModel* model = playbackSessionModel();
246     if (!model) {
247         [playBackControlsManager() setCanTogglePictureInPicture:NO];
248         return;
249     }
250
251     [playBackControlsManager() setCanTogglePictureInPicture:model->isPictureInPictureSupported() && !model->externalPlaybackEnabled()];
252 }
253
254 void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying)
255 {
256     WebPlaybackControlsManager *manager = playBackControlsManager();
257     if (!manager)
258         return;
259
260     PlaybackSessionModel *model = playbackSessionModel();
261     if (!model)
262         return;
263
264     double effectiveAnchorTime = playbackRate ? anchorTime : NAN;
265     double effectivePlaybackRate = playbackRate;
266     if (!isPlaying
267         || model->isScrubbing()
268         || (manager.rate > 0 && model->playbackStartedTime() >= currentTime)
269         || (manager.rate < 0 && model->playbackStartedTime() <= currentTime))
270         effectivePlaybackRate = 0;
271
272     manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime anchorTimeStamp:effectiveAnchorTime rate:effectivePlaybackRate];
273 }
274
275 #endif // ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
276
277 }
278
279 #endif // PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)