| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <cstdint> |
| |
| #include "base/check.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/task/single_thread_task_executor.h" |
| #include "base/threading/simple_thread.h" |
| #include "chromeos/ash/services/orca/public/cpp/orca_entry.h" |
| #include "chromeos/ash/services/orca/public/mojom/orca_service.mojom.h" |
| #include "mojo/public/c/system/thunks.h" |
| #include "mojo/public/cpp/bindings/pending_associated_receiver.h" |
| #include "mojo/public/cpp/bindings/pending_associated_remote.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| |
| namespace { |
| |
| class FakeOrcaService : public ash::orca::mojom::OrcaService { |
| public: |
| explicit FakeOrcaService(OrcaLogger* logger) : logger_(logger) {} |
| |
| void BindEditor( |
| mojo::PendingAssociatedRemote<ash::orca::mojom::SystemActuator> |
| text_actuator, |
| mojo::PendingAssociatedRemote<ash::orca::mojom::TextQueryProvider> |
| text_query_provider, |
| mojo::PendingAssociatedReceiver<ash::orca::mojom::EditorClientConnector> |
| client_connector, |
| mojo::PendingAssociatedReceiver<ash::orca::mojom::EditorEventSink> |
| event_sink, |
| ash::orca::mojom::EditorConfigPtr editor_config) override { |
| logger_->log(logger_, OrcaLogSeverity::ORCA_LOG_SEVERITY_WARNING, |
| "Success"); |
| } |
| |
| private: |
| raw_ptr<OrcaLogger> logger_; |
| }; |
| |
| class OrcaServiceThread : public base::SimpleThread { |
| public: |
| OrcaServiceThread(uintptr_t receiver_handle, OrcaLogger* logger) |
| : base::SimpleThread("OrcaServiceThread"), |
| receiver_handle_(receiver_handle), |
| logger_(logger) {} |
| |
| private: |
| // SimpleThread: |
| void Run() override { |
| base::SingleThreadTaskExecutor executor; |
| |
| FakeOrcaService fake_orca_service(logger_); |
| mojo::Receiver<ash::orca::mojom::OrcaService> receiver( |
| &fake_orca_service, |
| mojo::PendingReceiver<ash::orca::mojom::OrcaService>( |
| mojo::ScopedMessagePipeHandle( |
| mojo::MessagePipeHandle(receiver_handle_)))); |
| |
| base::RunLoop run_loop; |
| receiver.set_disconnect_handler(base::BindOnce( |
| [](base::RepeatingClosure quit_closure) { quit_closure.Run(); }, |
| run_loop.QuitClosure())); |
| |
| // Blocks this thread until `run_loop.Quit()` is called |
| // upon `receiver` disconnecting. |
| run_loop.Run(); |
| } |
| |
| uintptr_t receiver_handle_; |
| raw_ptr<OrcaLogger> logger_; |
| }; |
| |
| OrcaServiceThread* g_orca_service_thread = nullptr; |
| |
| } // namespace |
| |
| extern "C" { |
| |
| OrcaBindServiceStatus __attribute__((visibility("default"))) |
| OrcaBindServiceV2(const MojoSystemThunks2* mojo_thunks, |
| uintptr_t receiver_handle, |
| OrcaLogger* logger) { |
| CHECK(mojo_thunks); |
| MojoEmbedderSetSystemThunks(mojo_thunks); |
| |
| // Run the OrcaService in a separate thread so that it can have its own |
| // RunLoop to listen for Mojo messages. |
| g_orca_service_thread = new OrcaServiceThread(receiver_handle, logger); |
| g_orca_service_thread->Start(); |
| |
| return OrcaBindServiceStatus::ORCA_BIND_SERVICE_STATUS_OK; |
| } |
| |
| void OrcaResetService() { |
| if (!g_orca_service_thread) { |
| return; |
| } |
| |
| g_orca_service_thread->Join(); |
| delete g_orca_service_thread; |
| } |
| } |