Skip to content

Commit

Permalink
refactor: only access memory coordinator interface from browser proce…
Browse files Browse the repository at this point in the history
  • Loading branch information
deepak1556 committed Oct 6, 2021
1 parent d6f44a7 commit 9c54bf7
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 10 deletions.
4 changes: 4 additions & 0 deletions lib/browser/rpc-server.ts
Expand Up @@ -39,6 +39,10 @@ ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_LAST_WEB_PREFERENCES, function (
return event.sender.getLastWebPreferences();
});

ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO, function (event) {
return event.sender._getProcessMemoryInfo();
});

// Methods not listed in this set are called directly in the renderer process.
const allowedClipboardMethods = (() => {
switch (process.platform) {
Expand Down
1 change: 1 addition & 0 deletions lib/common/ipc-messages.ts
Expand Up @@ -4,6 +4,7 @@ export const enum IPC_MESSAGES {
BROWSER_PRELOAD_ERROR = 'BROWSER_PRELOAD_ERROR',
BROWSER_SANDBOX_LOAD = 'BROWSER_SANDBOX_LOAD',
BROWSER_WINDOW_CLOSE = 'BROWSER_WINDOW_CLOSE',
BROWSER_GET_PROCESS_MEMORY_INFO = 'BROWSER_GET_PROCESS_MEMORY_INFO',

GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',

Expand Down
4 changes: 4 additions & 0 deletions lib/renderer/init.ts
Expand Up @@ -59,6 +59,10 @@ v8Util.setHiddenValue(global, 'ipcNative', {
}
});

process.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};

// Use electron module after everything is ready.
const { webFrameInit } = require('@electron/internal/renderer/web-frame-init') as typeof webFrameInitModule;
webFrameInit();
Expand Down
4 changes: 4 additions & 0 deletions lib/sandboxed_renderer/init.ts
Expand Up @@ -86,6 +86,10 @@ Object.assign(preloadProcess, processProps);
Object.assign(process, binding.process);
Object.assign(process, processProps);

process.getProcessMemoryInfo = preloadProcess.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};

Object.defineProperty(preloadProcess, 'noDeprecation', {
get () {
return process.noDeprecation;
Expand Down
23 changes: 23 additions & 0 deletions shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -72,6 +72,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "printing/print_job_constants.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "shell/browser/api/electron_api_browser_window.h"
#include "shell/browser/api/electron_api_debugger.h"
Expand Down Expand Up @@ -99,6 +100,7 @@
#include "shell/browser/web_view_guest_delegate.h"
#include "shell/browser/web_view_manager.h"
#include "shell/common/api/electron_api_native_image.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/color_util.h"
#include "shell/common/electron_constants.h"
#include "shell/common/gin_converters/base_converter.h"
Expand Down Expand Up @@ -3251,6 +3253,26 @@ void WebContents::SetImageAnimationPolicy(const std::string& new_policy) {
web_contents()->OnWebPreferencesChanged();
}

v8::Local<v8::Promise> WebContents::GetProcessMemoryInfo(v8::Isolate* isolate) {
gin_helper::Promise<gin_helper::Dictionary> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();

auto* frame_host = web_contents()->GetMainFrame();
if (!frame_host) {
promise.RejectWithErrorMessage("Failed to create memory dump");
return handle;
}

auto pid = frame_host->GetProcess()->GetProcess().Pid();
v8::Global<v8::Context> context(isolate, isolate->GetCurrentContext());
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpForPid(
pid, std::vector<std::string>(),
base::BindOnce(&ElectronBindings::DidReceiveMemoryDump,
std::move(context), std::move(promise), pid));
return handle;
}

v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
v8::Isolate* isolate,
const base::FilePath& file_path) {
Expand Down Expand Up @@ -3882,6 +3904,7 @@ v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
.SetMethod("takeHeapSnapshot", &WebContents::TakeHeapSnapshot)
.SetMethod("setImageAnimationPolicy",
&WebContents::SetImageAnimationPolicy)
.SetMethod("_getProcessMemoryInfo", &WebContents::GetProcessMemoryInfo)
.SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_web_contents.h
Expand Up @@ -324,6 +324,7 @@ class WebContents : public gin::Wrappable<WebContents>,

v8::Local<v8::Promise> TakeHeapSnapshot(v8::Isolate* isolate,
const base::FilePath& file_path);
v8::Local<v8::Promise> GetProcessMemoryInfo(v8::Isolate* isolate);

// Properties.
int32_t ID() const { return id_; }
Expand Down
13 changes: 9 additions & 4 deletions shell/common/api/electron_bindings.cc
Expand Up @@ -50,7 +50,9 @@ void ElectronBindings::BindProcess(v8::Isolate* isolate,
process->SetMethod("getCreationTime", &GetCreationTime);
process->SetMethod("getHeapStatistics", &GetHeapStatistics);
process->SetMethod("getBlinkMemoryInfo", &GetBlinkMemoryInfo);
process->SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo);
if (gin_helper::Locker::IsBrowserProcess()) {
process->SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo);
}
process->SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo);
process->SetMethod("getSystemVersion",
&base::SysInfo::OperatingSystemVersion);
Expand Down Expand Up @@ -207,10 +209,11 @@ v8::Local<v8::Value> ElectronBindings::GetSystemMemoryInfo(
// static
v8::Local<v8::Promise> ElectronBindings::GetProcessMemoryInfo(
v8::Isolate* isolate) {
CHECK(gin_helper::Locker::IsBrowserProcess());
gin_helper::Promise<gin_helper::Dictionary> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();

if (gin_helper::Locker::IsBrowserProcess() && !Browser::Get()->is_ready()) {
if (!Browser::Get()->is_ready()) {
promise.RejectWithErrorMessage(
"Memory Info is available only after app ready");
return handle;
Expand All @@ -221,7 +224,8 @@ v8::Local<v8::Promise> ElectronBindings::GetProcessMemoryInfo(
->RequestGlobalDumpForPid(
base::GetCurrentProcId(), std::vector<std::string>(),
base::BindOnce(&ElectronBindings::DidReceiveMemoryDump,
std::move(context), std::move(promise)));
std::move(context), std::move(promise),
base::GetCurrentProcId()));
return handle;
}

Expand All @@ -242,6 +246,7 @@ v8::Local<v8::Value> ElectronBindings::GetBlinkMemoryInfo(
void ElectronBindings::DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
base::ProcessId target_pid,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump) {
v8::Isolate* isolate = promise.isolate();
Expand All @@ -259,7 +264,7 @@ void ElectronBindings::DidReceiveMemoryDump(
bool resolved = false;
for (const memory_instrumentation::GlobalMemoryDump::ProcessDump& dump :
global_dump->process_dumps()) {
if (base::GetCurrentProcId() == dump.pid()) {
if (target_pid == dump.pid()) {
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
const auto& osdump = dump.os_dump();
#if defined(OS_LINUX) || defined(OS_WIN)
Expand Down
13 changes: 7 additions & 6 deletions shell/common/api/electron_bindings.h
Expand Up @@ -49,6 +49,13 @@ class ElectronBindings {

static void Crash();

static void DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
base::ProcessId target_pid,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);

private:
static void Hang();
static v8::Local<v8::Value> GetHeapStatistics(v8::Isolate* isolate);
Expand All @@ -67,12 +74,6 @@ class ElectronBindings {

static void OnCallNextTick(uv_async_t* handle);

static void DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);

UvHandle<uv_async_t> call_next_tick_async_;
std::list<node::Environment*> pending_next_ticks_;
std::unique_ptr<base::ProcessMetrics> metrics_;
Expand Down
1 change: 1 addition & 0 deletions typings/internal-electron.d.ts
Expand Up @@ -58,6 +58,7 @@ declare namespace Electron {
_loadURL(url: string, options: ElectronInternal.LoadURLOptions): void;
getOwnerBrowserWindow(): Electron.BrowserWindow;
getLastWebPreferences(): Electron.WebPreferences;
_getProcessMemoryInfo(): Electron.ProcessMemoryInfo;
_getPreloadPaths(): string[];
equal(other: WebContents): boolean;
browserWindowOptions: BrowserWindowConstructorOptions;
Expand Down

0 comments on commit 9c54bf7

Please sign in to comment.