Index: remoting/host/cast_extension_session.h |
diff --git a/remoting/host/cast_extension_session.h b/remoting/host/cast_extension_session.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..477dcac5a8fb0214b7ab1650a5525df0d2f3abf2 |
--- /dev/null |
+++ b/remoting/host/cast_extension_session.h |
@@ -0,0 +1,211 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef REMOTING_HOST_CAST_EXTENSION_SESSION_H_ |
+#define REMOTING_HOST_CAST_EXTENSION_SESSION_H_ |
+ |
+#include <string> |
+ |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/threading/thread.h" |
+#include "base/timer/timer.h" |
+#include "base/values.h" |
+#include "jingle/glue/thread_wrapper.h" |
+#include "remoting/host/host_extension_session.h" |
+#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" |
+#include "third_party/webrtc/base/scoped_ref_ptr.h" |
+#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" |
+ |
+namespace base { |
+class SingleThreadTaskRunner; |
+class WaitableEvent; |
+} // namespace base |
+ |
+namespace net { |
+class URLRequestContextGetter; |
+} // namespace net |
+ |
+namespace webrtc { |
+class MediaStreamInterface; |
+} // namespace webrtc |
+ |
+namespace remoting { |
+ |
+namespace protocol { |
+struct NetworkSettings; |
+} // namespace protocol |
+ |
+// A HostExtensionSession implementation that enables WebRTC support using |
+// the PeerConnection native API. |
+class CastExtensionSession : public HostExtensionSession, |
+ public webrtc::PeerConnectionObserver { |
+ public: |
+ virtual ~CastExtensionSession(); |
+ |
+ // Creates and returns a CastExtensionSession object, after performing |
+ // initialization steps on it. The caller must take ownership of the returned |
+ // object. |
+ static scoped_ptr<CastExtensionSession> Create( |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, |
+ const protocol::NetworkSettings& network_settings, |
+ ClientSessionControl* client_session_control, |
+ protocol::ClientStub* client_stub); |
+ |
+ // Called by webrtc::CreateSessionDescriptionObserver implementation. |
+ void OnCreateSessionDescription(webrtc::SessionDescriptionInterface* desc); |
+ void OnCreateSessionDescriptionFailure(const std::string& error); |
+ |
+ // HostExtensionSession interface. |
+ virtual scoped_ptr<webrtc::DesktopCapturer> OnCreateVideoCapturer( |
+ scoped_ptr<webrtc::DesktopCapturer> capturer) OVERRIDE; |
+ virtual bool ModifiesVideoPipeline() const OVERRIDE; |
+ virtual bool OnExtensionMessage( |
+ ClientSessionControl* client_session_control, |
+ protocol::ClientStub* client_stub, |
+ const protocol::ExtensionMessage& message) OVERRIDE; |
+ |
+ // webrtc::PeerConnectionObserver interface. |
+ virtual void OnError() OVERRIDE; |
+ virtual void OnSignalingChange( |
+ webrtc::PeerConnectionInterface::SignalingState new_state) OVERRIDE; |
+ virtual void OnStateChange( |
+ webrtc::PeerConnectionObserver::StateType state_changed) OVERRIDE; |
+ virtual void OnAddStream(webrtc::MediaStreamInterface* stream) OVERRIDE; |
+ virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) OVERRIDE; |
+ virtual void OnDataChannel( |
+ webrtc::DataChannelInterface* data_channel) OVERRIDE; |
+ virtual void OnRenegotiationNeeded() OVERRIDE; |
+ virtual void OnIceConnectionChange( |
+ webrtc::PeerConnectionInterface::IceConnectionState new_state) OVERRIDE; |
+ virtual void OnIceGatheringChange( |
+ webrtc::PeerConnectionInterface::IceGatheringState new_state) OVERRIDE; |
+ virtual void OnIceCandidate( |
+ const webrtc::IceCandidateInterface* candidate) OVERRIDE; |
+ virtual void OnIceComplete() OVERRIDE; |
+ |
+ private: |
+ CastExtensionSession( |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, |
+ const protocol::NetworkSettings& network_settings, |
+ ClientSessionControl* client_session_control, |
+ protocol::ClientStub* client_stub); |
+ |
+ // Parses |message| for a Session Description and sets the remote |
+ // description, returning true if successful. |
+ bool ParseAndSetRemoteDescription(base::DictionaryValue* message); |
+ |
+ // Parses |message| for a PeerConnection ICE candidate and adds it to the |
+ // Peer Connection, returning true if successful. |
+ bool ParseAndAddICECandidate(base::DictionaryValue* message); |
+ |
+ // Sends a message to the client through |client_stub_|. This method must be |
+ // called on the network thread. |
+ // |
+ // A protocol::ExtensionMessage consists of two string fields: type and data. |
+ // |
+ // The specifications for Cast Extension Messages are as follows: |
Wez
2014/08/14 19:22:03
nit: This line adds nothing.
aiguha
2014/08/15 04:11:39
Done.
|
+ // The type field must be |kExtensionMessageType|. |
+ // The data field must be a JSON formatted string with two compulsory |
+ // top level keys: |kTopLevelSubject| and |kTopLevelData|. |
+ // Thus, the data field of any properly formed Cast Extension Message should |
+ // look like: |
+ // {subject: '...', chromoting_data: '...'} |
Wez
2014/08/14 19:22:03
nit: Suggest just documenting what 'subject' and '
Wez
2014/08/14 19:22:03
Since the data portion is specific to this extensi
aiguha
2014/08/15 04:11:39
It's "chromoting_data" not just "data" because:
1.
aiguha
2014/08/15 04:11:39
I've made the comment clearer. Also added better e
|
+ // |
+ // The |subject| of a message describes the message to the receiving peer, so |
+ // the peer can easily decide what to do next. The |subject| MUST be one of |
Wez
2014/08/14 19:22:03
So the Subject is essentially the extension-specif
aiguha
2014/08/15 04:11:39
responded above
|
+ // constants formatted as kSubject* defined in the .cc file. This set of |
+ // subjects is identical between host and client, thus standardizing how they |
+ // communicate WebRTC signaling and other control messages. |
+ // The |data| of a message could be a simple string or another JSON-formatted |
+ // string. |
Wez
2014/08/14 19:22:03
Better to say that the type of 'data' depends on t
aiguha
2014/08/15 04:11:39
Done.
|
+ bool SendMessageToClient(const std::string& subject, const std::string& data); |
+ |
+ // Creates the jingle wrapper for the current thread, sets send to allowed, |
+ // and saves a pointer to the relevant thread pointer in ptr. If |event| |
+ // is not NULL, signals the event on completion. |
+ void EnsureTaskAndSetSend(rtc::Thread** ptr, |
+ base::WaitableEvent* event = NULL); |
+ |
+ // Wraps each task runner in JingleThreadWrapper using EnsureTaskAndSetSend(), |
+ // returning true if successful. Wrapping the task runners allows them to be |
+ // shared with and used by the (about to be created) PeerConnectionFactory. |
+ bool WrapTasksAndSave(); |
+ |
+ // Initializes PeerConnectionFactory and PeerConnection and sends a "ready" |
+ // message to client. Returns true if these steps are performed successfully. |
+ bool InitializePeerConnection(); |
+ |
+ // Constructs a CastVideoCapturerAdapter, a VideoSource, a VideoTrack and a |
+ // MediaStream |stream_|, which it adds to the |peer_connection_|. Returns |
+ // true if these steps are performed successfully. This method is called only |
+ // when a PeerConnection offer is received from the client. |
+ bool SetupVideoStream(scoped_ptr<webrtc::DesktopCapturer> desktop_capturer); |
+ |
+ // Polls a single stats report from the PeerConnection immediately. Called |
+ // periodically using |stats_polling_timer_| after a PeerConnection has been |
+ // established. |
+ void PollPeerConnectionStats(); |
+ |
+ // Closes |peer_connection_|, releases |peer_connection_|, |stream_| and |
+ // |peer_conn_factory_| and stops the worker thread. |
+ void CleanupPeerConnection(); |
+ |
+ // Check if the connection is active. |
+ bool connection_active() const; |
+ |
+ // TaskRunners that will be used to setup the PeerConnectionFactory's |
+ // signalling thread and worker thread respectively. |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
+ scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_; |
+ |
+ // Objects related to the WebRTC PeerConnection. |
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; |
+ rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_conn_factory_; |
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_; |
+ |
+ // Parameters passed to ChromiumPortAllocatorFactory on creation. |
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; |
+ const protocol::NetworkSettings& network_settings_; |
+ |
+ // Interface to interact with ClientSession. |
+ ClientSessionControl* client_session_control_; |
+ |
+ // Interface through which messages can be sent to the client. |
+ protocol::ClientStub* client_stub_; |
+ |
+ // Used to track webrtc connection statistics. |
+ rtc::scoped_refptr<webrtc::StatsObserver> stats_observer_; |
+ |
+ // Used to repeatedly poll stats from the |peer_connection_|. |
+ base::RepeatingTimer<CastExtensionSession> stats_polling_timer_; |
+ |
+ // True if a PeerConnection offer from the client has been received. This |
+ // necessarily means that the host is not the caller in this attempted |
+ // peer connection. |
+ bool received_offer_; |
+ |
+ // True if the webrtc::ScreenCapturer has been grabbed through the |
+ // OnCreateVideoCapturer() callback. |
+ bool has_grabbed_capturer_; |
+ |
+ // PeerConnection signaling and worker threads created from |
+ // JingleThreadWrappers. Each is created by calling |
+ // jingle_glue::EnsureForCurrentMessageLoop() and thus deletes itself |
+ // automatically when the associated MessageLoop is destroyed. |
+ rtc::Thread* signaling_thread_wrapper_; |
+ rtc::Thread* worker_thread_wrapper_; |
+ |
+ // Worker thread that is wrapped to create |worker_thread_wrapper_|. |
+ base::Thread worker_thread_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CastExtensionSession); |
+}; |
+ |
+} // namespace remoting |
+ |
+#endif // REMOTING_HOST_CAST_EXTENSION_SESSION_H_ |
+ |