[remoting host] Implement a mojo interface broker and use it for WebAuthnProxy
This is a different take from crrev.com/c/3236834 on resolving the
issue of only one isolated connection being allowed per server-client
pair.
This CL:
1. introduces a new PendingRemote/PendingReceiver broker interface and
implements it on ChromotingHost
2. Introduces a ChromotingHostServicesClient class to allow the client
to easily connect to the server
3. Makes WebAuthnProxy use the new interface for binding, instead of
maintaining its own isolated connection.
Bug: 1225870
Change-Id: I4a85666b70439f10008c0bc879429e5435b710ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3246467
Commit-Queue: Yuwei Huang <[email protected]>
Reviewed-by: Alex Gough <[email protected]>
Reviewed-by: Joe Downing <[email protected]>
Cr-Commit-Position: refs/heads/main@{#937618}
diff --git a/remoting/host/chromoting_host_services_client.cc b/remoting/host/chromoting_host_services_client.cc
new file mode 100644
index 0000000..6f6e687
--- /dev/null
+++ b/remoting/host/chromoting_host_services_client.cc
@@ -0,0 +1,67 @@
+// Copyright 2021 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 "remoting/host/chromoting_host_services_client.h"
+
+#include "base/bind.h"
+#include "base/sequence_checker.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/system/isolated_connection.h"
+#include "remoting/host/ipc_constants.h"
+#include "remoting/host/mojom/chromoting_host_services.mojom.h"
+
+namespace remoting {
+
+ChromotingHostServicesClient::ChromotingHostServicesClient()
+ : server_name_(GetChromotingHostServicesServerName()) {}
+
+ChromotingHostServicesClient::~ChromotingHostServicesClient() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+mojom::ChromotingHostServices* ChromotingHostServicesClient::Get() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!const_cast<ChromotingHostServicesClient*>(this)->EnsureConnection()) {
+ return nullptr;
+ }
+
+ return remote_.get();
+}
+
+bool ChromotingHostServicesClient::EnsureConnection() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (remote_.is_bound()) {
+ return true;
+ }
+
+ auto endpoint = mojo::NamedPlatformChannel::ConnectToServer(server_name_);
+ if (!endpoint.is_valid()) {
+ LOG(WARNING) << "Cannot connect to IPC through server name " << server_name_
+ << ". Endpoint is invalid.";
+ return false;
+ }
+ connection_ = std::make_unique<mojo::IsolatedConnection>();
+ mojo::PendingRemote<mojom::ChromotingHostServices> pending_remote(
+ connection_->Connect(std::move(endpoint)), /* version= */ 0);
+ if (!pending_remote.is_valid()) {
+ LOG(WARNING) << "Invalid message pipe.";
+ connection_.reset();
+ return false;
+ }
+ remote_.Bind(std::move(pending_remote));
+ remote_.set_disconnect_handler(base::BindOnce(
+ &ChromotingHostServicesClient::OnDisconnected, base::Unretained(this)));
+ return true;
+}
+
+void ChromotingHostServicesClient::OnDisconnected() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ remote_.reset();
+ connection_.reset();
+}
+
+} // namespace remoting