Commit 61a28e37 authored by mikhail.pozdnyakov's avatar mikhail.pozdnyakov Committed by Commit bot

Add WiFi Display session class skeleton and mojo service

This patch introduces a WiFi Display session class
skeleton and mojo service which provides network
access for the render-hosted session.

The introduced code is compiled only if a newly added
'enable_wifi_display' build option is set.

Besides, some minor changes were applied to the
DisplaySourceConnectionDelegate interface in order
to better define its methods behavior.

BUG=242107

Review URL: https://codereview.chromium.org/1540563002

Cr-Commit-Position: refs/heads/master@{#369415}
parent c2103fb0
......@@ -88,6 +88,9 @@
# Enable Wayland display server support.
'enable_wayland_server%' : 0,
# Enable Wi-Fi Display support.
'enable_wifi_display%' : 0,
# By default we build against a stable sysroot image to avoid
# depending on the packages installed on the local machine. Set this
# to 0 to build against locally installed headers and libraries (e.g.
......@@ -166,6 +169,7 @@
'enable_hidpi%': '<(enable_hidpi)',
'enable_topchrome_md%': '<(enable_topchrome_md)',
'enable_wayland_server%': '<(enable_wayland_server)',
'enable_wifi_display%': '<(enable_wifi_display)',
'buildtype%': '<(buildtype)',
'branding%': '<(branding)',
'branding_path_component%': '<(branding)',
......@@ -351,6 +355,7 @@
'enable_hidpi%': '<(enable_hidpi)',
'enable_topchrome_md%': '<(enable_topchrome_md)',
'enable_wayland_server%': '<(enable_wayland_server)',
'enable_wifi_display%': '<(enable_wifi_display)',
'android_channel%': '<(android_channel)',
'use_goma%': '<(use_goma)',
'gomadir%': '<(gomadir)',
......@@ -1153,6 +1158,7 @@
'enable_hidpi%': '<(enable_hidpi)',
'enable_topchrome_md%': '<(enable_topchrome_md)',
'enable_wayland_server%': '<(enable_wayland_server)',
'enable_wifi_display%': '<(enable_wifi_display)',
'image_loader_extension%': '<(image_loader_extension)',
'fastbuild%': '<(fastbuild)',
'dont_embed_build_metadata%': '<(dont_embed_build_metadata)',
......@@ -2776,6 +2782,9 @@
['enable_wayland_server==1', {
'defines': ['ENABLE_WAYLAND_SERVER=1'],
}],
['enable_wifi_display==1', {
'defines': ['ENABLE_WIFI_DISPLAY=1'],
}],
['use_udev==1', {
'defines': ['USE_UDEV'],
}],
......
......@@ -231,6 +231,9 @@ config("feature_flags") {
if (enable_wayland_server) {
defines += [ "ENABLE_WAYLAND_SERVER=1" ]
}
if (enable_wifi_display) {
defines += [ "ENABLE_WIFI_DISPLAY=1" ]
}
if (proprietary_codecs) {
defines += [ "USE_PROPRIETARY_CODECS" ]
}
......
......@@ -115,6 +115,9 @@ declare_args() {
fieldtrial_testing_like_official_build = is_chrome_branded
use_cups = (is_desktop_linux || is_mac) && !is_chromecast && !is_headless
# Enables Wi-Fi Display functionality
enable_wifi_display = false
}
# Default these based on the explicit value of enable_nacl, not just
......
......@@ -51,17 +51,15 @@ class MockDisplaySourceConnectionDelegate
void Connect(int sink_id,
const DisplaySourceAuthInfo& auth_info,
const base::Closure& connected_callback,
const FailureCallback& failure_callback) override {}
void Disconnect(const base::Closure& disconnected_callback,
const FailureCallback& failure_callback) override {}
void Disconnect(const FailureCallback& failure_callback) override {}
void StartWatchingSinks() override {
void StartWatchingAvailableSinks() override {
AddSink(CreateSinkInfoPtr(2, "sink 2", SINK_STATE_DISCONNECTED));
}
void StopWatchingSinks() override {}
void StopWatchingAvailableSinks() override {}
private:
void AddSink(DisplaySourceSinkInfoPtr sink) {
......
......@@ -18,8 +18,7 @@ using DisplaySourceAuthInfo = api::display_source::AuthenticationInfo;
// The DisplaySourceConnectionDelegate interface should be implemented
// to provide sinks search and connection functionality for
// 'chrome.displaySource'
// API.
// 'chrome.displaySource' API.
class DisplaySourceConnectionDelegate : public KeyedService {
public:
using AuthInfoCallback = base::Callback<void(const DisplaySourceAuthInfo&)>;
......@@ -27,6 +26,8 @@ class DisplaySourceConnectionDelegate : public KeyedService {
using SinkInfoListCallback =
base::Callback<void(const DisplaySourceSinkInfoList&)>;
const static int kInvalidSinkId = -1;
struct Connection {
Connection();
~Connection();
......@@ -37,10 +38,11 @@ class DisplaySourceConnectionDelegate : public KeyedService {
class Observer {
public:
// This method is called each tiome the list of available
// This method is called each time the list of available
// sinks is updated whether after 'GetAvailableSinks' call
// or while the implementation is constantly watching the sinks
// (after 'StartWatchingSinks' was called).
// or while the implementation is constantly watching the
// available sinks (after 'StartWatchingAvailableSinks' was called).
// Also this method is called to reflect current connection updates.
virtual void OnSinksUpdated(const DisplaySourceSinkInfoList& sinks) = 0;
protected:
......@@ -61,7 +63,7 @@ class DisplaySourceConnectionDelegate : public KeyedService {
virtual DisplaySourceSinkInfoList last_found_sinks() const = 0;
// Returns the Connection object representing the current
// connection to the sink or NULL if there is no curent connection.
// connection to the sink or NULL if there is no current connection.
virtual const Connection* connection() const = 0;
// Queries the list of currently available sinks.
......@@ -80,19 +82,18 @@ class DisplaySourceConnectionDelegate : public KeyedService {
// Connects to a sink by given id and auth info.
virtual void Connect(int sink_id,
const DisplaySourceAuthInfo& auth_info,
const base::Closure& connected_callback,
const FailureCallback& failure_callback) = 0;
// Disconnects the current connection to sink, the 'failure_callback'
// is called if there is no current connection.
virtual void Disconnect(const base::Closure& disconnected_callback,
const FailureCallback& failure_callback) = 0;
// is called if an error has occurred or if there is no established
// connection.
virtual void Disconnect(const FailureCallback& failure_callback) = 0;
// Implementation should start watching the sinks updates.
virtual void StartWatchingSinks() = 0;
// Implementation should start watching the available sinks updates.
virtual void StartWatchingAvailableSinks() = 0;
// Implementation should stop watching the sinks updates.
virtual void StopWatchingSinks() = 0;
// Implementation should stop watching the available sinks updates.
virtual void StopWatchingAvailableSinks() = 0;
protected:
base::ObserverList<Observer> observers_;
......
......@@ -65,7 +65,7 @@ void DisplaySourceEventRouter::StartOrStopListeningForSinksChanges() {
browser_context_);
if (delegate) {
delegate->AddObserver(this);
delegate->StartWatchingSinks();
delegate->StartWatchingAvailableSinks();
}
}
if (!should_listen && listening_) {
......@@ -74,7 +74,7 @@ void DisplaySourceEventRouter::StartOrStopListeningForSinksChanges() {
browser_context_);
if (delegate) {
delegate->RemoveObserver(this);
delegate->StopWatchingSinks();
delegate->StopWatchingAvailableSinks();
}
}
......
// Copyright 2015 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/browser/api/display_source/wifi_display/wifi_display_session_service_impl.h"
#include "base/bind.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
namespace {
const char kErrorCannotHaveMultipleSessions[] =
"Multiple Wi-Fi Display sessions are not supported";
const char kErrorSinkNotAvailable[] = "The sink is not available";
} // namespace
namespace extensions {
using namespace api::display_source;
WiFiDisplaySessionServiceImpl::WiFiDisplaySessionServiceImpl(
DisplaySourceConnectionDelegate* delegate,
mojo::InterfaceRequest<WiFiDisplaySessionService> request)
: binding_(this, std::move(request)),
delegate_(delegate),
last_connected_sink_(DisplaySourceConnectionDelegate::kInvalidSinkId),
own_sink_(DisplaySourceConnectionDelegate::kInvalidSinkId),
weak_factory_(this) {
delegate_->AddObserver(this);
auto connection = delegate_->connection();
if (connection)
last_connected_sink_ = connection->connected_sink->id;
}
WiFiDisplaySessionServiceImpl::~WiFiDisplaySessionServiceImpl() {
delegate_->RemoveObserver(this);
if (own_sink_ != DisplaySourceConnectionDelegate::kInvalidSinkId)
Disconnect();
}
// static
void WiFiDisplaySessionServiceImpl::BindToRequest(
content::BrowserContext* browser_context,
mojo::InterfaceRequest<WiFiDisplaySessionService> request) {
DisplaySourceConnectionDelegate* delegate =
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
browser_context);
CHECK(delegate);
new WiFiDisplaySessionServiceImpl(delegate, std::move(request));
}
void WiFiDisplaySessionServiceImpl::SetClient(
WiFiDisplaySessionServiceClientPtr client) {
DCHECK(client);
DCHECK(!client_);
client_ = std::move(client);
client_.set_connection_error_handler(
base::Bind(&WiFiDisplaySessionServiceImpl::OnClientConnectionError,
weak_factory_.GetWeakPtr()));
}
void WiFiDisplaySessionServiceImpl::Connect(int32_t sink_id,
int32_t auth_method,
const mojo::String& auth_data) {
DCHECK(client_);
// We support only one Wi-Fi Display session at a time.
if (delegate_->connection()) {
client_->OnError(sink_id, ERROR_TYPE_EXCEEDED_SESSION_LIMIT_ERROR,
kErrorCannotHaveMultipleSessions);
return;
}
const DisplaySourceSinkInfoList& sinks = delegate_->last_found_sinks();
auto found = std::find_if(
sinks.begin(), sinks.end(),
[sink_id](DisplaySourceSinkInfoPtr ptr) { return ptr->id == sink_id; });
if (found == sinks.end() || (*found)->state != SINK_STATE_DISCONNECTED) {
client_->OnError(sink_id, ERROR_TYPE_ESTABLISH_CONNECTION_ERROR,
kErrorSinkNotAvailable);
return;
}
AuthenticationInfo auth_info;
if (auth_method != AUTHENTICATION_METHOD_NONE) {
DCHECK(auth_method <= AUTHENTICATION_METHOD_LAST);
auth_info.method = static_cast<AuthenticationMethod>(auth_method);
auth_info.data = scoped_ptr<std::string>(new std::string(auth_data));
}
auto on_error = base::Bind(&WiFiDisplaySessionServiceImpl::OnConnectFailed,
weak_factory_.GetWeakPtr(), sink_id);
delegate_->Connect(sink_id, auth_info, on_error);
own_sink_ = sink_id;
}
void WiFiDisplaySessionServiceImpl::Disconnect() {
if (own_sink_ == DisplaySourceConnectionDelegate::kInvalidSinkId) {
// The connection might drop before this call has arrived.
// Renderer should have been notified already.
return;
}
DCHECK(delegate_->connection());
DCHECK_EQ(own_sink_, delegate_->connection()->connected_sink->id);
auto on_error = base::Bind(&WiFiDisplaySessionServiceImpl::OnDisconnectFailed,
weak_factory_.GetWeakPtr(), own_sink_);
delegate_->Disconnect(on_error);
}
void WiFiDisplaySessionServiceImpl::SendMessage(const mojo::String& message) {}
void WiFiDisplaySessionServiceImpl::OnSinksUpdated(
const DisplaySourceSinkInfoList& sinks) {
auto connection = delegate_->connection();
if (!connection &&
last_connected_sink_ != DisplaySourceConnectionDelegate::kInvalidSinkId) {
if (last_connected_sink_ == own_sink_)
own_sink_ = DisplaySourceConnectionDelegate::kInvalidSinkId;
if (client_)
client_->OnDisconnected(last_connected_sink_);
last_connected_sink_ = DisplaySourceConnectionDelegate::kInvalidSinkId;
}
if (connection && last_connected_sink_ != connection->connected_sink->id) {
last_connected_sink_ = connection->connected_sink->id;
if (client_)
client_->OnConnected(last_connected_sink_, connection->local_ip);
}
}
void WiFiDisplaySessionServiceImpl::OnConnectFailed(
int sink_id,
const std::string& message) {
DCHECK(client_);
client_->OnError(sink_id, ERROR_TYPE_ESTABLISH_CONNECTION_ERROR, message);
own_sink_ = DisplaySourceConnectionDelegate::kInvalidSinkId;
}
void WiFiDisplaySessionServiceImpl::OnDisconnectFailed(
int sink_id,
const std::string& message) {
DCHECK(client_);
client_->OnError(sink_id, ERROR_TYPE_CONNECTION_ERROR, message);
}
void WiFiDisplaySessionServiceImpl::OnClientConnectionError() {
DLOG(ERROR) << "IPC connection error";
delete this;
}
} // namespace extensions
// Copyright 2015 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_SESSION_SERVICE_IMPL_H_
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_SERVICE_IMPL_H_
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "extensions/browser/api/display_source/display_source_connection_delegate.h"
#include "extensions/common/mojo/wifi_display_session_service.mojom.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
namespace content {
class BrowserContext;
} // namespace content
namespace extensions {
// This class provides access to the network transport for the Wi-Fi Display
// session (which is itself hosted in the sandboxed renderer process).
class WiFiDisplaySessionServiceImpl
: public WiFiDisplaySessionService,
public DisplaySourceConnectionDelegate::Observer {
public:
~WiFiDisplaySessionServiceImpl() override;
static void BindToRequest(
content::BrowserContext* context,
mojo::InterfaceRequest<WiFiDisplaySessionService> request);
private:
// WiFiDisplaySessionService overrides.
void SetClient(WiFiDisplaySessionServiceClientPtr client) override;
void Connect(int32_t sink_id,
int32_t auth_method,
const mojo::String& auth_data) override;
void Disconnect() override;
void SendMessage(const mojo::String& message) override;
// DisplaySourceConnectionDelegate::Observer overrides.
void OnSinksUpdated(const DisplaySourceSinkInfoList& sinks) override;
explicit WiFiDisplaySessionServiceImpl(
DisplaySourceConnectionDelegate* delegate,
mojo::InterfaceRequest<WiFiDisplaySessionService> request);
void OnConnectFailed(int sink_id, const std::string& message);
void OnDisconnectFailed(int sink_id, const std::string& message);
void OnClientConnectionError();
mojo::StrongBinding<WiFiDisplaySessionService> binding_;
WiFiDisplaySessionServiceClientPtr client_;
DisplaySourceConnectionDelegate* delegate_;
// Id of the currenty connected sink (if any), obtained from connection
// delegate. Keep it so that we know if a session has been ended.
int last_connected_sink_;
// Id of the sink of the session this object is associated with.
int own_sink_;
base::WeakPtrFactory<WiFiDisplaySessionServiceImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WiFiDisplaySessionServiceImpl);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_SERVICE_IMPL_H_
......@@ -21,6 +21,10 @@
#include "extensions/common/extension_api.h"
#include "extensions/common/switches.h"
#if defined(ENABLE_WIFI_DISPLAY)
#include "extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.h"
#endif
namespace extensions {
namespace {
......@@ -54,6 +58,15 @@ void RegisterServicesForFrame(content::RenderFrameHost* render_frame_host,
service_registry->AddService(base::Bind(
KeepAliveImpl::Create,
render_frame_host->GetProcess()->GetBrowserContext(), extension));
#if defined(ENABLE_WIFI_DISPLAY)
if (ExtensionHasPermission(extension, render_frame_host->GetProcess(),
"displaySource")) {
service_registry->AddService(
base::Bind(WiFiDisplaySessionServiceImpl::BindToRequest,
render_frame_host->GetProcess()->GetBrowserContext()));
}
#endif
}
} // namespace extensions
// Copyright 2015 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.
module extensions;
// WiFiDisplaySessionService class provides access to the network for
// the render-hosted Wi-Fi Display session.
interface WiFiDisplaySessionService {
SetClient(WiFiDisplaySessionServiceClient client);
// Requires connection to a sink using the given authentication information.
Connect(int32 sink_id, int32 auth_method, string auth_data);
// Drops the established connection to the connected sink.
Disconnect();
// Sends a controlling mesage to the connected sink.
SendMessage(string message);
};
interface WiFiDisplaySessionServiceClient {
// Notification of a successfull connection to a sink.
OnConnected(int32 sink_id, string ip_address);
// Notification of a connection termination.
OnDisconnected(int32 sink_id);
// Notification of an error occurred during the session.
OnError(int32 sink_id, int32 type, string description);
// Invoked to transmit a controlling message from
// the connected sink.
OnMessage(string data);
};
......@@ -37,6 +37,13 @@
'sources': [
'<@(extensions_common_mojo_sources)',
],
'conditions': [
['enable_wifi_display==1', {
'sources': [
'<@(extensions_common_mojo_sources_wifi_display)',
],
}],
],
},
{
# GN version: //extensions/common
......@@ -177,6 +184,13 @@
'<@(extensions_browser_sources_linux_nonchromeos)',
],
}],
['enable_wifi_display == 1', {
'sources': [
'<@(extensions_browser_sources_wifi_display)',
'<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/wifi_display_session_service.mojom.cc',
'<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/wifi_display_session_service.mojom.h',
],
}],
],
# Disable c4267 warnings until we fix size_t to int truncations.
'msvs_disabled_warnings': [ 4267, ],
......@@ -201,6 +215,13 @@
],
# Disable c4267 warnings until we fix size_t to int truncations.
'msvs_disabled_warnings': [ 4267, ],
'conditions': [
['enable_wifi_display==1', {
'sources': [
'<@(extensions_render_sources_wifi_display)',
],
}],
],
},
{
# GN version: //extensions/utility
......
......@@ -12,6 +12,9 @@
'common/mojo/keep_alive.mojom',
'common/mojo/stash.mojom',
],
'extensions_common_mojo_sources_wifi_display': [
'common/mojo/wifi_display_session_service.mojom',
],
'extensions_common_sources': [
'common/api/bluetooth/bluetooth_manifest_data.cc',
'common/api/bluetooth/bluetooth_manifest_data.h',
......@@ -849,6 +852,10 @@
'browser/api/networking_private/networking_private_linux.cc',
'browser/api/networking_private/networking_private_linux.h',
],
'extensions_browser_sources_wifi_display': [
'browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc',
'browser/api/display_source/wifi_display/wifi_display_session_service_impl.h',
],
'extensions_renderer_sources': [
'renderer/activity_log_converter_strategy.cc',
'renderer/activity_log_converter_strategy.h',
......@@ -1024,6 +1031,10 @@
'renderer/worker_script_context_set.cc',
'renderer/worker_script_context_set.h',
],
'extensions_render_sources_wifi_display': [
'renderer/api/display_source/wifi_display/wifi_display_session.cc',
'renderer/api/display_source/wifi_display/wifi_display_session.h',
],
'extensions_utility_sources': [
'utility/unpacker.cc',
'utility/unpacker.h',
......
......@@ -4,15 +4,24 @@
#include "extensions/renderer/api/display_source/display_source_session.h"
#if defined(ENABLE_WIFI_DISPLAY)
#include "extensions/renderer/api/display_source/wifi_display/wifi_display_session.h"
#endif
namespace extensions {
DisplaySourceSession::DisplaySourceSession()
: state_(Idle) {
DisplaySourceSessionParams::DisplaySourceSessionParams()
: auth_method(api::display_source::AUTHENTICATION_METHOD_NONE) {
}
DisplaySourceSession::~DisplaySourceSession() {
DisplaySourceSessionParams::~DisplaySourceSessionParams() = default;
DisplaySourceSession::DisplaySourceSession()
: state_(Idle) {
}
DisplaySourceSession::~DisplaySourceSession() = default;
void DisplaySourceSession::SetCallbacks(
const SinkIdCallback& started_callback,
const SinkIdCallback& terminated_callback,
......@@ -27,10 +36,10 @@ void DisplaySourceSession::SetCallbacks(
}
scoped_ptr<DisplaySourceSession> DisplaySourceSessionFactory::CreateSession(
int sink_id,
const blink::WebMediaStreamTrack& video_track,
const blink::WebMediaStreamTrack& audio_track,
scoped_ptr<DisplaySourceAuthInfo> auth_info) {
const DisplaySourceSessionParams& params) {
#if defined(ENABLE_WIFI_DISPLAY)
return scoped_ptr<DisplaySourceSession>(new WiFiDisplaySession(params));
#endif
return nullptr;
}
......
......@@ -10,9 +10,14 @@
#include "extensions/common/api/display_source.h"
#include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h"
namespace content {
class RenderFrame;
}
namespace extensions {
using DisplaySourceAuthInfo = api::display_source::AuthenticationInfo;
using DisplaySourceAuthMethod = api::display_source::AuthenticationMethod;
using DisplaySourceErrorType = api::display_source::ErrorType;
// This class represents a generic display source session interface.
......@@ -78,13 +83,22 @@ class DisplaySourceSession {
DISALLOW_COPY_AND_ASSIGN(DisplaySourceSession);
};
struct DisplaySourceSessionParams {
DisplaySourceSessionParams();
~DisplaySourceSessionParams();
int sink_id;
blink::WebMediaStreamTrack video_track;
blink::WebMediaStreamTrack audio_track;
DisplaySourceAuthMethod auth_method;
std::string auth_data;
content::RenderFrame* render_frame;
};
class DisplaySourceSessionFactory {
public:
static scoped_ptr<DisplaySourceSession> CreateSession(
int sink_id,
const blink::WebMediaStreamTrack& video_track,
const blink::WebMediaStreamTrack& audio_track,
scoped_ptr<DisplaySourceAuthInfo> auth_info);
const DisplaySourceSessionParams& params);
private:
DISALLOW_COPY_AND_ASSIGN(DisplaySourceSessionFactory);
};
......
// Copyright 2015 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_session.h"
#include "base/logging.h"
#include "base/timer/timer.h"
#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_frame.h"
namespace {
const char kErrorInternal[] = "An internal error has occurred";
} // namespace
namespace extensions {
using api::display_source::ErrorType;
WiFiDisplaySession::WiFiDisplaySession(
const DisplaySourceSessionParams& params)
: binding_(this),
params_(params),
weak_factory_(this) {
DCHECK(params_.render_frame);
params.render_frame->GetServiceRegistry()->ConnectToRemoteService(
mojo::GetProxy(&service_));
service_.set_connection_error_handler(base::Bind(
&WiFiDisplaySession::OnConnectionError,
weak_factory_.GetWeakPtr()));
WiFiDisplaySessionServiceClientPtr client_ptr;
binding_.Bind(GetProxy(&client_ptr));
binding_.set_connection_error_handler(base::Bind(
&WiFiDisplaySession::OnConnectionError,
weak_factory_.GetWeakPtr()));
DCHECK(client_ptr);
service_->SetClient(std::move(client_ptr));
}
WiFiDisplaySession::~WiFiDisplaySession() {
}
void WiFiDisplaySession::Start() {
DCHECK(state_ == DisplaySourceSession::Idle);
service_->Connect(params_.sink_id, params_.auth_method, params_.auth_data);
state_ = DisplaySourceSession::Establishing;
}
void WiFiDisplaySession::Terminate() {
DCHECK(state_ != DisplaySourceSession::Idle);
switch (state_) {
case DisplaySourceSession::Idle:
case DisplaySourceSession::Terminating:
// Nothing to do.
return;
case DisplaySourceSession::Establishing:
case DisplaySourceSession::Established:
service_->Disconnect();
state_ = DisplaySourceSession::Terminating;
break;
default:
NOTREACHED();
}
}
void WiFiDisplaySession::OnConnected(
int32_t sink_id, const mojo::String& ip_address) {
if (sink_id == params_.sink_id) {
DCHECK(state_ != DisplaySourceSession::Established);
ip_address_ = ip_address;
state_ = DisplaySourceSession::Established;
}
if (!started_callback_.is_null())
started_callback_.Run(sink_id);
}
void WiFiDisplaySession::OnDisconnected(int32_t sink_id) {
if (sink_id == params_.sink_id) {
DCHECK(state_ == DisplaySourceSession::Established ||
state_ == DisplaySourceSession::Terminating);
state_ = DisplaySourceSession::Idle;
}
if (!terminated_callback_.is_null())
terminated_callback_.Run(sink_id);
}
void WiFiDisplaySession::OnError(
int32_t sink_id, int32_t type, const mojo::String& description) {
DCHECK(type > api::display_source::ERROR_TYPE_NONE
&& type <= api::display_source::ERROR_TYPE_LAST);
if (!error_callback_.is_null())
error_callback_.Run(sink_id, static_cast<ErrorType>(type), description);
}
void WiFiDisplaySession::OnMessage(const mojo::String& data) {
DCHECK(state_ == DisplaySourceSession::Established);
}
void WiFiDisplaySession::OnConnectionError() {
if (!error_callback_.is_null()) {
error_callback_.Run(params_.sink_id,
api::display_source::ERROR_TYPE_UNKNOWN_ERROR,
kErrorInternal);
}
if (state_ == DisplaySourceSession::Established ||
state_ == DisplaySourceSession::Terminating) {
// We must explicitly notify the session termination as it will never
// arrive from browser process (IPC is broken).
if (!terminated_callback_.is_null())
terminated_callback_.Run(params_.sink_id);
}
}
} // namespace extensions
// Copyright 2015 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_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_H_
#define EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_H_
#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"
namespace extensions {
class WiFiDisplaySession: public DisplaySourceSession,
public WiFiDisplaySessionServiceClient {
public:
explicit WiFiDisplaySession(
const DisplaySourceSessionParams& params);
~WiFiDisplaySession() override;
private:
// DisplaySourceSession overrides.
void Start() override;
void Terminate() override;
// WiFiDisplaySessionServiceClient overrides.
void OnConnected(int32_t sink_id,
const mojo::String& ip_address) override;
void OnDisconnected(int32_t sink_id) override;
void OnError(int32_t sink_id,
int32_t type,
const mojo::String& description) override;
void OnMessage(const mojo::String& data) override;
// A connection error handler for the mojo objects used in this class.
void OnConnectionError();
private:
WiFiDisplaySessionServicePtr service_;
mojo::Binding<WiFiDisplaySessionServiceClient> binding_;
std::string ip_address_;
DisplaySourceSessionParams params_;
base::WeakPtrFactory<WiFiDisplaySession> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WiFiDisplaySession);
};
} // namespace extensions
#endif // EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_SESSION_H_
......@@ -135,9 +135,17 @@ void DisplaySourceCustomBindings::StartSession(
auth_info = DisplaySourceAuthInfo::FromValue(*auth_info_val);
}
DisplaySourceSessionParams session_params;
session_params.sink_id = sink_id;
session_params.video_track = video_track;
session_params.audio_track = audio_track;
session_params.render_frame = context()->GetRenderFrame();
if (auth_info) {
session_params.auth_method = auth_info->method;
session_params.auth_data = auth_info->data ? *auth_info->data : "";
}
scoped_ptr<DisplaySourceSession> session =
DisplaySourceSessionFactory::CreateSession(
sink_id, video_track, audio_track, std::move(auth_info));
DisplaySourceSessionFactory::CreateSession(session_params);
if (!session) {
isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
isolate, kErrorNotSupported)));
......@@ -156,8 +164,8 @@ void DisplaySourceCustomBindings::StartSession(
session->SetCallbacks(on_started_callback,
on_terminated_callback,
on_error_callback);
session_map_.insert(std::make_pair(sink_id, std::move(session)));
session->Start();
session_map_.insert(std::make_pair(sink_id, std::move(session)));
}
void DisplaySourceCustomBindings::TerminateSession(
......@@ -249,8 +257,10 @@ void DisplaySourceCustomBindings::OnSessionError(int sink_id,
const std::string& message) {
DisplaySourceSession* session = GetDisplaySession(sink_id);
CHECK(session);
if (session->state() == DisplaySourceSession::Establishing) {
// Error has occured before the session has actually started.
if (session->state() != DisplaySourceSession::Established &&
session->state() != DisplaySourceSession::Terminating) {
// Error has occured before the session has actually started,
// no need to wait for session termination notification.
session_map_.erase(sink_id);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment