1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/passage_embeddings/chrome_passage_embeddings_service_controller.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/notreached.h"
#include "base/process/process.h"
#include "chrome/browser/passage_embeddings/cpu_histogram_logger.h"
#include "components/passage_embeddings/passage_embeddings_features.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/service_process_host.h"
#include "content/public/common/process_type.h"
namespace passage_embeddings {
// static
ChromePassageEmbeddingsServiceController*
ChromePassageEmbeddingsServiceController::Get() {
static base::NoDestructor<ChromePassageEmbeddingsServiceController> instance;
return instance.get();
}
ChromePassageEmbeddingsServiceController::
ChromePassageEmbeddingsServiceController() = default;
ChromePassageEmbeddingsServiceController::
~ChromePassageEmbeddingsServiceController() = default;
void ChromePassageEmbeddingsServiceController::MaybeLaunchService() {
// No-op if already launched.
if (service_remote_) {
return;
}
auto receiver = service_remote_.BindNewPipeAndPassReceiver();
// Unretained is safe because `this` owns `service_remote_`, which
// synchronously calls the disconnect and idle handlers.
service_remote_.set_disconnect_handler(base::BindOnce(
&ChromePassageEmbeddingsServiceController::ResetServiceRemote,
base::Unretained(this)));
service_remote_.set_idle_handler(
kEmbeddingsServiceTimeout.Get(),
base::BindRepeating(
&ChromePassageEmbeddingsServiceController::ResetServiceRemote,
base::Unretained(this)));
content::ServiceProcessHost::Launch<mojom::PassageEmbeddingsService>(
std::move(receiver),
content::ServiceProcessHost::Options()
.WithDisplayName("Passage Embeddings Service")
.WithProcessCallback(base::BindOnce(
&ChromePassageEmbeddingsServiceController::OnServiceLaunched,
weak_ptr_factory_.GetWeakPtr()))
.Pass());
}
void ChromePassageEmbeddingsServiceController::ResetServiceRemote() {
ResetEmbedderRemote();
service_remote_.reset();
cpu_logger_.StopLoggingAfterNextUpdate();
}
void ChromePassageEmbeddingsServiceController::OnServiceLaunched(
const base::Process& process) {
// `OnServiceLaunched` is triggered by the same observable that
// `PerformanceManager` uses to register new process hosts, which is necessary
// before we can start the CPU histogram logger. As such, this has to be a
// `PostTask` to ensure that `InitializeCpuLogger` is invoked after the
// service process host is registered.
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
&ChromePassageEmbeddingsServiceController::InitializeCpuLogger,
weak_ptr_factory_.GetWeakPtr()));
}
void ChromePassageEmbeddingsServiceController::InitializeCpuLogger() {
content::BrowserChildProcessHostIterator iter(content::PROCESS_TYPE_UTILITY);
while (!iter.Done()) {
const content::ChildProcessData& data = iter.GetData();
if (data.name == u"Passage Embeddings Service") {
cpu_logger_.StartLogging(
content::BrowserChildProcessHost::FromID(data.id),
base::BindRepeating(
&PassageEmbeddingsServiceController::EmbedderRunning,
base::Unretained(this)));
return;
}
++iter;
}
}
} // namespace passage_embeddings
|