Commit e00bfd52 authored by Anand K. Mistry's avatar Anand K. Mistry Committed by Commit Bot

Move PendingConnectionManager to a separate component.

This class will be used by smbfs to establish a Mojo channel to Chrome.

BUG=939235

Change-Id: Idc0bc822e4839325ba32f204a06cd5fe4a92e012
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1833017
Commit-Queue: Anand Mistry <amistry@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarSergei Datsenko <dats@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710220}
parent a6a2f4ce
...@@ -90,6 +90,7 @@ source_set("chromeos") { ...@@ -90,6 +90,7 @@ source_set("chromeos") {
"//chromeos/components/account_manager", "//chromeos/components/account_manager",
"//chromeos/components/drivefs", "//chromeos/components/drivefs",
"//chromeos/components/drivefs/mojom", "//chromeos/components/drivefs/mojom",
"//chromeos/components/mojo_bootstrap",
"//chromeos/components/multidevice", "//chromeos/components/multidevice",
"//chromeos/components/multidevice/logging", "//chromeos/components/multidevice/logging",
"//chromeos/components/power", "//chromeos/components/power",
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "dbus/message.h" #include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
...@@ -47,8 +47,8 @@ void DriveFileStreamServiceProvider::HandleOpenIpcChannel( ...@@ -47,8 +47,8 @@ void DriveFileStreamServiceProvider::HandleOpenIpcChannel(
method_call, DBUS_ERROR_INVALID_ARGS, "Second argument is not FD.")); method_call, DBUS_ERROR_INVALID_ARGS, "Second argument is not FD."));
return; return;
} }
if (!drivefs::PendingConnectionManager::Get().OpenIpcChannel(id, if (!mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
std::move(fd))) { id, std::move(fd))) {
response_sender.Run(dbus::ErrorResponse::FromMethodCall( response_sender.Run(dbus::ErrorResponse::FromMethodCall(
method_call, DBUS_ERROR_FAILED, "Failed to open IPC")); method_call, DBUS_ERROR_FAILED, "Failed to open IPC"));
return; return;
......
...@@ -19,6 +19,7 @@ test("chromeos_components_unittests") { ...@@ -19,6 +19,7 @@ test("chromeos_components_unittests") {
"//chromeos:chromeos_buildflags", "//chromeos:chromeos_buildflags",
"//chromeos/components/account_manager:unit_tests", "//chromeos/components/account_manager:unit_tests",
"//chromeos/components/drivefs:unit_tests", "//chromeos/components/drivefs:unit_tests",
"//chromeos/components/mojo_bootstrap:unit_tests",
"//chromeos/components/multidevice:unit_tests", "//chromeos/components/multidevice:unit_tests",
"//chromeos/components/nearby:unit_tests", "//chromeos/components/nearby:unit_tests",
"//chromeos/components/power:unit_tests", "//chromeos/components/power:unit_tests",
......
...@@ -20,12 +20,11 @@ component("drivefs") { ...@@ -20,12 +20,11 @@ component("drivefs") {
"drivefs_util.h", "drivefs_util.h",
"fake_drivefs_launcher_client.cc", "fake_drivefs_launcher_client.cc",
"fake_drivefs_launcher_client.h", "fake_drivefs_launcher_client.h",
"pending_connection_manager.cc",
"pending_connection_manager.h",
] ]
deps = [ deps = [
"//base", "//base",
"//chromeos/components/drivefs/mojom", "//chromeos/components/drivefs/mojom",
"//chromeos/components/mojo_bootstrap",
"//chromeos/constants", "//chromeos/constants",
"//chromeos/dbus", "//chromeos/dbus",
"//chromeos/disks", "//chromeos/disks",
...@@ -66,7 +65,6 @@ source_set("unit_tests") { ...@@ -66,7 +65,6 @@ source_set("unit_tests") {
"drivefs_host_unittest.cc", "drivefs_host_unittest.cc",
"drivefs_search_unittest.cc", "drivefs_search_unittest.cc",
"drivefs_session_unittest.cc", "drivefs_session_unittest.cc",
"pending_connection_manager_unittest.cc",
] ]
deps = [ deps = [
...@@ -75,6 +73,7 @@ source_set("unit_tests") { ...@@ -75,6 +73,7 @@ source_set("unit_tests") {
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//chromeos/components/drivefs/mojom", "//chromeos/components/drivefs/mojom",
"//chromeos/components/mojo_bootstrap",
"//chromeos/disks:test_support", "//chromeos/disks:test_support",
"//components/account_id", "//components/account_id",
"//components/drive", "//components/drive",
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h" #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
...@@ -20,7 +20,7 @@ DriveFsBootstrapListener::DriveFsBootstrapListener() ...@@ -20,7 +20,7 @@ DriveFsBootstrapListener::DriveFsBootstrapListener()
: bootstrap_(invitation_.AttachMessagePipe("drivefs-bootstrap"), : bootstrap_(invitation_.AttachMessagePipe("drivefs-bootstrap"),
mojom::DriveFsBootstrap::Version_), mojom::DriveFsBootstrap::Version_),
pending_token_(base::UnguessableToken::Create()) { pending_token_(base::UnguessableToken::Create()) {
PendingConnectionManager::Get().ExpectOpenIpcChannel( mojo_bootstrap::PendingConnectionManager::Get().ExpectOpenIpcChannel(
pending_token_, pending_token_,
base::BindOnce(&DriveFsBootstrapListener::AcceptMojoConnection, base::BindOnce(&DriveFsBootstrapListener::AcceptMojoConnection,
base::Unretained(this))); base::Unretained(this)));
...@@ -28,8 +28,8 @@ DriveFsBootstrapListener::DriveFsBootstrapListener() ...@@ -28,8 +28,8 @@ DriveFsBootstrapListener::DriveFsBootstrapListener()
DriveFsBootstrapListener::~DriveFsBootstrapListener() { DriveFsBootstrapListener::~DriveFsBootstrapListener() {
if (pending_token_) { if (pending_token_) {
PendingConnectionManager::Get().CancelExpectedOpenIpcChannel( mojo_bootstrap::PendingConnectionManager::Get()
pending_token_); .CancelExpectedOpenIpcChannel(pending_token_);
pending_token_ = {}; pending_token_ = {};
} }
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom-test-utils.h" #include "chromeos/components/drivefs/mojom/drivefs.mojom-test-utils.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
...@@ -91,8 +91,8 @@ class DriveFsBootstrapTest : public testing::Test, ...@@ -91,8 +91,8 @@ class DriveFsBootstrapTest : public testing::Test,
} }
void WaitForConnection(const base::UnguessableToken& token) { void WaitForConnection(const base::UnguessableToken& token) {
ASSERT_TRUE( ASSERT_TRUE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
PendingConnectionManager::Get().OpenIpcChannel(token.ToString(), {})); token.ToString(), {}));
base::RunLoop run_loop; base::RunLoop run_loop;
bootstrap_receiver_.set_disconnect_handler(run_loop.QuitClosure()); bootstrap_receiver_.set_disconnect_handler(run_loop.QuitClosure());
run_loop.Run(); run_loop.Run();
...@@ -121,8 +121,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_Disconnect) { ...@@ -121,8 +121,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_Disconnect) {
EXPECT_CALL(*this, OnDisconnect()); EXPECT_CALL(*this, OnDisconnect());
receiver_.reset(); receiver_.reset();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_FALSE( ASSERT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
PendingConnectionManager::Get().OpenIpcChannel(token.ToString(), {})); token.ToString(), {}));
} }
TEST_F(DriveFsBootstrapTest, Listen_Connect_DisconnectDelegate) { TEST_F(DriveFsBootstrapTest, Listen_Connect_DisconnectDelegate) {
...@@ -132,8 +132,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_DisconnectDelegate) { ...@@ -132,8 +132,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_DisconnectDelegate) {
EXPECT_CALL(*this, OnDisconnect()); EXPECT_CALL(*this, OnDisconnect());
delegate_.reset(); delegate_.reset();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_FALSE( ASSERT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
PendingConnectionManager::Get().OpenIpcChannel(token.ToString(), {})); token.ToString(), {}));
} }
TEST_F(DriveFsBootstrapTest, Listen_Connect_Destroy) { TEST_F(DriveFsBootstrapTest, Listen_Connect_Destroy) {
...@@ -143,8 +143,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_Destroy) { ...@@ -143,8 +143,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Connect_Destroy) {
EXPECT_CALL(*this, OnDisconnect()).Times(0); EXPECT_CALL(*this, OnDisconnect()).Times(0);
connection_.reset(); connection_.reset();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_FALSE( ASSERT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
PendingConnectionManager::Get().OpenIpcChannel(token.ToString(), {})); token.ToString(), {}));
} }
TEST_F(DriveFsBootstrapTest, Listen_Destroy) { TEST_F(DriveFsBootstrapTest, Listen_Destroy) {
...@@ -152,8 +152,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Destroy) { ...@@ -152,8 +152,8 @@ TEST_F(DriveFsBootstrapTest, Listen_Destroy) {
auto token = ListenForConnection(); auto token = ListenForConnection();
connection_.reset(); connection_.reset();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_FALSE( ASSERT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
PendingConnectionManager::Get().OpenIpcChannel(token.ToString(), {})); token.ToString(), {}));
} }
TEST_F(DriveFsBootstrapTest, Listen_DisconnectDelegate) { TEST_F(DriveFsBootstrapTest, Listen_DisconnectDelegate) {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "chromeos/components/drivefs/fake_drivefs.h" #include "chromeos/components/drivefs/fake_drivefs.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom-test-utils.h" #include "chromeos/components/drivefs/mojom/drivefs.mojom-test-utils.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "chromeos/disks/mock_disk_mount_manager.h" #include "chromeos/disks/mock_disk_mount_manager.h"
#include "components/drive/drive_notification_manager.h" #include "components/drive/drive_notification_manager.h"
#include "components/drive/drive_notification_observer.h" #include "components/drive/drive_notification_observer.h"
...@@ -342,7 +342,8 @@ class DriveFsHostTest : public ::testing::Test, public mojom::DriveFsBootstrap { ...@@ -342,7 +342,8 @@ class DriveFsHostTest : public ::testing::Test, public mojom::DriveFsBootstrap {
token_ = StartMount(); token_ = StartMount();
DispatchMountSuccessEvent(token_); DispatchMountSuccessEvent(token_);
ASSERT_TRUE(PendingConnectionManager::Get().OpenIpcChannel(token_, {})); ASSERT_TRUE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
token_, {}));
{ {
base::RunLoop run_loop; base::RunLoop run_loop;
bootstrap_receiver_.set_disconnect_handler(run_loop.QuitClosure()); bootstrap_receiver_.set_disconnect_handler(run_loop.QuitClosure());
...@@ -488,7 +489,8 @@ TEST_F(DriveFsHostTest, OnMountFailedFromDbus) { ...@@ -488,7 +489,8 @@ TEST_F(DriveFsHostTest, OnMountFailedFromDbus) {
run_loop.Run(); run_loop.Run();
ASSERT_FALSE(host_->IsMounted()); ASSERT_FALSE(host_->IsMounted());
EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); EXPECT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
token, {}));
} }
TEST_F(DriveFsHostTest, DestroyBeforeMojoConnection) { TEST_F(DriveFsHostTest, DestroyBeforeMojoConnection) {
...@@ -498,7 +500,8 @@ TEST_F(DriveFsHostTest, DestroyBeforeMojoConnection) { ...@@ -498,7 +500,8 @@ TEST_F(DriveFsHostTest, DestroyBeforeMojoConnection) {
chromeos::UNMOUNT_OPTIONS_LAZY, _)); chromeos::UNMOUNT_OPTIONS_LAZY, _));
host_.reset(); host_.reset();
EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); EXPECT_FALSE(mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
token, {}));
} }
TEST_F(DriveFsHostTest, MountWhileAlreadyMounted) { TEST_F(DriveFsHostTest, MountWhileAlreadyMounted) {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/system/sys_info.h" #include "base/system/sys_info.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_cros_disks_client.h" #include "chromeos/dbus/fake_cros_disks_client.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
...@@ -96,7 +96,7 @@ base::FilePath FakeDriveFsLauncherClient::MaybeMountDriveFs( ...@@ -96,7 +96,7 @@ base::FilePath FakeDriveFsLauncherClient::MaybeMountDriveFs(
} }
const std::string datadir = base::StrCat({"drivefs-", datadir_suffix}); const std::string datadir = base::StrCat({"drivefs-", datadir_suffix});
mojo::PlatformChannel channel; mojo::PlatformChannel channel;
PendingConnectionManager::Get().OpenIpcChannel( mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
identity, channel.TakeLocalEndpoint().TakePlatformHandle().TakeFD()); identity, channel.TakeLocalEndpoint().TakePlatformHandle().TakeFD());
launcher_->LaunchDriveFs( launcher_->LaunchDriveFs(
base::FilePath("/tmp").Append(datadir), base::FilePath("/tmp").Append(datadir),
......
// Copyright 2018 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 CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_
#define CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_
#include <string>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/unguessable_token.h"
namespace drivefs {
class PendingConnectionManagerTest;
class COMPONENT_EXPORT(DRIVEFS) PendingConnectionManager {
public:
using OpenIpcChannelCallback = base::OnceCallback<void(base::ScopedFD)>;
static PendingConnectionManager& Get();
bool OpenIpcChannel(const std::string& identity, base::ScopedFD ipc_channel);
void ExpectOpenIpcChannel(base::UnguessableToken token,
OpenIpcChannelCallback handler);
void CancelExpectedOpenIpcChannel(base::UnguessableToken token);
private:
friend class base::NoDestructor<PendingConnectionManager>;
friend class PendingConnectionManagerTest;
PendingConnectionManager();
~PendingConnectionManager();
base::flat_map<std::string, OpenIpcChannelCallback>
open_ipc_channel_callbacks_;
DISALLOW_COPY_AND_ASSIGN(PendingConnectionManager);
};
} // namespace drivefs
#endif // CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_
# Copyright 2019 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.
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
component("mojo_bootstrap") {
sources = [
"pending_connection_manager.cc",
"pending_connection_manager.h",
]
deps = [
"//base",
]
defines = [ "IS_MOJO_BOOTSTRAP_IMPL" ]
}
source_set("unit_tests") {
testonly = true
sources = [
"pending_connection_manager_unittest.cc",
]
deps = [
":mojo_bootstrap",
"//base/test:test_support",
"//testing/gtest",
]
}
amistry@chromium.org
dats@chromium.org
slangley@chromium.org
# COMPONENT: OS>Systems
chromeos/components/mojo_bootstrap
==================================
This directory contains classes that are useful to establish a Mojo
connection with a Chrome OS service.
In general, any class that is used by more than one Chrome OS service to
establish a Mojo connection should be moved here.
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
namespace drivefs { namespace mojo_bootstrap {
// static // static
PendingConnectionManager& PendingConnectionManager::Get() { PendingConnectionManager& PendingConnectionManager::Get() {
...@@ -16,15 +16,15 @@ PendingConnectionManager& PendingConnectionManager::Get() { ...@@ -16,15 +16,15 @@ PendingConnectionManager& PendingConnectionManager::Get() {
return *connection_manager; return *connection_manager;
} }
bool PendingConnectionManager::OpenIpcChannel(const std::string& identity, bool PendingConnectionManager::OpenIpcChannel(const std::string& token,
base::ScopedFD ipc_channel) { base::ScopedFD fd) {
auto it = open_ipc_channel_callbacks_.find(identity); auto it = open_ipc_channel_callbacks_.find(token);
if (it == open_ipc_channel_callbacks_.end()) { if (it == open_ipc_channel_callbacks_.end()) {
return false; return false;
} }
OpenIpcChannelCallback callback = std::move(it->second); OpenIpcChannelCallback callback = std::move(it->second);
open_ipc_channel_callbacks_.erase(it); open_ipc_channel_callbacks_.erase(it);
std::move(callback).Run(std::move(ipc_channel)); std::move(callback).Run(std::move(fd));
return true; return true;
} }
...@@ -44,4 +44,4 @@ void PendingConnectionManager::CancelExpectedOpenIpcChannel( ...@@ -44,4 +44,4 @@ void PendingConnectionManager::CancelExpectedOpenIpcChannel(
PendingConnectionManager::PendingConnectionManager() = default; PendingConnectionManager::PendingConnectionManager() = default;
PendingConnectionManager::~PendingConnectionManager() = default; PendingConnectionManager::~PendingConnectionManager() = default;
} // namespace drivefs } // namespace mojo_bootstrap
// Copyright 2019 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 CHROMEOS_COMPONENTS_MOJO_BOOTSTRAP_PENDING_CONNECTION_MANAGER_H_
#define CHROMEOS_COMPONENTS_MOJO_BOOTSTRAP_PENDING_CONNECTION_MANAGER_H_
#include <string>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/unguessable_token.h"
namespace mojo_bootstrap {
class PendingConnectionManagerTest;
// PendingConnectionManager is used to wait for a unix domain socket to be used
// for bootstrapping a Mojo connection. The typical use case is where a system
// service is started by Chrome, but only text arguments can be passed to the
// service startup. An example of this are filesystems mounted by cros-disks,
// where only an array of strings can be passed as options to the Mount() D-Bus
// method. This class is NOT needed if a socket end can be passed to the system
// service directly.
//
// To use this class:
// 1. Create and export a D-Bus service in Chrome containing a single method
// which is passed a string and FD. (eg. org.chromium.DriveFileStream).
// This method simply calls PendingConnectionManager::OpenIpcChannel().
// 2. Create an UnguessableToken and pass the string serialisation to the system
// service. Use PendingConnectionManager::ExpectOpenIpcChannel() to wait for
// an FD.
// 3. In the system service, create a socketpair() and pass one end over the
// D-Bus method created in step 1, along with the token.
//
// Sample usage:
// --- Chrome ---
// class MyClass {
// private:
// const base::UnguessableToken token_;
// mojo::OutgoingInvitation invitation_;
// };
//
// MyClass::MyClass() : token_(base::UnguessableToken::Create()) {}
//
// void MyClass::StartService() {
// // Use this message pipe to bind an InterfacePtr<> to the Mojo service.
// mojo::ScopedMessagePipeHandle bootstrap_handle =
// invitation_.AttachMessagePipe("myservice-bootstrap");
//
// base::UnguessableToken token = base::UnguessableToken::Create();
// PendingConnectionManager::Get().ExpectOpenIpcChannel(
// token_, base::BindOnce(&MyClass::AcceptConnection,
// base::Unretained(this)));
// StartMySystemService(token_.ToString());
// }
//
// void MyClass::AcceptConnection(base::ScopedFD handle) {
// mojo::OutgoingInvitation::Send(
// std::move(invitation_), base::kNullProcessHandle,
// mojo::PlatformChannelEndpoint(
// mojo::PlatformHandle(std::move(handle))));
// }
//
// void MyClass::MyExportedDbusConnectMethod(
// dbus::MethodCall* method_call,
// dbus::ExportedObject::ResponseSender response_sender) {
// std::string token = // Pop token passed to StartMySystemService()
// base::ScopedFD fd = // Pop FD
// CHECK(PendingConnectionManager::Get().OpenIpcChannel(
// token, std::move(fd)));
// }
//
// --- System Service ---
// // Returns an InterfaceRequest<> that can be used to bind the Mojo service
// // implementation.
// mojom::MyServiceRequest MyService::BootstrapMojo() {
// mojo::edk::PlatformChannelPair channel;
// org::chromium::MyChromeServiceProxy dbus_proxy(bus_, kServiceName);
// brillo::ErrorPtr error;
// CHECK(dbus_proxy.MyExportedDbusConnectMethod(
// token_, channel.PassClientHandle().get().handle, &error));
// mojo::edk::SetParentPipeHandle(channel.PassServerHandle());
//
// mojom::MyServiceRequest request;
// request.Bind(mojo::edk::CreateChildMessagePipe("myservice-bootstrap"));
// return request;
// }
class COMPONENT_EXPORT(MOJO_BOOTSTRAP) PendingConnectionManager {
public:
using OpenIpcChannelCallback = base::OnceCallback<void(base::ScopedFD)>;
static PendingConnectionManager& Get();
// Responds to a file descriptor request for |token| with |fd|. |token| is the
// UnguessableToken::ToString() representation of the |token| parameter to
// ExpectOpenIpcChannel().
bool OpenIpcChannel(const std::string& token, base::ScopedFD ipc_channel);
// Registers a callback that is run when a file descriptor is received for
// |token|.
void ExpectOpenIpcChannel(base::UnguessableToken token,
OpenIpcChannelCallback handler);
// Cancels the pending callback for |token|.
void CancelExpectedOpenIpcChannel(base::UnguessableToken token);
private:
friend class base::NoDestructor<PendingConnectionManager>;
friend class PendingConnectionManagerTest;
PendingConnectionManager();
~PendingConnectionManager();
base::flat_map<std::string, OpenIpcChannelCallback>
open_ipc_channel_callbacks_;
DISALLOW_COPY_AND_ASSIGN(PendingConnectionManager);
};
} // namespace mojo_bootstrap
#endif // CHROMEOS_COMPONENTS_MOJO_BOOTSTRAP_PENDING_CONNECTION_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromeos/components/drivefs/pending_connection_manager.h" #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace drivefs { namespace mojo_bootstrap {
class PendingConnectionManagerTest : public testing::Test { class PendingConnectionManagerTest : public testing::Test {
protected: protected:
...@@ -41,4 +41,4 @@ TEST_F(PendingConnectionManagerTest, UnexpectedConnection) { ...@@ -41,4 +41,4 @@ TEST_F(PendingConnectionManagerTest, UnexpectedConnection) {
} }
} // namespace } // namespace
} // namespace drivefs } // namespace mojo_bootstrap
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