mirror of
https://github.com/electron/electron.git
synced 2026-10-29 12:14:50 +08:00
* fix: clear vibrancy view before destruction Keep the removed NativeViewHost alive until vibrant_native_view_host_ has been cleared. Memory was freed at: 0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x000000012b8ea86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764 3 Electron Framework 0x000000012b996bcc void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)8>(void*) + 5392 4 Electron Framework 0x00000001335fe8f4 views::NativeViewHost::~NativeViewHost() + 16 5 Electron Framework 0x0000000124916004 ___ZN8electron15NativeWindowMac11SetVibrancyERKNSt4__Cr12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi_block_invoke + 140 6 Electron Framework 0x0000000124915a74 electron::NativeWindowMac::SetVibrancy(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, int) + 1048 The dangling raw_ptr was released at: 0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x000000012b8eb158 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)1, (base::features::DanglingPtrType)0>(unsigned long) + 92 3 Electron Framework 0x000000012b93c3b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480 4 Electron Framework 0x0000000124916058 ___ZN8electron15NativeWindowMac11SetVibrancyERKNSt4__Cr12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi_block_invoke + 224 5 Electron Framework 0x0000000124915a74 electron::NativeWindowMac::SetVibrancy(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, int) + 1048 * fix: clear notification delegate before callback Release delegate_ before NotificationDestroyed() can synchronously delete the delegate. Memory was freed at: 0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x000000012b8ea86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764 3 Electron Framework 0x000000012b9aa080 void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 5928 4 Electron Framework 0x000000012b99f940 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 1324 5 Electron Framework 0x000000012b9c3a50 allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)6>::FreeWithSize(void*, unsigned long, void*) + 200 6 Electron Framework 0x00000001247f797c electron::Notification::~Notification() + 72 7 Electron Framework 0x0000000124919fbc electron::CocoaNotification::~CocoaNotification() + 220 8 Electron Framework 0x000000012491a014 electron::CocoaNotification::~CocoaNotification() + 12 9 Electron Framework 0x00000001247f81cc electron::NotificationPresenter::RemoveNotification(electron::Notification*) + 200 The dangling raw_ptr was released at: 0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x000000012b8eb158 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)1, (base::features::DanglingPtrType)0>(unsigned long) + 92 3 Electron Framework 0x000000012b93c3b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480 4 Electron Framework 0x00000001247f7a50 electron::Notification::~Notification() + 284 5 Electron Framework 0x0000000124919fbc electron::CocoaNotification::~CocoaNotification() + 220 6 Electron Framework 0x000000012491a014 electron::CocoaNotification::~CocoaNotification() + 12 7 Electron Framework 0x00000001247f81cc electron::NotificationPresenter::RemoveNotification(electron::Notification*) + 200 * fix: erase notifications before destruction Remove each raw_ptr from notifications_ before deleting the Notification it references. Memory was freed at: 0 Electron Framework 0x000000012cacd6e0 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012cab6968 base::debug::StackTrace::StackTrace(unsigned long) + 168 2 Electron Framework 0x000000012cad3a24 base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764 3 Electron Framework 0x000000012cbbb9ac void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 5868 4 Electron Framework 0x000000012cbb1264 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 1324 5 Electron Framework 0x000000012cbd522c allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)6>::FreeWithSize(void*, unsigned long, void*) + 200 6 Electron Framework 0x00000001258ed394 electron::NotificationPresenter::~NotificationPresenter() + 72 7 Electron Framework 0x0000000125a0ee60 electron::NotificationPresenterMac::~NotificationPresenterMac() + 356 8 Electron Framework 0x0000000125a0ef00 electron::NotificationPresenterMac::~NotificationPresenterMac() + 12 9 Electron Framework 0x0000000125868dfc electron::ElectronBrowserClient::~ElectronBrowserClient() + 500 The dangling raw_ptr was released at: 0 Electron Framework 0x000000012cacd6e0 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x000000012cab6968 base::debug::StackTrace::StackTrace(unsigned long) + 168 2 Electron Framework 0x000000012cad3aec void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)0, (base::features::DanglingPtrType)0>(unsigned long) + 84 3 Electron Framework 0x000000012cb27fc8 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480 4 Electron Framework 0x00000001258b87c8 void std::__Cr::__destroy_at[abi:sqn240000]<base::raw_ptr<DraggableRegionProvider, (partition_alloc::internal::RawPtrTraits)0>>(base::raw_ptr<DraggableRegionProvider, (partition_alloc::internal::RawPtrTraits)0>*) + 136 5 Electron Framework 0x00000001258eda14 std::__Cr::__tree<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>, std::__Cr::less<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>>, std::__Cr::allocator<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>>>::__tree_deleter::operator()[abi:sqn240000](std::__Cr::__tree_node<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>, void*>*) + 52 6 Electron Framework 0x00000001258ed3d4 electron::NotificationPresenter::~NotificationPresenter() + 136 7 Electron Framework 0x0000000125a0ee60 electron::NotificationPresenterMac::~NotificationPresenterMac() + 356 8 Electron Framework 0x0000000125a0ef00 electron::NotificationPresenterMac::~NotificationPresenterMac() + 12 9 Electron Framework 0x0000000125868dfc electron::ElectronBrowserClient::~ElectronBrowserClient() + 500 * fix: clear Node environment before teardown Clear NodeBindings::uv_env_ before NodeService releases the node::Environment. Memory was freed at: 0 Electron Framework 0x0000000129b78940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x0000000129b63a00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x0000000129b7e86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764 3 Electron Framework 0x0000000129c3c93c void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)18>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)18)>::Type) + 8480 4 Electron Framework 0x0000000129c33390 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)18>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)18)>::Type) + 1324 5 Electron Framework 0x0000000129c56ce8 allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)2>::FreeWithSize(void*, unsigned long, void*) + 200 6 Electron Framework 0x0000000122c4bd24 node::FreeEnvironment(node::Environment*) + 248 7 Electron Framework 0x0000000122b3a74c _ZNSt4__Cr20__shared_ptr_pointerB9sqn240000IPN4node11EnvironmentEZN8electron12NodeBindings17CreateEnvironmentEPN2v87IsolateENS6_5LocalINS6_7ContextEEEPNS1_20MultiIsolatePlatformEmNS_6vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENSI_ISK_EEEESM_NS_8optionalIN4base17RepeatingCallbackIFvvEEEEEE3$_0NSI_IS2_EEE16__on_zero_sharedEv + 188 8 Electron Framework 0x0000000122b7ee40 electron::NodeService::~NodeService() + 416 9 Electron Framework 0x0000000122b7ef2c electron::NodeService::~NodeService() + 12 The dangling raw_ptr was released at: 0 Electron Framework 0x0000000129b78940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24 1 Electron Framework 0x0000000129b63a00 base::debug::StackTrace::StackTrace(unsigned long) + 128 2 Electron Framework 0x0000000129b7e934 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)0, (base::features::DanglingPtrType)0>(unsigned long) + 84 3 Electron Framework 0x0000000129bd03b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480 4 Electron Framework 0x0000000122b34b94 electron::NodeBindings::~NodeBindings() + 372 5 Electron Framework 0x0000000122bde08c electron::NodeBindingsMac::~NodeBindingsMac() + 12 6 Electron Framework 0x0000000122b7edf8 electron::NodeService::~NodeService() + 344 7 Electron Framework 0x0000000122b7ef2c electron::NodeService::~NodeService() + 12 * fix: enable dangling raw_ptr checks * fix: avoid retaining isolate in PromiseBase Resolve PromiseHandle traced references with the currently entered isolate instead of retaining a raw pointer that can outlive IsolateHolder. Promise operations already require execution on their creation thread with the isolate entered. ``` gin::IsolateHolder::~IsolateHolder -> JavascriptEnvironment::~JavascriptEnvironment -> isolate free static Promise<void> destruction -> PromiseBase::~PromiseBase -> isolate_ raw_ptr release ``` * fix: annotate additional dangling raw pointers * fix(win): annotate additional dangling raw_ptr
314 lines
12 KiB
C++
314 lines
12 KiB
C++
// Copyright (c) 2022 Microsoft, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "shell/services/node/node_service.h"
|
|
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <utility>
|
|
|
|
#include "base/command_line.h"
|
|
#include "base/no_destructor.h"
|
|
#include "base/strings/utf_string_conversions.h"
|
|
#include "electron/buildflags/buildflags.h"
|
|
#include "electron/fuses.h"
|
|
#include "electron/mas.h"
|
|
#include "net/base/network_change_notifier.h"
|
|
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
|
|
#include "services/network/public/mojom/host_resolver.mojom.h"
|
|
#include "services/network/public/mojom/network_context.mojom.h"
|
|
#include "shell/browser/javascript_environment.h"
|
|
#include "shell/common/api/electron_bindings.h"
|
|
#include "shell/common/gin_converters/file_path_converter.h"
|
|
#include "shell/common/gin_helper/dictionary.h"
|
|
#include "shell/common/node_bindings.h"
|
|
#include "shell/common/node_includes.h"
|
|
#include "shell/common/v8_util.h"
|
|
#include "shell/services/node/parent_port.h"
|
|
|
|
#if !IS_MAS_BUILD()
|
|
#include "shell/common/crash_keys.h"
|
|
#endif
|
|
|
|
#if BUILDFLAG(ENABLE_PROMPT_API)
|
|
#include "shell/common/gin_helper/event_emitter_caller.h"
|
|
#include "shell/utility/ai/utility_ai_manager.h"
|
|
#include "shell/utility/api/electron_api_local_ai_handler.h"
|
|
#include "url/gurl.h"
|
|
#include "url/origin.h"
|
|
#endif // BUILDFLAG(ENABLE_PROMPT_API)
|
|
|
|
namespace electron {
|
|
|
|
mojo::Remote<node::mojom::NodeServiceClient>& GetRemote() {
|
|
static base::NoDestructor<mojo::Remote<node::mojom::NodeServiceClient>>
|
|
instance;
|
|
return *instance;
|
|
}
|
|
|
|
void V8FatalErrorCallback(const char* location, const char* message) {
|
|
if (GetRemote().is_bound() && GetRemote().is_connected()) {
|
|
auto* isolate = v8::Isolate::TryGetCurrent();
|
|
std::ostringstream outstream;
|
|
node::GetNodeReport(isolate, message, location,
|
|
v8::Local<v8::Object>() /* error */, outstream);
|
|
GetRemote()->OnV8FatalError(location, outstream.str());
|
|
}
|
|
|
|
#if !IS_MAS_BUILD()
|
|
electron::crash_keys::SetCrashKey("electron.v8-fatal.message", message);
|
|
electron::crash_keys::SetCrashKey("electron.v8-fatal.location", location);
|
|
#endif
|
|
|
|
volatile int* zero = nullptr;
|
|
*zero = 0; // NOLINT(clang-analyzer-core.NullDereference)
|
|
}
|
|
|
|
URLLoaderBundle::URLLoaderBundle() = default;
|
|
|
|
URLLoaderBundle::~URLLoaderBundle() = default;
|
|
|
|
URLLoaderBundle* URLLoaderBundle::GetInstance() {
|
|
static base::NoDestructor<URLLoaderBundle> instance;
|
|
return instance.get();
|
|
}
|
|
|
|
void URLLoaderBundle::SetURLLoaderFactory(
|
|
mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_factory,
|
|
mojo::Remote<network::mojom::HostResolver> host_resolver,
|
|
bool use_network_observer_from_url_loader_factory) {
|
|
factory_ = network::SharedURLLoaderFactory::Create(
|
|
std::make_unique<network::WrapperPendingSharedURLLoaderFactory>(
|
|
std::move(pending_factory)));
|
|
host_resolver_ = std::move(host_resolver);
|
|
should_use_network_observer_from_url_loader_factory_ =
|
|
use_network_observer_from_url_loader_factory;
|
|
}
|
|
|
|
scoped_refptr<network::SharedURLLoaderFactory>
|
|
URLLoaderBundle::GetSharedURLLoaderFactory() {
|
|
return factory_;
|
|
}
|
|
|
|
network::mojom::HostResolver* URLLoaderBundle::GetHostResolver() {
|
|
DCHECK(host_resolver_);
|
|
return host_resolver_.get();
|
|
}
|
|
|
|
bool URLLoaderBundle::ShouldUseNetworkObserverfromURLLoaderFactory() const {
|
|
return should_use_network_observer_from_url_loader_factory_;
|
|
}
|
|
|
|
NodeService::NodeService(
|
|
mojo::PendingReceiver<node::mojom::NodeService> receiver)
|
|
: node_bindings_{
|
|
NodeBindings::Create(NodeBindings::BrowserEnvironment::kUtility,
|
|
uv_default_loop())},
|
|
electron_bindings_{
|
|
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())} {
|
|
if (receiver.is_valid())
|
|
receiver_.Bind(std::move(receiver));
|
|
}
|
|
|
|
NodeService::~NodeService() {
|
|
#if BUILDFLAG(ENABLE_PROMPT_API)
|
|
electron::api::local_ai_handler::SetHandlerChangedCallback({});
|
|
// Tear down the AI receivers while the isolate is still alive; their
|
|
// destructors call into V8.
|
|
ai_managers_.Clear();
|
|
#endif
|
|
if (!node_env_stopped_) {
|
|
node_env_->set_trace_sync_io(false);
|
|
ParentPort::GetInstance()->Close();
|
|
js_env_->DestroyMicrotasksRunner();
|
|
node::Stop(node_env_.get(), node::StopFlags::kDoNotTerminateIsolate);
|
|
GetRemote().reset();
|
|
}
|
|
node_bindings_->set_uv_env(nullptr);
|
|
}
|
|
|
|
void NodeService::Initialize(
|
|
node::mojom::NodeServiceParamsPtr params,
|
|
mojo::PendingRemote<node::mojom::NodeServiceClient> client_pending_remote) {
|
|
if (NodeBindings::IsInitialized())
|
|
return;
|
|
|
|
GetRemote().Bind(std::move(client_pending_remote));
|
|
GetRemote().reset_on_disconnect();
|
|
|
|
if (params->url_loader_factory_params) {
|
|
UpdateURLLoaderFactory(std::move(params->url_loader_factory_params));
|
|
}
|
|
|
|
// Enable trap handlers before creating the V8 isolate. V8 initialization
|
|
// calls IsTrapHandlerEnabled() which prevents later EnableTrapHandler calls.
|
|
#if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)) && \
|
|
defined(ARCH_CPU_X86_64)) || \
|
|
((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)) && defined(ARCH_CPU_ARM64))
|
|
if (electron::fuses::IsWasmTrapHandlersEnabled()) {
|
|
electron::SetUpWebAssemblyTrapHandler();
|
|
}
|
|
#endif
|
|
|
|
js_env_.emplace(node_bindings_->uv_loop());
|
|
|
|
v8::Isolate* const isolate = js_env_->isolate();
|
|
v8::HandleScope scope{isolate};
|
|
|
|
// Empty when the isolate was created from the embedded Node startup
|
|
// snapshot: the main context is then materialized (with the whole
|
|
// bootstrapped environment) inside CreateEnvironment and entered below --
|
|
// the same path the browser process takes.
|
|
const v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
|
|
|
node_bindings_->Initialize(isolate, context);
|
|
|
|
// ParentPort is a cppgc-managed wrappable, so it must be created after the
|
|
// V8 isolate (and its cppgc heap) exists. The connector is created paused and
|
|
// is not resumed until the entry script calls parentPort.start() during
|
|
// LoadEnvironment below, so binding the port here changes no observable
|
|
// behavior.
|
|
ParentPort::GetInstance()->Initialize(std::move(params->port));
|
|
|
|
network_change_notifier_ = net::NetworkChangeNotifier::CreateIfNeeded(
|
|
net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
|
|
net::NetworkChangeNotifier::ConnectionSubtype::SUBTYPE_UNKNOWN);
|
|
|
|
// Append program path for process.argv0
|
|
auto program = base::CommandLine::ForCurrentProcess()->GetProgram();
|
|
#if defined(OS_WIN)
|
|
params->args.insert(params->args.begin(), base::WideToUTF8(program.value()));
|
|
#else
|
|
params->args.insert(params->args.begin(), program.value());
|
|
#endif
|
|
|
|
// Create the global environment.
|
|
node_env_ = node_bindings_->CreateEnvironment(
|
|
isolate, context, js_env_->platform(),
|
|
js_env_->max_young_generation_size_in_bytes(), params->args,
|
|
params->exec_args);
|
|
if (context.IsEmpty())
|
|
node_env_->context()->Enter();
|
|
node_bindings_->SetUpIsolate(isolate);
|
|
|
|
// Override the default handler set by NodeBindings.
|
|
node_env_->isolate()->SetFatalErrorHandler(V8FatalErrorCallback);
|
|
|
|
node::SetProcessExitHandler(
|
|
node_env_.get(), [this](node::Environment* env, int exit_code) {
|
|
// Destroy node platform.
|
|
node_env_stopped_ = true;
|
|
ParentPort::GetInstance()->Close();
|
|
js_env_->DestroyMicrotasksRunner();
|
|
GetRemote().reset();
|
|
receiver_.ResetWithReason(exit_code, "process_exit_termination");
|
|
node::DefaultProcessExitHandler(env, exit_code);
|
|
});
|
|
|
|
node_env_->set_trace_sync_io(node_env_->options()->trace_sync_io);
|
|
|
|
// We do not want to crash the utility process on unhandled rejections.
|
|
node_env_->options()->unhandled_rejections = "warn-with-error-code";
|
|
|
|
// Add Electron extended APIs.
|
|
electron_bindings_->BindTo(node_env_->isolate(), node_env_->process_object());
|
|
|
|
// Add entry script to process object.
|
|
gin_helper::Dictionary process(node_env_->isolate(),
|
|
node_env_->process_object());
|
|
process.SetHidden("_serviceStartupScript", params->script);
|
|
|
|
// Setup microtask runner.
|
|
js_env_->CreateMicrotasksRunner();
|
|
|
|
// Wrap the uv loop with global env.
|
|
node_bindings_->set_uv_env(node_env_.get());
|
|
|
|
// LoadEnvironment should be called after setting up
|
|
// JavaScriptEnvironment including the microtask runner
|
|
// since this call will start compilation and execution
|
|
// of the entry script. If there is an uncaught exception
|
|
// the exit handler set above will be triggered and it expects
|
|
// both Node Env and JavaScriptEnvironment are setup to perform
|
|
// a clean shutdown of this process.
|
|
node_bindings_->LoadEnvironment(node_env_.get());
|
|
|
|
// Run entry script.
|
|
node_bindings_->PrepareEmbedThread();
|
|
node_bindings_->StartPolling();
|
|
}
|
|
|
|
void NodeService::UpdateURLLoaderFactory(
|
|
node::mojom::URLLoaderFactoryParamsPtr params) {
|
|
URLLoaderBundle::GetInstance()->SetURLLoaderFactory(
|
|
std::move(params->url_loader_factory),
|
|
mojo::Remote(std::move(params->host_resolver)),
|
|
params->use_network_observer_from_url_loader_factory);
|
|
}
|
|
|
|
#if BUILDFLAG(ENABLE_PROMPT_API)
|
|
NodeService::PendingAIManagerBinding::PendingAIManagerBinding(
|
|
node::mojom::BindAIManagerParamsPtr params,
|
|
mojo::PendingReceiver<blink::mojom::AIManager> receiver)
|
|
: params(std::move(params)), receiver(std::move(receiver)) {}
|
|
|
|
NodeService::PendingAIManagerBinding::~PendingAIManagerBinding() = default;
|
|
|
|
NodeService::PendingAIManagerBinding::PendingAIManagerBinding(
|
|
PendingAIManagerBinding&&) = default;
|
|
|
|
NodeService::PendingAIManagerBinding&
|
|
NodeService::PendingAIManagerBinding::operator=(PendingAIManagerBinding&&) =
|
|
default;
|
|
|
|
void NodeService::BindAIManager(
|
|
node::mojom::BindAIManagerParamsPtr params,
|
|
mojo::PendingReceiver<blink::mojom::AIManager> ai_manager) {
|
|
auto& handler = electron::api::local_ai_handler::GetPromptAPIHandler();
|
|
if (!handler.has_value()) {
|
|
// No handler set yet — register for notification on first pending binding.
|
|
if (pending_ai_manager_bindings_.empty()) {
|
|
electron::api::local_ai_handler::SetHandlerChangedCallback(
|
|
base::BindRepeating(&NodeService::FlushPendingAIManagerBindings,
|
|
base::Unretained(this)));
|
|
}
|
|
if (pending_ai_manager_bindings_.size() >= kMaxPendingAIManagerBindings) {
|
|
pending_ai_manager_bindings_.front().receiver.reset();
|
|
pending_ai_manager_bindings_.pop_front();
|
|
}
|
|
pending_ai_manager_bindings_.emplace_back(std::move(params),
|
|
std::move(ai_manager));
|
|
{
|
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
|
v8::HandleScope scope{isolate};
|
|
v8::Global<v8::Object>& module_object =
|
|
electron::api::local_ai_handler::GetModuleObject();
|
|
if (!module_object.IsEmpty()) {
|
|
gin_helper::EmitEvent(isolate, module_object.Get(isolate),
|
|
"-pending-bind-ai-manager");
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
ai_managers_.Add(std::make_unique<UtilityAIManager>(
|
|
params->web_contents_id, params->security_origin,
|
|
params->frame_token, params->render_process_id),
|
|
std::move(ai_manager));
|
|
}
|
|
|
|
void NodeService::FlushPendingAIManagerBindings() {
|
|
auto pending = std::move(pending_ai_manager_bindings_);
|
|
for (auto& binding : pending) {
|
|
ai_managers_.Add(
|
|
std::make_unique<UtilityAIManager>(
|
|
binding.params->web_contents_id, binding.params->security_origin,
|
|
binding.params->frame_token, binding.params->render_process_id),
|
|
std::move(binding.receiver));
|
|
}
|
|
}
|
|
#endif // BUILDFLAG(ENABLE_PROMPT_API)
|
|
|
|
} // namespace electron
|