diff --git a/lib/sandboxed_renderer/init.ts b/lib/sandboxed_renderer/init.ts index a99567591727..079dd38b069e 100644 --- a/lib/sandboxed_renderer/init.ts +++ b/lib/sandboxed_renderer/init.ts @@ -41,25 +41,15 @@ const loadableModules = new Map([ ['url', () => require('url')] ]); -// ElectronSandboxedRendererClient will look for the "lifecycle" hidden object when -v8Util.setHiddenValue(global, 'lifecycle', { - onLoaded () { - (process as events.EventEmitter).emit('loaded'); - }, - onExit () { - (process as events.EventEmitter).emit('exit'); - }, - onDocumentStart () { - (process as events.EventEmitter).emit('document-start'); - }, - onDocumentEnd () { - (process as events.EventEmitter).emit('document-end'); - } -}); - // Pass different process object to the preload script. const preloadProcess: NodeJS.Process = new EventEmitter() as any; +// InvokeEmitProcessEvent in ElectronSandboxedRendererClient will look for this +v8Util.setHiddenValue(global, 'emit-process-event', (event: string) => { + (process as events.EventEmitter).emit(event); + (preloadProcess as events.EventEmitter).emit(event); +}); + Object.assign(preloadProcess, binding.process); Object.assign(preloadProcess, processProps); @@ -79,11 +69,6 @@ Object.defineProperty(preloadProcess, 'noDeprecation', { } }); -process.on('loaded', () => (preloadProcess as events.EventEmitter).emit('loaded')); -process.on('exit', () => (preloadProcess as events.EventEmitter).emit('exit')); -(process as events.EventEmitter).on('document-start', () => (preloadProcess as events.EventEmitter).emit('document-start')); -(process as events.EventEmitter).on('document-end', () => (preloadProcess as events.EventEmitter).emit('document-end')); - // This is the `require` function that will be visible to the preload script function preloadRequire (module: string) { if (loadedModules.has(module)) { diff --git a/shell/renderer/electron_sandboxed_renderer_client.cc b/shell/renderer/electron_sandboxed_renderer_client.cc index a0e36ff3dc4e..ca619b1fc7ec 100644 --- a/shell/renderer/electron_sandboxed_renderer_client.cc +++ b/shell/renderer/electron_sandboxed_renderer_client.cc @@ -4,11 +4,13 @@ #include "shell/renderer/electron_sandboxed_renderer_client.h" +#include #include #include #include "base/base_paths.h" #include "base/command_line.h" +#include "base/containers/contains.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/process/process_handle.h" @@ -33,7 +35,7 @@ namespace electron { namespace { -const char kLifecycleKey[] = "lifecycle"; +const char kEmitProcessEventKey[] = "emit-process-event"; const char kModuleCacheKey[] = "native-module-cache"; v8::Local GetModuleCache(v8::Isolate* isolate) { @@ -94,27 +96,25 @@ double Uptime() { .InSecondsF(); } -void InvokeHiddenCallback(v8::Handle context, - const std::string& hidden_key, - const std::string& callback_name) { +void InvokeEmitProcessEvent(v8::Handle context, + const std::string& event_name) { auto* isolate = context->GetIsolate(); - auto binding_key = - gin::ConvertToV8(isolate, hidden_key)->ToString(context).ToLocalChecked(); + // set by sandboxed_renderer/init.js + auto binding_key = gin::ConvertToV8(isolate, kEmitProcessEventKey) + ->ToString(context) + .ToLocalChecked(); auto private_binding_key = v8::Private::ForApi(isolate, binding_key); auto global_object = context->Global(); - v8::Local value; - if (!global_object->GetPrivate(context, private_binding_key).ToLocal(&value)) + v8::Local callback_value; + if (!global_object->GetPrivate(context, private_binding_key) + .ToLocal(&callback_value)) return; - if (value.IsEmpty() || !value->IsObject()) + if (callback_value.IsEmpty() || !callback_value->IsFunction()) return; - auto binding = value->ToObject(context).ToLocalChecked(); - auto callback_key = gin::ConvertToV8(isolate, callback_name) - ->ToString(context) - .ToLocalChecked(); - auto callback_value = binding->Get(context, callback_key).ToLocalChecked(); - DCHECK(callback_value->IsFunction()); // set by sandboxed_renderer/init.js auto callback = callback_value.As(); - std::ignore = callback->Call(context, binding, 0, nullptr); + v8::Local args[] = {gin::ConvertToV8(isolate, event_name)}; + std::ignore = + callback->Call(context, callback, std::size(args), std::data(args)); } } // namespace @@ -158,37 +158,13 @@ void ElectronSandboxedRendererClient::RenderFrameCreated( void ElectronSandboxedRendererClient::RunScriptsAtDocumentStart( content::RenderFrame* render_frame) { RendererClientBase::RunScriptsAtDocumentStart(render_frame); - if (injected_frames_.find(render_frame) == injected_frames_.end()) - return; - - auto* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local context = - GetContext(render_frame->GetWebFrame(), isolate); - gin_helper::MicrotasksScope microtasks_scope( - isolate, context->GetMicrotaskQueue(), - v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::Context::Scope context_scope(context); - - InvokeHiddenCallback(context, kLifecycleKey, "onDocumentStart"); + EmitProcessEvent(render_frame, "document-start"); } void ElectronSandboxedRendererClient::RunScriptsAtDocumentEnd( content::RenderFrame* render_frame) { RendererClientBase::RunScriptsAtDocumentEnd(render_frame); - if (injected_frames_.find(render_frame) == injected_frames_.end()) - return; - - auto* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local context = - GetContext(render_frame->GetWebFrame(), isolate); - gin_helper::MicrotasksScope microtasks_scope( - isolate, context->GetMicrotaskQueue(), - v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::Context::Scope context_scope(context); - - InvokeHiddenCallback(context, kLifecycleKey, "onDocumentEnd"); + EmitProcessEvent(render_frame, "document-end"); } void ElectronSandboxedRendererClient::DidCreateScriptContext( @@ -219,7 +195,7 @@ void ElectronSandboxedRendererClient::DidCreateScriptContext( v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(context); - InvokeHiddenCallback(context, kLifecycleKey, "onLoaded"); + InvokeEmitProcessEvent(context, "loaded"); } void ElectronSandboxedRendererClient::WillReleaseScriptContext( @@ -234,7 +210,25 @@ void ElectronSandboxedRendererClient::WillReleaseScriptContext( v8::MicrotasksScope::kDoNotRunMicrotasks); v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(context); - InvokeHiddenCallback(context, kLifecycleKey, "onExit"); + InvokeEmitProcessEvent(context, "exit"); +} + +void ElectronSandboxedRendererClient::EmitProcessEvent( + content::RenderFrame* render_frame, + const char* event_name) { + if (injected_frames_.find(render_frame) == injected_frames_.end()) + return; + + auto* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + v8::Local context = + GetContext(render_frame->GetWebFrame(), isolate); + gin_helper::MicrotasksScope microtasks_scope( + isolate, context->GetMicrotaskQueue(), + v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::Context::Scope context_scope(context); + + InvokeEmitProcessEvent(context, event_name); } } // namespace electron diff --git a/shell/renderer/electron_sandboxed_renderer_client.h b/shell/renderer/electron_sandboxed_renderer_client.h index 3647893a75ec..9d6191eea871 100644 --- a/shell/renderer/electron_sandboxed_renderer_client.h +++ b/shell/renderer/electron_sandboxed_renderer_client.h @@ -45,6 +45,9 @@ class ElectronSandboxedRendererClient : public RendererClientBase { void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override; private: + void EmitProcessEvent(content::RenderFrame* render_frame, + const char* event_name); + std::unique_ptr metrics_; // Getting main script context from web frame would lazily initializes