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 // PlaybackSessionModelClient
74 void durationChanged(double) final;
75 void currentTimeChanged(double currentTime, double anchorTime) final;
76 void bufferedTimeChanged(double) final;
77 void playbackStartedTimeChanged(double playbackStartedTime) final;
78 void rateChanged(bool isPlaying, float playbackRate) final;
79 void seekableRangesChanged(const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval) final;
80 void canPlayFastReverseChanged(bool value) final;
81 void audioMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
82 void legibleMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
83 void audioMediaSelectionIndexChanged(uint64_t) final;
84 void legibleMediaSelectionIndexChanged(uint64_t) final;
85 void externalPlaybackChanged(bool enabled, WebCore::PlaybackSessionModel::ExternalPlaybackTargetType, const String& localizedDeviceName) final;
86 void wirelessVideoPlaybackDisabledChanged(bool) final;
87 void mutedChanged(bool) final;
88 void volumeChanged(double) final;
89 void isPictureInPictureSupportedChanged(bool) final;
91 PlaybackSessionInterfaceContext(PlaybackSessionManager&, uint64_t contextId);
93 PlaybackSessionManager* m_manager;
97 class PlaybackSessionManager : public RefCounted<PlaybackSessionManager>, private IPC::MessageReceiver {
99 static Ref<PlaybackSessionManager> create(WebPage&);
100 virtual ~PlaybackSessionManager();
104 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
106 void setUpPlaybackControlsManager(WebCore::HTMLMediaElement&);
107 void clearPlaybackControlsManager();
108 uint64_t contextIdForMediaElement(WebCore::HTMLMediaElement&);
110 WebCore::HTMLMediaElement* currentPlaybackControlsElement() const;
113 friend class PlaybackSessionInterfaceContext;
114 friend class VideoFullscreenManager;
116 explicit PlaybackSessionManager(WebPage&);
118 typedef std::tuple<RefPtr<WebCore::PlaybackSessionModelMediaElement>, RefPtr<PlaybackSessionInterfaceContext>> ModelInterfaceTuple;
119 ModelInterfaceTuple createModelAndInterface(uint64_t contextId);
120 ModelInterfaceTuple& ensureModelAndInterface(uint64_t contextId);
121 WebCore::PlaybackSessionModelMediaElement& ensureModel(uint64_t contextId);
122 PlaybackSessionInterfaceContext& ensureInterface(uint64_t contextId);
123 void removeContext(uint64_t contextId);
124 void addClientForContext(uint64_t contextId);
125 void removeClientForContext(uint64_t contextId);
127 // Interface to PlaybackSessionInterfaceContext
128 void durationChanged(uint64_t contextId, double);
129 void currentTimeChanged(uint64_t contextId, double currentTime, double anchorTime);
130 void bufferedTimeChanged(uint64_t contextId, double bufferedTime);
131 void playbackStartedTimeChanged(uint64_t contextId, double playbackStartedTime);
132 void rateChanged(uint64_t contextId, bool isPlaying, float playbackRate);
133 void seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval);
134 void canPlayFastReverseChanged(uint64_t contextId, bool value);
135 void audioMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);
136 void legibleMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);
137 void audioMediaSelectionIndexChanged(uint64_t contextId, uint64_t selectedIndex);
138 void legibleMediaSelectionIndexChanged(uint64_t contextId, uint64_t selectedIndex);
139 void externalPlaybackChanged(uint64_t contextId, bool enabled, WebCore::PlaybackSessionModel::ExternalPlaybackTargetType, String localizedDeviceName);
140 void wirelessVideoPlaybackDisabledChanged(uint64_t contextId, bool);
141 void mutedChanged(uint64_t contextId, bool);
142 void volumeChanged(uint64_t contextId, double);
143 void isPictureInPictureSupportedChanged(uint64_t contextId, bool);
145 // Messages from PlaybackSessionManagerProxy
146 void play(uint64_t contextId);
147 void pause(uint64_t contextId);
148 void togglePlayState(uint64_t contextId);
149 void beginScrubbing(uint64_t contextId);
150 void endScrubbing(uint64_t contextId);
151 void seekToTime(uint64_t contextId, double time, double toleranceBefore, double toleranceAfter);
152 void fastSeek(uint64_t contextId, double time);
153 void beginScanningForward(uint64_t contextId);
154 void beginScanningBackward(uint64_t contextId);
155 void endScanning(uint64_t contextId);
156 void selectAudioMediaOption(uint64_t contextId, uint64_t index);
157 void selectLegibleMediaOption(uint64_t contextId, uint64_t index);
158 void handleControlledElementIDRequest(uint64_t contextId);
159 void togglePictureInPicture(uint64_t contextId);
160 void toggleMuted(uint64_t contextId);
161 void setMuted(uint64_t contextId, bool muted);
162 void setVolume(uint64_t contextId, double volume);
163 void setPlayingOnSecondScreen(uint64_t contextId, bool value);
166 HashMap<WebCore::HTMLMediaElement*, uint64_t> m_mediaElements;
167 HashMap<uint64_t, ModelInterfaceTuple> m_contextMap;
168 uint64_t m_controlsManagerContextId { 0 };
169 HashCountedSet<uint64_t> m_clientCounts;
172 } // namespace WebKit
174 #endif // PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))