summaryrefslogtreecommitdiffstats
path: root/extensions/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/renderer')
-rw-r--r--extensions/renderer/BUILD.gn10
-rw-r--r--extensions/renderer/DEPS2
-rw-r--r--extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc85
-rw-r--r--extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h47
-rw-r--r--extensions/renderer/api/display_source/wifi_display/wifi_display_session.cc89
-rw-r--r--extensions/renderer/api/display_source/wifi_display/wifi_display_session.h35
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);