Index: extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc |
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc |
index 78fd28587f6498b015805e2e3b36b21c78dcfa13..a9bd7394b5b54f46d0632b01b8b4daf1fe666aa5 100644 |
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc |
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc |
@@ -8,9 +8,23 @@ |
#include "base/timer/timer.h" |
#include "content/public/common/service_registry.h" |
#include "content/public/renderer/render_frame.h" |
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h" |
+#include "third_party/wds/src/libwds/public/logging.h" |
+#include "third_party/wds/src/libwds/public/media_manager.h" |
namespace { |
const char kErrorInternal[] = "An internal error has occurred"; |
+const char kErrorTimeout[] = "Sink became unresponsive"; |
+ |
+static void LogWDSError(const char* format, ...) { |
+ va_list args; |
+ va_start(args, format); |
+ char buffer[256]; |
+ vsnprintf(buffer, 256, format, args); |
+ va_end(args); |
+ DVLOG(1) << "[WDS] " << buffer; |
+} |
+ |
} // namespace |
namespace extensions { |
@@ -21,17 +35,20 @@ WiFiDisplaySession::WiFiDisplaySession( |
const DisplaySourceSessionParams& params) |
: binding_(this), |
params_(params), |
+ cseq_(0), |
+ timer_id_(0), |
weak_factory_(this) { |
DCHECK(params_.render_frame); |
+ wds::LogSystem::set_error_func(&LogWDSError); |
params.render_frame->GetServiceRegistry()->ConnectToRemoteService( |
mojo::GetProxy(&service_)); |
service_.set_connection_error_handler(base::Bind( |
- &WiFiDisplaySession::OnConnectionError, |
+ &WiFiDisplaySession::OnIPCConnectionError, |
weak_factory_.GetWeakPtr())); |
service_->SetClient(binding_.CreateInterfacePtrAndBind()); |
binding_.set_connection_error_handler(base::Bind( |
- &WiFiDisplaySession::OnConnectionError, |
+ &WiFiDisplaySession::OnIPCConnectionError, |
weak_factory_.GetWeakPtr())); |
} |
@@ -60,7 +77,9 @@ void WiFiDisplaySession::Terminate(const CompletionCallback& callback) { |
void WiFiDisplaySession::OnConnected(const mojo::String& ip_address) { |
DCHECK_EQ(DisplaySourceSession::Established, state_); |
ip_address_ = ip_address; |
- // TODO(Mikhail): Start Wi-Fi Display session control message exchange. |
+ media_manager_.reset(new WiFiDisplayMediaManager()); |
+ wfd_source_.reset(wds::Source::Create(this, media_manager_.get(), this)); |
+ wfd_source_->Start(); |
} |
void WiFiDisplaySession::OnConnectRequestHandled(bool success, |
@@ -74,6 +93,8 @@ void WiFiDisplaySession::OnConnectRequestHandled(bool success, |
void WiFiDisplaySession::OnTerminated() { |
DCHECK_NE(DisplaySourceSession::Idle, state_); |
state_ = DisplaySourceSession::Idle; |
+ media_manager_.reset(); |
+ wfd_source_.reset(); |
terminated_callback_.Run(); |
} |
@@ -92,9 +113,11 @@ void WiFiDisplaySession::OnError(int32_t type, |
void WiFiDisplaySession::OnMessage(const mojo::String& data) { |
DCHECK_EQ(DisplaySourceSession::Established, state_); |
+ DCHECK(wfd_source_); |
+ wfd_source_->RTSPDataReceived(data); |
} |
-void WiFiDisplaySession::OnConnectionError() { |
+void WiFiDisplaySession::OnIPCConnectionError() { |
// We must explicitly notify the session termination as it will never |
// arrive from browser process (IPC is broken). |
switch (state_) { |
@@ -114,6 +137,64 @@ void WiFiDisplaySession::OnConnectionError() { |
} |
} |
+std::string WiFiDisplaySession::GetLocalIPAddress() const { |
+ return ip_address_; |
+} |
+ |
+int WiFiDisplaySession::GetNextCSeq(int* initial_peer_cseq) const { |
+ return ++cseq_; |
+} |
+ |
+void WiFiDisplaySession::SendRTSPData(const std::string& message) { |
+ service_->SendMessage(message); |
+} |
+ |
+unsigned WiFiDisplaySession::CreateTimer(int seconds) { |
+ scoped_ptr<base::Timer> timer(new base::Timer(true, true)); |
+ auto insert_ret = timers_.insert( |
+ std::pair<int, scoped_ptr<base::Timer>>( |
+ ++timer_id_, std::move(timer))); |
+ DCHECK(insert_ret.second); |
+ timer->Start(FROM_HERE, |
+ base::TimeDelta::FromSeconds(seconds), |
+ base::Bind(&wds::Source::OnTimerEvent, |
+ base::Unretained(wfd_source_.get()), |
+ timer_id_)); |
+ return static_cast<unsigned>(timer_id_); |
+} |
+ |
+void WiFiDisplaySession::ReleaseTimer(unsigned timer_id) { |
+ auto it = timers_.find(static_cast<int>(timer_id)); |
+ if (it != timers_.end()) |
+ timers_.erase(it); |
+} |
+ |
+void WiFiDisplaySession::ErrorOccurred(wds::ErrorType error) { |
+ DCHECK_NE(DisplaySourceSession::Idle, state_); |
+ if (error == wds::TimeoutError) { |
+ error_callback_.Run(api::display_source::ERROR_TYPE_TIMEOUT_ERROR, |
+ kErrorTimeout); |
+ } else { |
+ error_callback_.Run(api::display_source::ERROR_TYPE_UNKNOWN_ERROR, |
+ kErrorInternal); |
+ } |
+ |
+ if (state_ == DisplaySourceSession::Established) { |
+ // The session cannot continue. |
+ service_->Disconnect(); |
+ state_ = DisplaySourceSession::Terminating; |
+ } |
+} |
+ |
+void WiFiDisplaySession::SessionCompleted() { |
+ DCHECK_NE(DisplaySourceSession::Idle, state_); |
+ if (state_ == DisplaySourceSession::Established) { |
+ // The session has finished normally. |
+ service_->Disconnect(); |
+ state_ = DisplaySourceSession::Terminating; |
+ } |
+} |
+ |
void WiFiDisplaySession::RunStartCallback(bool success, |
const std::string& error_message) { |
if (!start_completion_callback_.is_null()) |