2 * Copyright (C) 2011 Google 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'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 #ifndef MediaStreamFrameController_h
26 #define MediaStreamFrameController_h
28 #if ENABLE(MEDIA_STREAM)
30 #include "ExceptionCode.h"
31 #include "MediaStreamClient.h"
32 #include "NavigatorUserMediaError.h"
33 #include <wtf/Forward.h>
34 #include <wtf/HashMap.h>
35 #include <wtf/Noncopyable.h>
36 #include <wtf/text/StringHash.h>
41 class LocalMediaStream;
43 class MediaStreamController;
44 class MediaStreamTrackList;
45 class NavigatorUserMediaErrorCallback;
46 class NavigatorUserMediaSuccessCallback;
49 class ScriptExecutionContext;
51 class SignalingCallback;
53 class MediaStreamFrameController {
54 WTF_MAKE_NONCOPYABLE(MediaStreamFrameController);
56 template <typename IdType>
58 WTF_MAKE_NONCOPYABLE(ClientBase);
60 ClientBase() : m_frameController(0), m_clientId(0) { }
62 ClientBase(MediaStreamFrameController* frameController, const IdType& id)
63 : m_frameController(frameController)
66 virtual ~ClientBase() { }
68 MediaStreamFrameController* mediaStreamFrameController() const { return m_frameController; }
69 const IdType& clientId() const { return m_clientId; }
71 virtual bool isMediaStream() const { return false; }
72 virtual bool isLocalMediaStream() const { return false; }
73 virtual bool isGenericClient() const { return false; }
74 virtual bool isPeerConnection() const { return false; }
76 // Called when the frame controller is being disconnected to the MediaStreamClient embedder.
77 // Clients should override this to send any required shutdown messages.
78 virtual void detachEmbedder() { }
81 // Used for objects that are optionally associated to the frame controller after construction, like the MediaStreamTracks.
82 void associateFrameController(MediaStreamFrameController* frameController, const IdType& id)
84 ASSERT(!m_frameController && !m_clientId);
85 m_frameController = frameController;
89 // Avoids repeating the same code in the unregister method of each derived class.
90 // This is required since the controller's unregister methods make use of the isObject virtuals,
91 // and the unregistration can be triggered either by the destructor of the client or by the disconnection of the frame.
92 template <typename ClientType>
93 void unregisterClient(ClientType* client)
95 if (!m_frameController)
98 m_frameController->unregister(static_cast<ClientType*>(client));
99 m_frameController = 0;
102 virtual void unregister() = 0;
103 friend class MediaStreamFrameController;
105 MediaStreamFrameController* m_frameController;
109 class MediaStreamClient : public ClientBase<String> {
111 MediaStreamClient(MediaStreamFrameController* frameController, const String& label, bool isLocalMediaStream)
112 : ClientBase<String>(frameController, label)
113 , m_isLocalMediaStream(isLocalMediaStream) { }
115 virtual ~MediaStreamClient() { unregister(); }
117 virtual bool isMediaStream() const { return true; }
119 // Accessed by the destructor.
120 virtual bool isLocalMediaStream() const { return m_isLocalMediaStream; }
122 // Stream has ended for some external reason.
123 virtual void streamEnded() = 0;
126 virtual void unregister() { unregisterClient(this); }
127 bool m_isLocalMediaStream;
130 // Generic clients are objects that require access to the frame controller but don't have a global id (like streams do)
131 // or need to receive any messages from the embedder client.
132 class GenericClient : public ClientBase<int> {
135 GenericClient(MediaStreamFrameController* frameController, int id) : ClientBase<int>(frameController, id) { }
136 virtual ~GenericClient() { unregister(); }
137 virtual bool isGenericClient() const { return true; }
140 virtual void unregister() { unregisterClient(this); }
143 class PeerConnectionClient : public GenericClient {
145 PeerConnectionClient(MediaStreamFrameController* frameController, int id) : GenericClient(frameController, id) { }
146 virtual ~PeerConnectionClient() { }
147 virtual bool isPeerConnection() const { return true; }
150 MediaStreamFrameController(Frame*);
151 virtual ~MediaStreamFrameController();
153 SecurityOrigin* securityOrigin() const;
154 ScriptExecutionContext* scriptExecutionContext() const;
156 bool isClientAvailable() const;
157 void disconnectPage();
158 void disconnectFrame();
159 void transferToNewPage(Page*);
161 static GenerateStreamOptionFlags parseGenerateStreamOptions(const String&);
162 void generateStream(const String& options, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&);
163 void stopGeneratedStream(const String& streamLabel);
164 void setMediaStreamTrackEnabled(const String& trackId, bool enabled);
166 PassRefPtr<PeerConnection> createPeerConnection(const String& configuration, PassRefPtr<SignalingCallback>);
167 void newPeerConnection(int peerConnectionId, const String& configuration);
168 void startNegotiation(int peerConnectionId);
169 void processSignalingMessage(int peerConnectionId, const String& message);
170 void message(int peerConnectionId, const String& message);
171 void addStream(int peerConnectionId, PassRefPtr<MediaStream>);
172 void removeStream(int peerConnectionId, PassRefPtr<MediaStream>);
173 void closePeerConnection(int peerConnectionId);
175 // --- Calls coming back from the controller. --- //
177 void streamGenerated(int requestId, const String& streamLabel, PassRefPtr<MediaStreamTrackList> tracks);
178 void streamGenerationFailed(int requestId, NavigatorUserMediaError::ErrorCode);
179 void streamFailed(const String& streamLabel);
181 void onSignalingMessage(int peerConnectionId, const String& message);
182 void onMessage(int peerConnectionId, const String& message);
183 void onAddStream(int peerConnectionId, const String& streamLabel, PassRefPtr<MediaStreamTrackList>);
184 void onRemoveStream(int peerConnectionId, const String& streamLabel);
185 void onNegotiationStarted(int peerConnectionId);
186 void onNegotiationDone(int peerConnectionId);
190 class GenerateStreamRequest;
193 WTF_MAKE_NONCOPYABLE(IdGenerator);
195 IdGenerator() : m_id(0) { }
196 int getNextId() { return ++m_id; }
202 class RequestMap : public IdGenerator, public HashMap<int, RefPtr<Request> > {
204 void abort(int requestId);
208 template <typename IdType>
209 class ClientMapBase : public HashMap<IdType, ClientBase<IdType>* > {
210 WTF_MAKE_NONCOPYABLE(ClientMapBase);
212 typedef HashMap<IdType, ClientBase<IdType>* > MapType;
215 void unregisterAll();
216 void detachEmbedder();
219 // Streams are a special class of clients since they are identified by a global label string instead of an id.
220 typedef ClientMapBase<String> StreamMap;
222 // All other types of clients use autogenerated integer ids.
223 class ClientMap : public IdGenerator, public ClientMapBase<int> { };
225 // Detached from a page, and hence from a embedder client.
226 void enterDetachedState();
228 void unregister(MediaStreamClient*);
229 void unregister(GenericClient*);
230 MediaStreamController* pageController() const;
231 MediaStream* getStreamFromLabel(const String&) const;
233 RequestMap m_requests;
238 bool m_isInDetachedState;
241 } // namespace WebCore
243 #endif // ENABLE(MEDIA_STREAM)
245 #endif // MediaStreamFrameController_h