2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
30 #include "MessageReceiver.h"
31 #include <WebCore/EventListener.h>
32 #include <WebCore/HTMLMediaElementEnums.h>
33 #include <WebCore/PlatformCALayer.h>
34 #include <WebCore/PlaybackSessionInterface.h>
35 #include <WebCore/PlaybackSessionModelMediaElement.h>
36 #include <wtf/HashCountedSet.h>
37 #include <wtf/HashMap.h>
38 #include <wtf/RefCounted.h>
39 #include <wtf/RefPtr.h>
45 class MessageReceiver;
55 class PlaybackSessionManager;
57 class PlaybackSessionInterfaceContext final
58 : public RefCounted<PlaybackSessionInterfaceContext>
59 , public WebCore::PlaybackSessionInterface
60 , public WebCore::PlaybackSessionModelClient {
62 static Ref<PlaybackSessionInterfaceContext> create(PlaybackSessionManager& manager, uint64_t contextId)
64 return adoptRef(*new PlaybackSessionInterfaceContext(manager, contextId));
66 virtual ~PlaybackSessionInterfaceContext();
68 void invalidate() { m_manager = nullptr; }
71 friend class VideoFullscreenInterfaceContext;
73 // PlaybackSessionInterface
74 void resetMediaState() final;
76 // PlaybackSessionModelClient
77 void durationChanged(double) final;
78 void currentTimeChanged(double currentTime, double anchorTime) final;
79 void bufferedTimeChanged(double) final;
80 void playbackStartedTimeChanged(double playbackStartedTime) final;
81 void rateChanged(bool isPlaying, float playbackRate) final;
82 void seekableRangesChanged(const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval) final;
83 void canPlayFastReverseChanged(bool value) final;
84 void audioMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
85 void legibleMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
86 void audioMediaSelectionIndexChanged(uint64_t) final;
87 void legibleMediaSelectionIndexChanged(uint64_t) final;
88 void externalPlaybackChanged(bool enabled, WebCore::PlaybackSessionModel::ExternalPlaybackTargetType, const String& localizedDeviceName) final;
89 void wirelessVideoPlaybackDisabledChanged(bool) final;
90 void mutedChanged(bool) final;
91 void volumeChanged(double) final;
92 void isPictureInPictureSupportedChanged(bool) final;
94 PlaybackSessionInterfaceContext(PlaybackSessionManager&, uint64_t contextId);
96 PlaybackSessionManager* m_manager;
100 class PlaybackSessionManager : public RefCounted<PlaybackSessionManager>, private IPC::MessageReceiver {
102 static Ref<PlaybackSessionManager> create(WebPage&);
103 virtual ~PlaybackSessionManager();
107 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
109 void setUpPlaybackControlsManager(WebCore::HTMLMediaElement&);
110 void clearPlaybackControlsManager();
111 uint64_t contextIdForMediaElement(WebCore::HTMLMediaElement&);
113 WebCore::HTMLMediaElement* currentPlaybackControlsElement() const;
116 friend class PlaybackSessionInterfaceContext;
117 friend class VideoFullscreenManager;
119 explicit PlaybackSessionManager(WebPage&);
121 typedef std::tuple<RefPtr<WebCore::PlaybackSessionModelMediaElement>, RefPtr<PlaybackSessionInterfaceContext>> ModelInterfaceTuple;
122 ModelInterfaceTuple createModelAndInterface(uint64_t contextId);
123 ModelInterfaceTuple& ensureModelAndInterface(uint64_t contextId);
124 WebCore::PlaybackSessionModelMediaElement& ensureModel(uint64_t contextId);
125 PlaybackSessionInterfaceContext& ensureInterface(uint64_t contextId);
126 void removeContext(uint64_t contextId);
127 void addClientForContext(uint64_t contextId);
128 void removeClientForContext(uint64_t contextId);
130 // Interface to PlaybackSessionInterfaceContext
131 void resetMediaState(uint64_t contextId);
132 void durationChanged(uint64_t contextId, double);
133 void currentTimeChanged(uint64_t contextId, double currentTime, double anchorTime);
134 void bufferedTimeChanged(uint64_t contextId, double bufferedTime);
135 void playbackStartedTimeChanged(uint64_t contextId, double playbackStartedTime);
136 void rateChanged(uint64_t contextId, bool isPlaying, float playbackRate);
137 void seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval);
138 void canPlayFastReverseChanged(uint64_t contextId, bool value);
139 void audioMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);
140 void legibleMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);
141 void audioMediaSelectionIndexChanged(uint64_t contextId, uint64_t selectedIndex);
142 void legibleMediaSelectionIndexChanged(uint64_t contextId, uint64_t selectedIndex);
143 void externalPlaybackChanged(uint64_t contextId, bool enabled, WebCore::PlaybackSessionModel::ExternalPlaybackTargetType, String localizedDeviceName);
144 void wirelessVideoPlaybackDisabledChanged(uint64_t contextId, bool);
145 void mutedChanged(uint64_t contextId, bool);
146 void volumeChanged(uint64_t contextId, double);
147 void isPictureInPictureSupportedChanged(uint64_t contextId, bool);
149 // Messages from PlaybackSessionManagerProxy
150 void play(uint64_t contextId);
151 void pause(uint64_t contextId);
152 void togglePlayState(uint64_t contextId);
153 void beginScrubbing(uint64_t contextId);
154 void endScrubbing(uint64_t contextId);
155 void seekToTime(uint64_t contextId, double time, double toleranceBefore, double toleranceAfter);
156 void fastSeek(uint64_t contextId, double time);
157 void beginScanningForward(uint64_t contextId);
158 void beginScanningBackward(uint64_t contextId);
159 void endScanning(uint64_t contextId);
160 void selectAudioMediaOption(uint64_t contextId, uint64_t index);
161 void selectLegibleMediaOption(uint64_t contextId, uint64_t index);
162 void handleControlledElementIDRequest(uint64_t contextId);
163 void togglePictureInPicture(uint64_t contextId);
164 void toggleMuted(uint64_t contextId);
165 void setMuted(uint64_t contextId, bool muted);
166 void setVolume(uint64_t contextId, double volume);
167 void setPlayingOnSecondScreen(uint64_t contextId, bool value);
170 HashMap<WebCore::HTMLMediaElement*, uint64_t> m_mediaElements;
171 HashMap<uint64_t, ModelInterfaceTuple> m_contextMap;
172 uint64_t m_controlsManagerContextId { 0 };
173 HashCountedSet<uint64_t> m_clientCounts;
176 } // namespace WebKit
178 #endif // PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))