| Index: extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc
|
| diff --git a/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc b/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ae3713d0707dbfdb42c085810342729af026b56f
|
| --- /dev/null
|
| +++ b/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc
|
| @@ -0,0 +1,149 @@
|
| +// 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
|
|
|