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 |