diff options
Diffstat (limited to 'extensions/renderer')
6 files changed, 262 insertions, 6 deletions
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index 9606e85..1b8f7d0 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn @@ -31,4 +31,14 @@ source_set("renderer") { "//skia", "//third_party/WebKit/public:blink", ] + + if (enable_wifi_display) { + wifi_display_sources = rebase_path( + extensions_gypi_values.extensions_renderer_sources_wifi_display, + ".", + "//extensions") + sources += wifi_display_sources + + deps += [ "//third_party/wds:libwds" ] + } } diff --git a/extensions/renderer/DEPS b/extensions/renderer/DEPS index bd0ed52..6d144629 100644 --- a/extensions/renderer/DEPS +++ b/extensions/renderer/DEPS @@ -13,6 +13,8 @@ include_rules = [ "+third_party/WebKit/public/platform", "+third_party/WebKit/public/web", + "+third_party/wds/src/libwds/public", + "+tools/json_schema_compiler", "-v8", diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc new file mode 100644 index 0000000..e534a9b --- /dev/null +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc @@ -0,0 +1,85 @@ +// Copyright 2016 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. + +#include "extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h" + +#include "base/logging.h" +#include "base/rand_util.h" + +namespace extensions { + +WiFiDisplayMediaManager::WiFiDisplayMediaManager() { +} + +WiFiDisplayMediaManager::~WiFiDisplayMediaManager() { +} + +void WiFiDisplayMediaManager::Play() { + NOTIMPLEMENTED(); +} + +void WiFiDisplayMediaManager::Teardown() { + NOTIMPLEMENTED(); +} + +void WiFiDisplayMediaManager::Pause() { + NOTIMPLEMENTED(); +} + +bool WiFiDisplayMediaManager::IsPaused() const { + NOTIMPLEMENTED(); + return true; +} + +wds::SessionType WiFiDisplayMediaManager::GetSessionType() const { + NOTIMPLEMENTED(); + return wds::AudioVideoSession; +} + +void WiFiDisplayMediaManager::SetSinkRtpPorts(int port1, int port2) { + NOTIMPLEMENTED(); +} + +std::pair<int,int> WiFiDisplayMediaManager::GetSinkRtpPorts() const { + NOTIMPLEMENTED(); + return std::pair<int,int>(); +} + +int WiFiDisplayMediaManager::GetLocalRtpPort() const { + NOTIMPLEMENTED(); + return 0; +} + +wds::H264VideoFormat WiFiDisplayMediaManager::GetOptimalVideoFormat() const { + NOTIMPLEMENTED(); + return wds::H264VideoFormat(); +} + +void WiFiDisplayMediaManager::SendIDRPicture() { + NOTIMPLEMENTED(); +} + +std::string WiFiDisplayMediaManager::GetSessionId() const { + return base::RandBytesAsString(8); +} + +bool WiFiDisplayMediaManager::InitOptimalVideoFormat( + const wds::NativeVideoFormat& sink_native_format, + const std::vector<wds::H264VideoCodec>& sink_supported_codecs) { + NOTIMPLEMENTED(); + return false; +} + +bool WiFiDisplayMediaManager::InitOptimalAudioFormat( + const std::vector<wds::AudioCodec>& sink_codecs) { + NOTIMPLEMENTED(); + return false; +} + +wds::AudioCodec WiFiDisplayMediaManager::GetOptimalAudioFormat() const { + NOTIMPLEMENTED(); + return wds::AudioCodec(); +} + +} // namespace extensions diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h new file mode 100644 index 0000000..6b64547 --- /dev/null +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h @@ -0,0 +1,47 @@ +// Copyright 2016 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 EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_MEDIA_MANAGER_H_ +#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_MEDIA_MANAGER_H_ + +#include "base/macros.h" +#include "third_party/wds/src/libwds/public/media_manager.h" + +namespace extensions { + +class WiFiDisplayMediaManager : public wds::SourceMediaManager { + public: + WiFiDisplayMediaManager(); + ~WiFiDisplayMediaManager() override; + + private: + // wds::SourceMediaManager overrides. + void Play() override; + + void Pause() override; + void Teardown() override; + bool IsPaused() const override; + wds::SessionType GetSessionType() const override; + void SetSinkRtpPorts(int port1, int port2) override; + std::pair<int,int> GetSinkRtpPorts() const override; + int GetLocalRtpPort() const override; + + bool InitOptimalVideoFormat( + const wds::NativeVideoFormat& sink_native_format, + const std::vector<wds::H264VideoCodec>& sink_supported_codecs) override; + wds::H264VideoFormat GetOptimalVideoFormat() const override; + bool InitOptimalAudioFormat( + const std::vector<wds::AudioCodec>& sink_supported_codecs) override; + wds::AudioCodec GetOptimalAudioFormat() const override; + + void SendIDRPicture() override; + + std::string GetSessionId() const override; + + DISALLOW_COPY_AND_ASSIGN(WiFiDisplayMediaManager); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_MEDIA_MANAGER_H_ 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 78fd285..a9bd739 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()) diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_session.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_session.h index 7eeb987..6d0e8cb 100644 --- a/extensions/renderer/api/display_source/wifi_display/wifi_display_session.h +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_session.h @@ -5,16 +5,29 @@ #ifndef EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_H_ #define EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_H_ +#include <map> #include <string> #include "extensions/common/mojo/wifi_display_session_service.mojom.h" #include "extensions/renderer/api/display_source/display_source_session.h" #include "mojo/public/cpp/bindings/binding.h" +#include "third_party/wds/src/libwds/public/source.h" + +namespace base { +class Timer; +} // namespace base namespace extensions { +class WiFiDisplayMediaManager; + +// This class represents a single Wi-Fi Display session. +// It manages life-cycle of the session and it is also responsible for +// exchange of session controlling (RTSP) messages with the sink. class WiFiDisplaySession: public DisplaySourceSession, - public WiFiDisplaySessionServiceClient { + public WiFiDisplaySessionServiceClient, + public wds::Peer::Delegate, + public wds::Peer::Observer { public: explicit WiFiDisplaySession( const DisplaySourceSessionParams& params); @@ -36,19 +49,37 @@ class WiFiDisplaySession: public DisplaySourceSession, void OnError(int32_t type, const mojo::String& description) override; void OnMessage(const mojo::String& data) override; + // wds::Peer::Delegate overrides. + unsigned CreateTimer(int seconds) override; + void ReleaseTimer(unsigned timer_id) override; + void SendRTSPData(const std::string& message) override; + std::string GetLocalIPAddress() const override; + int GetNextCSeq(int* initial_peer_cseq = nullptr) const override; + + // wds::Peer::Observer overrides. + void ErrorOccurred(wds::ErrorType error) override; + void SessionCompleted() override; + // A connection error handler for the mojo objects used in this class. - void OnConnectionError(); + void OnIPCConnectionError(); void RunStartCallback(bool success, const std::string& error = ""); void RunTerminateCallback(bool success, const std::string& error = ""); private: + scoped_ptr<wds::Source> wfd_source_; + scoped_ptr<WiFiDisplayMediaManager> media_manager_; WiFiDisplaySessionServicePtr service_; mojo::Binding<WiFiDisplaySessionServiceClient> binding_; std::string ip_address_; + std::map<int, scoped_ptr<base::Timer>> timers_; + DisplaySourceSessionParams params_; CompletionCallback start_completion_callback_; CompletionCallback teminate_completion_callback_; + // Holds sequence number for the following RTSP request-response pair. + mutable int cseq_; + int timer_id_; base::WeakPtrFactory<WiFiDisplaySession> weak_factory_; DISALLOW_COPY_AND_ASSIGN(WiFiDisplaySession); |