summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikhail.pozdnyakov <mikhail.pozdnyakov@intel.com>2016-02-29 00:59:33 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-29 09:00:41 +0000
commitda8ee699b156b3d8d82b16285039f7bf7d80b720 (patch)
treeb30559a99b6d2f2057fabcbdc3ebf8421c6baa46
parent724a18da5c695cfea307116a6bde98f7aef11663 (diff)
downloadchromium_src-da8ee699b156b3d8d82b16285039f7bf7d80b720.zip
chromium_src-da8ee699b156b3d8d82b16285039f7bf7d80b720.tar.gz
chromium_src-da8ee699b156b3d8d82b16285039f7bf7d80b720.tar.bz2
[chrome.displaySource] Use WDS for Wi-Fi Display implementation
The WDS library implements a Wi-Fi Display dialect of RTSP that includes the parser, actual negotiation logic for sink and source, and the related data structures. This patch contains initial implementation of WDS library embedder interfaces. BUG=242107 Review URL: https://codereview.chromium.org/1698473004 Cr-Commit-Position: refs/heads/master@{#378182}
-rw-r--r--extensions/browser/BUILD.gn7
-rw-r--r--extensions/common/BUILD.gn7
-rw-r--r--extensions/extensions.gyp5
-rw-r--r--extensions/extensions.gypi4
-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
10 files changed, 283 insertions, 8 deletions
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 5665b9d..e044a7a 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -101,6 +101,13 @@ source_set("browser") {
sources += win_or_mac_sources
}
}
+ if (enable_wifi_display) {
+ wifi_display_sources = rebase_path(
+ extensions_gypi_values.extensions_browser_sources_wifi_display,
+ ".",
+ "//extensions")
+ sources += wifi_display_sources
+ }
}
}
}
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index b0f40b5..13c2f2e 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -22,6 +22,13 @@ if (enable_extensions) {
sources = rebase_path(extensions_gypi_values.extensions_common_mojo_sources,
".",
"//extensions")
+ if (enable_wifi_display) {
+ wifi_display_sources = rebase_path(
+ extensions_gypi_values.extensions_common_mojo_sources_wifi_display,
+ ".",
+ "//extensions")
+ sources += wifi_display_sources
+ }
}
# GYP version: extensions/extensions.gyp:extensions_common
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 0dda3f7..82e7d6a 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -217,8 +217,11 @@
'msvs_disabled_warnings': [ 4267, ],
'conditions': [
['enable_wifi_display==1', {
+ 'dependencies': [
+ '../third_party/wds/wds.gyp:libwds',
+ ],
'sources': [
- '<@(extensions_render_sources_wifi_display)',
+ '<@(extensions_renderer_sources_wifi_display)',
],
}],
],
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi
index d92bf49..04f3e45 100644
--- a/extensions/extensions.gypi
+++ b/extensions/extensions.gypi
@@ -1033,7 +1033,9 @@
'renderer/worker_script_context_set.cc',
'renderer/worker_script_context_set.h',
],
- 'extensions_render_sources_wifi_display': [
+ 'extensions_renderer_sources_wifi_display': [
+ 'renderer/api/display_source/wifi_display/wifi_display_media_manager.cc',
+ 'renderer/api/display_source/wifi_display/wifi_display_media_manager.h',
'renderer/api/display_source/wifi_display/wifi_display_session.cc',
'renderer/api/display_source/wifi_display/wifi_display_session.h',
],
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);