| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include <base/check_op.h> |
| #include <base/functional/bind.h> |
| #include <base/logging.h> |
| #include <base/task/single_thread_task_runner.h> |
| #include <brillo/daemons/daemon.h> |
| #include <brillo/flag_helper.h> |
| #include <brillo/syslog_logging.h> |
| #include <mojo/core/embedder/embedder.h> |
| #include <mojo/core/embedder/scoped_ipc_support.h> |
| #include <mojo/public/c/system/buffer.h> |
| #include <mojo/public/cpp/bindings/receiver.h> |
| #include <mojo/public/cpp/bindings/receiver_set.h> |
| #include <mojo/public/cpp/bindings/remote.h> |
| #include <mojo/public/cpp/system/handle.h> |
| |
| #include "mojo_service_manager/lib/connect.h" |
| #include "mojo_service_manager/lib/mojom/service_manager.mojom.h" |
| #include "mojo_service_manager/lib/simple_mojo_service_provider.h" |
| #include "mojo_service_manager/testing/test.mojom.h" |
| |
| namespace chromeos::mojo_service_manager { |
| namespace { |
| |
| // The actions supported by test tool. |
| constexpr char kActionCreateTestService[] = "create-test-service"; |
| constexpr char kActionPingTestService[] = "ping-test-service"; |
| constexpr char kActionTestSharedBuffer[] = "test-shared-buffer"; |
| |
| // The service name to register and request test service from service manager. |
| constexpr char kTestServiceName[] = "MojoServiceManagerTest"; |
| |
| // The buffer size to test the shared buffer creation. |
| constexpr uint64_t kTestSharedBufferSize = 1024; |
| |
| class FooImpl : public mojom::Foo { |
| public: |
| explicit FooImpl(mojom::ServiceManager* service_manager) { |
| provider_.Register(service_manager, kTestServiceName); |
| } |
| ~FooImpl() override = default; |
| |
| // mojom::Foo overrides. |
| void Ping(PingCallback callback) override { |
| LOG(INFO) << "Foo::Ping() is called"; |
| std::move(callback).Run(); |
| } |
| |
| private: |
| SimpleMojoServiceProvider<mojom::Foo> provider_{this}; |
| }; |
| |
| int CreateTestService(brillo::Daemon& daemon, |
| mojom::ServiceManager* service_manager) { |
| FooImpl foo{service_manager}; |
| LOG(INFO) << "Registered test service."; |
| |
| return daemon.Run(); |
| } |
| |
| int PingTestService(brillo::Daemon& daemon, |
| mojom::ServiceManager* service_manager) { |
| mojo::Remote<mojom::Foo> foo; |
| service_manager->Request(kTestServiceName, std::nullopt, |
| foo.BindNewPipeAndPassReceiver().PassPipe()); |
| foo.set_disconnect_with_reason_handler( |
| base::BindOnce([](uint32_t error, const std::string& message) { |
| LOG(FATAL) << "Foo service disconnected: " << error << ", " << message; |
| })); |
| foo->Ping(base::BindOnce(&brillo::Daemon::Quit, base::Unretained(&daemon))); |
| daemon.Run(); |
| LOG(INFO) << "Ping test service successfully."; |
| return 0; |
| } |
| |
| int TestSharedBuffer() { |
| MojoCreateSharedBufferOptions options = {sizeof(options), |
| MOJO_CREATE_SHARED_BUFFER_FLAG_NONE}; |
| mojo::Handle handle; |
| CHECK_EQ(MojoCreateSharedBuffer(kTestSharedBufferSize, &options, |
| handle.mutable_value()), |
| MOJO_RESULT_OK) |
| << "Failed to allocate shared buffer."; |
| CHECK(handle.is_valid()) << "Invalid shared buffer handle."; |
| |
| LOG(INFO) << "Create shared buffer successfully."; |
| return 0; |
| } |
| |
| } // namespace |
| |
| int TestToolMain(int argc, char* argv[]) { |
| DEFINE_int32(log_level, 0, |
| "Logging level - 0: LOG(INFO), 1: LOG(WARNING), 2: LOG(ERROR), " |
| "-1: VLOG(1), -2: VLOG(2), ..."); |
| DEFINE_string(action, "", |
| "Indicates whether the service manager daemon is in the " |
| "permissive mode. In permissive mode, the requests with wrong " |
| "identity won't be rejected."); |
| |
| brillo::InitLog(brillo::kLogToStderr); |
| brillo::FlagHelper::Init(argc, argv, "Mojo service manager test tool"); |
| logging::SetMinLogLevel(FLAGS_log_level); |
| |
| mojo::core::Init(); |
| brillo::Daemon daemon; |
| mojo::core::ScopedIPCSupport ipc_support( |
| base::SingleThreadTaskRunner::GetCurrentDefault(), |
| mojo::core::ScopedIPCSupport::ShutdownPolicy:: |
| CLEAN /* blocking shutdown */); |
| mojo::Remote<mojom::ServiceManager> service_manager{ |
| ConnectToMojoServiceManager()}; |
| service_manager.set_disconnect_with_reason_handler( |
| base::BindOnce([](uint32_t error, const std::string& message) { |
| LOG(FATAL) << "Service manager disconnected: " << error << ", " |
| << message; |
| })); |
| |
| if (FLAGS_action == kActionCreateTestService) |
| return CreateTestService(daemon, service_manager.get()); |
| if (FLAGS_action == kActionPingTestService) |
| return PingTestService(daemon, service_manager.get()); |
| if (FLAGS_action == kActionTestSharedBuffer) |
| return TestSharedBuffer(); |
| |
| LOG(ERROR) << "Unknown action " << FLAGS_action << ", could be " |
| << kActionCreateTestService << ", " << kActionPingTestService |
| << ", " << kActionTestSharedBuffer; |
| return 1; |
| } |
| |
| } // namespace chromeos::mojo_service_manager |
| |
| int main(int argc, char* argv[]) { |
| return chromeos::mojo_service_manager::TestToolMain(argc, argv); |
| } |