1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef REMOTING_HOST_CAST_EXTENSION_SESSION_H_ 6#define REMOTING_HOST_CAST_EXTENSION_SESSION_H_ 7 8#include <string> 9 10#include "base/memory/ref_counted.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/threading/thread.h" 13#include "base/timer/timer.h" 14#include "base/values.h" 15#include "jingle/glue/thread_wrapper.h" 16#include "remoting/host/host_extension_session.h" 17#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" 18#include "third_party/webrtc/base/scoped_ref_ptr.h" 19#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" 20 21namespace base { 22class SingleThreadTaskRunner; 23class WaitableEvent; 24} // namespace base 25 26namespace net { 27class URLRequestContextGetter; 28} // namespace net 29 30namespace webrtc { 31class MediaStreamInterface; 32} // namespace webrtc 33 34namespace remoting { 35 36class CastCreateSessionDescriptionObserver; 37 38namespace protocol { 39struct NetworkSettings; 40} // namespace protocol 41 42// A HostExtensionSession implementation that enables WebRTC support using 43// the PeerConnection native API. 44class CastExtensionSession : public HostExtensionSession, 45 public webrtc::PeerConnectionObserver { 46 public: 47 virtual ~CastExtensionSession(); 48 49 // Creates and returns a CastExtensionSession object, after performing 50 // initialization steps on it. The caller must take ownership of the returned 51 // object. 52 static scoped_ptr<CastExtensionSession> Create( 53 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 54 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, 55 const protocol::NetworkSettings& network_settings, 56 ClientSessionControl* client_session_control, 57 protocol::ClientStub* client_stub); 58 59 // Called by webrtc::CreateSessionDescriptionObserver implementation. 60 void OnCreateSessionDescription(webrtc::SessionDescriptionInterface* desc); 61 void OnCreateSessionDescriptionFailure(const std::string& error); 62 63 // HostExtensionSession interface. 64 virtual void OnCreateVideoCapturer( 65 scoped_ptr<webrtc::DesktopCapturer>* capturer) OVERRIDE; 66 virtual bool ModifiesVideoPipeline() const OVERRIDE; 67 virtual bool OnExtensionMessage( 68 ClientSessionControl* client_session_control, 69 protocol::ClientStub* client_stub, 70 const protocol::ExtensionMessage& message) OVERRIDE; 71 72 // webrtc::PeerConnectionObserver interface. 73 virtual void OnError() OVERRIDE; 74 virtual void OnSignalingChange( 75 webrtc::PeerConnectionInterface::SignalingState new_state) OVERRIDE; 76 virtual void OnStateChange( 77 webrtc::PeerConnectionObserver::StateType state_changed) OVERRIDE; 78 virtual void OnAddStream(webrtc::MediaStreamInterface* stream) OVERRIDE; 79 virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) OVERRIDE; 80 virtual void OnDataChannel( 81 webrtc::DataChannelInterface* data_channel) OVERRIDE; 82 virtual void OnRenegotiationNeeded() OVERRIDE; 83 virtual void OnIceConnectionChange( 84 webrtc::PeerConnectionInterface::IceConnectionState new_state) OVERRIDE; 85 virtual void OnIceGatheringChange( 86 webrtc::PeerConnectionInterface::IceGatheringState new_state) OVERRIDE; 87 virtual void OnIceCandidate( 88 const webrtc::IceCandidateInterface* candidate) OVERRIDE; 89 virtual void OnIceComplete() OVERRIDE; 90 91 private: 92 CastExtensionSession( 93 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 94 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, 95 const protocol::NetworkSettings& network_settings, 96 ClientSessionControl* client_session_control, 97 protocol::ClientStub* client_stub); 98 99 // Parses |message| for a Session Description and sets the remote 100 // description, returning true if successful. 101 bool ParseAndSetRemoteDescription(base::DictionaryValue* message); 102 103 // Parses |message| for a PeerConnection ICE candidate and adds it to the 104 // Peer Connection, returning true if successful. 105 bool ParseAndAddICECandidate(base::DictionaryValue* message); 106 107 // Sends a message to the client through |client_stub_|. This method must be 108 // called on the network thread. 109 // 110 // A protocol::ExtensionMessage consists of two string fields: type and data. 111 // 112 // The type field must be |kExtensionMessageType|. 113 // The data field must be a JSON formatted string with two compulsory 114 // top level keys: |kTopLevelSubject| and |kTopLevelData|. 115 // 116 // The |subject| of a message describes the message to the receiving peer, 117 // effectively identifying the command the receiving peer should perform. 118 // The |subject| MUST be one of constants formatted as kSubject* defined in 119 // the .cc file. This set of subjects is identical between host and client, 120 // thus standardizing how they communicate. 121 // The |data| of a message depends on the |subject| of the message. 122 // 123 // Examples of what ExtensionMessage.data() could look like: 124 // 125 // Host Ready Message: 126 // Notifies the remote peer that we are ready to receive an offer. 127 // 128 // { 129 // "subject": "ready", 130 // "chromoting_data": "Host Ready to receive offers" 131 // } 132 // 133 // WebRTC Offer Message: 134 // Represents the offer received from the remote peer. The local 135 // peer would then respond with a webrtc_answer message. 136 // { 137 // "subject": "webrtc_offer", 138 // "chromoting_data": { 139 // "sdp" : "...", 140 // "type" : "offer" 141 // } 142 // } 143 // 144 // WebRTC Candidate Message: 145 // Represents an ICE candidate received from the remote peer. Each peer 146 // shares its local ICE candidates in this way, until a connection is 147 // established. 148 // 149 // { 150 // "subject": "webrtc_candidate", 151 // "chromoting_data": { 152 // "candidate" : "...", 153 // "sdpMid" : "...", 154 // "sdpMLineIndex" : "..." 155 // } 156 // } 157 // 158 bool SendMessageToClient(const std::string& subject, const std::string& data); 159 160 // Creates the jingle wrapper for the current thread, sets send to allowed, 161 // and saves a pointer to the relevant thread pointer in ptr. If |event| 162 // is not NULL, signals the event on completion. 163 void EnsureTaskAndSetSend(rtc::Thread** ptr, 164 base::WaitableEvent* event = NULL); 165 166 // Wraps each task runner in JingleThreadWrapper using EnsureTaskAndSetSend(), 167 // returning true if successful. Wrapping the task runners allows them to be 168 // shared with and used by the (about to be created) PeerConnectionFactory. 169 bool WrapTasksAndSave(); 170 171 // Initializes PeerConnectionFactory and PeerConnection and sends a "ready" 172 // message to client. Returns true if these steps are performed successfully. 173 bool InitializePeerConnection(); 174 175 // Constructs a CastVideoCapturerAdapter, a VideoSource, a VideoTrack and a 176 // MediaStream |stream_|, which it adds to the |peer_connection_|. Returns 177 // true if these steps are performed successfully. This method is called only 178 // when a PeerConnection offer is received from the client. 179 bool SetupVideoStream(scoped_ptr<webrtc::DesktopCapturer> desktop_capturer); 180 181 // Polls a single stats report from the PeerConnection immediately. Called 182 // periodically using |stats_polling_timer_| after a PeerConnection has been 183 // established. 184 void PollPeerConnectionStats(); 185 186 // Closes |peer_connection_|, releases |peer_connection_|, |stream_| and 187 // |peer_conn_factory_| and stops the worker thread. 188 void CleanupPeerConnection(); 189 190 // Check if the connection is active. 191 bool connection_active() const; 192 193 // TaskRunners that will be used to setup the PeerConnectionFactory's 194 // signalling thread and worker thread respectively. 195 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 196 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_; 197 198 // Objects related to the WebRTC PeerConnection. 199 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; 200 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_conn_factory_; 201 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_; 202 rtc::scoped_refptr<CastCreateSessionDescriptionObserver> 203 create_session_desc_observer_; 204 205 // Parameters passed to ChromiumPortAllocatorFactory on creation. 206 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 207 const protocol::NetworkSettings& network_settings_; 208 209 // Interface to interact with ClientSession. 210 ClientSessionControl* client_session_control_; 211 212 // Interface through which messages can be sent to the client. 213 protocol::ClientStub* client_stub_; 214 215 // Used to track webrtc connection statistics. 216 rtc::scoped_refptr<webrtc::StatsObserver> stats_observer_; 217 218 // Used to repeatedly poll stats from the |peer_connection_|. 219 base::RepeatingTimer<CastExtensionSession> stats_polling_timer_; 220 221 // True if a PeerConnection offer from the client has been received. This 222 // necessarily means that the host is not the caller in this attempted 223 // peer connection. 224 bool received_offer_; 225 226 // True if the webrtc::ScreenCapturer has been grabbed through the 227 // OnCreateVideoCapturer() callback. 228 bool has_grabbed_capturer_; 229 230 // PeerConnection signaling and worker threads created from 231 // JingleThreadWrappers. Each is created by calling 232 // jingle_glue::EnsureForCurrentMessageLoop() and thus deletes itself 233 // automatically when the associated MessageLoop is destroyed. 234 rtc::Thread* signaling_thread_wrapper_; 235 rtc::Thread* worker_thread_wrapper_; 236 237 // Worker thread that is wrapped to create |worker_thread_wrapper_|. 238 base::Thread worker_thread_; 239 240 DISALLOW_COPY_AND_ASSIGN(CastExtensionSession); 241}; 242 243} // namespace remoting 244 245#endif // REMOTING_HOST_CAST_EXTENSION_SESSION_H_ 246