Remove dead code: resetMediaState.
[WebKit-https.git] / Source / WebCore / platform / mac / PlaybackSessionInterfaceMac.mm
1 /*
2  * Copyright (C) 2016-2017 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(&model)
56 {
57 }
58
59 PlaybackSessionInterfaceMac::~PlaybackSessionInterfaceMac()
60 {
61     invalidate();
62 }
63
64 PlaybackSessionModel* PlaybackSessionInterfaceMac::playbackSessionModel() const
65 {
66     return m_playbackSessionModel;
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     playbackSessionModel()->beginScrubbing();
114 }
115
116 void PlaybackSessionInterfaceMac::endScrubbing()
117 {
118     playbackSessionModel()->endScrubbing();
119 }
120
121 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
122 static RetainPtr<NSMutableArray> timeRangesToArray(const TimeRanges& timeRanges)
123 {
124     RetainPtr<NSMutableArray> rangeArray = adoptNS([[NSMutableArray alloc] init]);
125
126     for (unsigned i = 0; i < timeRanges.length(); i++) {
127         const PlatformTimeRanges& ranges = timeRanges.ranges();
128         CMTimeRange range = PAL::CMTimeRangeMake(PAL::toCMTime(ranges.start(i)), PAL::toCMTime(ranges.end(i)));
129         [rangeArray addObject:[NSValue valueWithCMTimeRange:range]];
130     }
131
132     return rangeArray;
133 }
134 #endif
135
136 void PlaybackSessionInterfaceMac::seekableRangesChanged(const TimeRanges& timeRanges, double, double)
137 {
138 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
139     [playBackControlsManager() setSeekableTimeRanges:timeRangesToArray(timeRanges).get()];
140 #else
141     UNUSED_PARAM(timeRanges);
142 #endif
143 }
144
145 void PlaybackSessionInterfaceMac::audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
146 {
147 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
148     [playBackControlsManager() setAudioMediaSelectionOptions:options withSelectedIndex:static_cast<NSUInteger>(selectedIndex)];
149 #else
150     UNUSED_PARAM(options);
151     UNUSED_PARAM(selectedIndex);
152 #endif
153 }
154
155 void PlaybackSessionInterfaceMac::legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex)
156 {
157 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
158     [playBackControlsManager() setLegibleMediaSelectionOptions:options withSelectedIndex:static_cast<NSUInteger>(selectedIndex)];
159 #else
160     UNUSED_PARAM(options);
161     UNUSED_PARAM(selectedIndex);
162 #endif
163 }
164
165 void PlaybackSessionInterfaceMac::audioMediaSelectionIndexChanged(uint64_t selectedIndex)
166 {
167 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
168     [playBackControlsManager() setAudioMediaSelectionIndex:selectedIndex];
169 #else
170     UNUSED_PARAM(selectedIndex);
171 #endif
172 }
173
174 void PlaybackSessionInterfaceMac::legibleMediaSelectionIndexChanged(uint64_t selectedIndex)
175 {
176 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
177     [playBackControlsManager() setLegibleMediaSelectionIndex:selectedIndex];
178 #else
179     UNUSED_PARAM(selectedIndex);
180 #endif
181 }
182
183 void PlaybackSessionInterfaceMac::isPictureInPictureSupportedChanged(bool)
184 {
185 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
186     updatePlaybackControlsManagerCanTogglePictureInPicture();
187 #endif
188 }
189
190 void PlaybackSessionInterfaceMac::externalPlaybackChanged(bool, PlaybackSessionModel::ExternalPlaybackTargetType, const String&)
191 {
192 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
193     updatePlaybackControlsManagerCanTogglePictureInPicture();
194 #endif
195 }
196
197 void PlaybackSessionInterfaceMac::invalidate()
198 {
199     if (!m_playbackSessionModel)
200         return;
201
202     m_playbackSessionModel->removeClient(*this);
203     m_playbackSessionModel = nullptr;
204 }
205
206 void PlaybackSessionInterfaceMac::ensureControlsManager()
207 {
208 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
209     playBackControlsManager();
210 #endif
211 }
212
213 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
214
215 WebPlaybackControlsManager *PlaybackSessionInterfaceMac::playBackControlsManager()
216 {
217     return m_playbackControlsManager;
218 }
219
220 void PlaybackSessionInterfaceMac::setPlayBackControlsManager(WebPlaybackControlsManager *manager)
221 {
222     m_playbackControlsManager = manager;
223
224     if (!manager || !m_playbackSessionModel)
225         return;
226
227     NSTimeInterval anchorTimeStamp = ![manager rate] ? NAN : [[NSProcessInfo processInfo] systemUptime];
228     manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:m_playbackSessionModel->currentTime() anchorTimeStamp:anchorTimeStamp rate:0];
229     double duration = m_playbackSessionModel->duration();
230     manager.contentDuration = duration;
231     manager.hasEnabledAudio = duration > 0;
232     manager.hasEnabledVideo = duration > 0;
233     manager.rate = m_playbackSessionModel->isPlaying() ? m_playbackSessionModel->playbackRate() : 0.;
234     manager.seekableTimeRanges = timeRangesToArray(m_playbackSessionModel->seekableRanges()).get();
235     manager.canTogglePlayback = YES;
236     manager.playing = m_playbackSessionModel->isPlaying();
237     [manager setAudioMediaSelectionOptions:m_playbackSessionModel->audioMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->audioMediaSelectedIndex())];
238     [manager setLegibleMediaSelectionOptions:m_playbackSessionModel->legibleMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->legibleMediaSelectedIndex())];
239 }
240
241 void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerCanTogglePictureInPicture()
242 {
243     PlaybackSessionModel* model = playbackSessionModel();
244     if (!model) {
245         [playBackControlsManager() setCanTogglePictureInPicture:NO];
246         return;
247     }
248
249     [playBackControlsManager() setCanTogglePictureInPicture:model->isPictureInPictureSupported() && !model->externalPlaybackEnabled()];
250 }
251
252 void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying)
253 {
254     WebPlaybackControlsManager *manager = playBackControlsManager();
255     if (!manager)
256         return;
257
258     PlaybackSessionModel *model = playbackSessionModel();
259     if (!model)
260         return;
261
262     double effectiveAnchorTime = playbackRate ? anchorTime : NAN;
263     double effectivePlaybackRate = playbackRate;
264     if (!isPlaying
265         || model->isScrubbing()
266         || (manager.rate > 0 && model->playbackStartedTime() >= currentTime)
267         || (manager.rate < 0 && model->playbackStartedTime() <= currentTime))
268         effectivePlaybackRate = 0;
269
270     manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime anchorTimeStamp:effectiveAnchorTime rate:effectivePlaybackRate];
271 }
272
273 #endif // ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
274
275 }
276
277 #endif // PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)