initial import
[vuplus_webkit] / Source / WebCore / page / MediaStreamFrameController.h
1 /*
2  * Copyright (C) 2011 Google 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'' 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.
23  */
24
25 #ifndef MediaStreamFrameController_h
26 #define MediaStreamFrameController_h
27
28 #if ENABLE(MEDIA_STREAM)
29
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>
37
38 namespace WebCore {
39
40 class Frame;
41 class LocalMediaStream;
42 class MediaStream;
43 class MediaStreamController;
44 class MediaStreamTrackList;
45 class NavigatorUserMediaErrorCallback;
46 class NavigatorUserMediaSuccessCallback;
47 class Page;
48 class PeerConnection;
49 class ScriptExecutionContext;
50 class SecurityOrigin;
51 class SignalingCallback;
52
53 class MediaStreamFrameController {
54     WTF_MAKE_NONCOPYABLE(MediaStreamFrameController);
55 public:
56     template <typename IdType>
57     class ClientBase {
58         WTF_MAKE_NONCOPYABLE(ClientBase);
59     public:
60         ClientBase() : m_frameController(0), m_clientId(0) { }
61
62         ClientBase(MediaStreamFrameController* frameController, const IdType& id)
63             : m_frameController(frameController)
64             , m_clientId(id) { }
65
66         virtual ~ClientBase() { }
67
68         MediaStreamFrameController* mediaStreamFrameController() const { return m_frameController; }
69         const IdType& clientId() const { return m_clientId; }
70
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; }
75
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() { }
79
80     protected:
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)
83         {
84             ASSERT(!m_frameController && !m_clientId);
85             m_frameController = frameController;
86             m_clientId = id;
87         }
88
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)
94         {
95             if (!m_frameController)
96                 return;
97
98             m_frameController->unregister(static_cast<ClientType*>(client));
99             m_frameController = 0;
100         }
101
102         virtual void unregister() = 0;
103         friend class MediaStreamFrameController;
104
105         MediaStreamFrameController* m_frameController;
106         IdType m_clientId;
107     };
108
109     class MediaStreamClient : public ClientBase<String> {
110     public:
111         MediaStreamClient(MediaStreamFrameController* frameController, const String& label, bool isLocalMediaStream)
112             : ClientBase<String>(frameController, label)
113             , m_isLocalMediaStream(isLocalMediaStream) { }
114
115         virtual ~MediaStreamClient() { unregister(); }
116
117         virtual bool isMediaStream() const { return true; }
118
119         // Accessed by the destructor.
120         virtual bool isLocalMediaStream() const { return m_isLocalMediaStream; }
121
122         // Stream has ended for some external reason.
123         virtual void streamEnded() = 0;
124
125     private:
126         virtual void unregister() { unregisterClient(this); }
127         bool m_isLocalMediaStream;
128     };
129
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> {
133     public:
134         GenericClient() { }
135         GenericClient(MediaStreamFrameController* frameController, int id) : ClientBase<int>(frameController, id) { }
136         virtual ~GenericClient() { unregister(); }
137         virtual bool isGenericClient() const { return true; }
138
139     private:
140         virtual void unregister() { unregisterClient(this); }
141     };
142
143     class PeerConnectionClient : public GenericClient {
144     public:
145         PeerConnectionClient(MediaStreamFrameController* frameController, int id) : GenericClient(frameController, id) { }
146         virtual ~PeerConnectionClient() { }
147         virtual bool isPeerConnection() const { return true; }
148     };
149
150     MediaStreamFrameController(Frame*);
151     virtual ~MediaStreamFrameController();
152
153     SecurityOrigin* securityOrigin() const;
154     ScriptExecutionContext* scriptExecutionContext() const;
155
156     bool isClientAvailable() const;
157     void disconnectPage();
158     void disconnectFrame();
159     void transferToNewPage(Page*);
160
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);
165
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);
174
175     // --- Calls coming back from the controller. --- //
176
177     void streamGenerated(int requestId, const String& streamLabel, PassRefPtr<MediaStreamTrackList> tracks);
178     void streamGenerationFailed(int requestId, NavigatorUserMediaError::ErrorCode);
179     void streamFailed(const String& streamLabel);
180
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);
187
188 private:
189     class Request;
190     class GenerateStreamRequest;
191
192     class IdGenerator {
193         WTF_MAKE_NONCOPYABLE(IdGenerator);
194     public:
195         IdGenerator() : m_id(0) { }
196         int getNextId() { return ++m_id; }
197
198     private:
199         int m_id;
200     };
201
202     class RequestMap : public IdGenerator, public HashMap<int, RefPtr<Request> > {
203     public:
204         void abort(int requestId);
205         void abortAll();
206     };
207
208     template <typename IdType>
209     class ClientMapBase : public HashMap<IdType, ClientBase<IdType>* > {
210         WTF_MAKE_NONCOPYABLE(ClientMapBase);
211     public:
212         typedef HashMap<IdType, ClientBase<IdType>* > MapType;
213
214         ClientMapBase() { }
215         void unregisterAll();
216         void detachEmbedder();
217     };
218
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;
221
222     // All other types of clients use autogenerated integer ids.
223     class ClientMap : public IdGenerator, public ClientMapBase<int> { };
224
225     // Detached from a page, and hence from a embedder client.
226     void enterDetachedState();
227
228     void unregister(MediaStreamClient*);
229     void unregister(GenericClient*);
230     MediaStreamController* pageController() const;
231     MediaStream* getStreamFromLabel(const String&) const;
232
233     RequestMap m_requests;
234     ClientMap m_clients;
235     StreamMap m_streams;
236
237     Frame* m_frame;
238     bool m_isInDetachedState;
239 };
240
241 } // namespace WebCore
242
243 #endif // ENABLE(MEDIA_STREAM)
244
245 #endif // MediaStreamFrameController_h