Skip to content

Commit

Permalink
Move process explorer into electron-sandbox layer, fixes #101832
Browse files Browse the repository at this point in the history
  • Loading branch information
Rachel Macfarlane committed Jul 17, 2020
1 parent d345602 commit a8b8907
Show file tree
Hide file tree
Showing 14 changed files with 58 additions and 30 deletions.
2 changes: 1 addition & 1 deletion build/gulpfile.vscode.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const vscodeResources = [
'out-build/vs/code/electron-browser/workbench/**',
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
'out-build/vs/code/electron-browser/issue/issueReporter.js',
'out-build/vs/code/electron-browser/processExplorer/processExplorer.js',
'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.js',
'out-build/vs/platform/auth/common/auth.css',
'!**/test/**'
];
Expand Down
2 changes: 1 addition & 1 deletion src/vs/code/buildfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ exports.collectModules = function () {
createModuleDescription('vs/code/electron-browser/sharedProcess/sharedProcessMain', []),
createModuleDescription('vs/code/electron-browser/issue/issueReporterMain', []),
createModuleDescription('vs/platform/driver/node/driver', []),
createModuleDescription('vs/code/electron-browser/processExplorer/processExplorerMain', [])
createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain', [])
];
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ const bootstrapWindow = (() => {
return window.MonacoBootstrapWindow;
})();

bootstrapWindow.load(['vs/code/electron-browser/processExplorer/processExplorerMain'], function (processExplorer, configuration) {
processExplorer.startup(configuration.data);
bootstrapWindow.load(['vs/code/electron-sandbox/processExplorer/processExplorerMain'], function (processExplorer, configuration) {
processExplorer.startup(configuration.windowId, configuration.data);
}, { forceEnableDeveloperKeybindings: true });
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@
*--------------------------------------------------------------------------------------------*/

import 'vs/css!./media/processExplorer';
import { clipboard } from 'electron';
import { totalmem } from 'os';
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import product from 'vs/platform/product/common/product';
import { localize } from 'vs/nls';
import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue';
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import * as platform from 'vs/base/common/platform';
import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
import { popup } from 'vs/base/parts/contextmenu/electron-sandbox/contextmenu';
import { ProcessItem } from 'vs/base/common/processes';
import { addDisposableListener, addClass } from 'vs/base/browser/dom';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
import { MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';

const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/;
const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/;
Expand All @@ -40,7 +39,12 @@ class ProcessExplorer {

private listeners = new DisposableStore();

constructor(data: ProcessExplorerData) {
private electronService: IElectronService;

constructor(windowId: number, private data: ProcessExplorerData) {
const mainProcessService = new MainProcessService(windowId);
this.electronService = new ElectronService(windowId, mainProcessService) as IElectronService;

this.applyStyles(data.styles);

// Map window process pids to titles, annotate process names with this when rendering to distinguish between them
Expand All @@ -59,17 +63,17 @@ class ProcessExplorer {
ipcRenderer.send('vscode:listProcesses');
}

private getProcessList(rootProcess: ProcessItem, isLocal: boolean): FormattedProcessItem[] {
private getProcessList(rootProcess: ProcessItem, isLocal: boolean, totalMem: number): FormattedProcessItem[] {
const processes: FormattedProcessItem[] = [];

if (rootProcess) {
this.getProcessItem(processes, rootProcess, 0, isLocal);
this.getProcessItem(processes, rootProcess, 0, isLocal, totalMem);
}

return processes;
}

private getProcessItem(processes: FormattedProcessItem[], item: ProcessItem, indent: number, isLocal: boolean): void {
private getProcessItem(processes: FormattedProcessItem[], item: ProcessItem, indent: number, isLocal: boolean, totalMem: number): void {
const isRoot = (indent === 0);

const MB = 1024 * 1024;
Expand All @@ -86,7 +90,7 @@ class ProcessExplorer {

// Format name with indent
const formattedName = isRoot ? name : `${' '.repeat(indent)} ${name}`;
const memory = process.platform === 'win32' ? item.mem : (totalmem() * (item.mem / 100));
const memory = this.data.platform === 'win32' ? item.mem : (totalMem * (item.mem / 100));
processes.push({
cpu: item.load,
memory: (memory / MB),
Expand All @@ -100,7 +104,7 @@ class ProcessExplorer {
if (Array.isArray(item.children)) {
item.children.forEach(child => {
if (child) {
this.getProcessItem(processes, child, indent + 1, isLocal);
this.getProcessItem(processes, child, indent + 1, isLocal, totalMem);
}
});
}
Expand Down Expand Up @@ -258,7 +262,7 @@ class ProcessExplorer {
container.appendChild(body);
}

private updateProcessInfo(processLists: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]): void {
private async updateProcessInfo(processLists: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]): Promise<void> {
const container = document.getElementById('process-list');
if (!container) {
return;
Expand All @@ -278,12 +282,13 @@ class ProcessExplorer {
container.append(tableHead);

const hasMultipleMachines = Object.keys(processLists).length > 1;
const totalMem = await this.electronService.getTotalMem();
processLists.forEach((remote, i) => {
const isLocal = i === 0;
if (isRemoteDiagnosticError(remote.rootProcess)) {
this.renderProcessFetchError(remote.name, remote.rootProcess.errorMessage);
} else {
this.renderTableSection(remote.name, this.getProcessList(remote.rootProcess, isLocal), hasMultipleMachines, isLocal);
this.renderTableSection(remote.name, this.getProcessList(remote.rootProcess, isLocal, totalMem), hasMultipleMachines, isLocal);
}
});
}
Expand Down Expand Up @@ -322,15 +327,15 @@ class ProcessExplorer {
if (isLocal) {
items.push({
label: localize('killProcess', "Kill Process"),
click() {
process.kill(pid, 'SIGTERM');
click: () => {
this.electronService.killProcess(pid, 'SIGTERM');
}
});

items.push({
label: localize('forceKillProcess', "Force Kill Process"),
click() {
process.kill(pid, 'SIGKILL');
click: () => {
this.electronService.killProcess(pid, 'SIGKILL');
}
});

Expand All @@ -341,20 +346,20 @@ class ProcessExplorer {

items.push({
label: localize('copy', "Copy"),
click() {
click: () => {
const row = document.getElementById(pid.toString());
if (row) {
clipboard.writeText(row.innerText);
this.electronService.writeClipboardText(row.innerText);
}
}
});

items.push({
label: localize('copyAll', "Copy All"),
click() {
click: () => {
const processList = document.getElementById('process-list');
if (processList) {
clipboard.writeText(processList.innerText);
this.electronService.writeClipboardText(processList.innerText);
}
}
});
Expand Down Expand Up @@ -398,15 +403,15 @@ class ProcessExplorer {



export function startup(data: ProcessExplorerData): void {
const platformClass = platform.isWindows ? 'windows' : platform.isLinux ? 'linux' : 'mac';
export function startup(windowId: number, data: ProcessExplorerData): void {
const platformClass = data.platform === 'win32' ? 'windows' : data.platform === 'linux' ? 'linux' : 'mac';
addClass(document.body, platformClass); // used by our fonts
applyZoom(data.zoomLevel);

const processExplorer = new ProcessExplorer(data);
const processExplorer = new ProcessExplorer(windowId, data);

document.onkeydown = (e: KeyboardEvent) => {
const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
const cmdOrCtrlKey = data.platform === 'darwin' ? e.metaKey : e.ctrlKey;

// Cmd/Ctrl + zooms in
if (cmdOrCtrlKey && e.keyCode === 187) {
Expand All @@ -421,7 +426,7 @@ export function startup(data: ProcessExplorerData): void {

// Cmd/Ctrl + w closes process explorer
window.addEventListener('keydown', e => {
const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
const cmdOrCtrlKey = data.platform === 'darwin' ? e.metaKey : e.ctrlKey;
if (cmdOrCtrlKey && e.keyCode === 87) {
processExplorer.dispose();
ipcRenderer.send('vscode:closeProcessExplorer');
Expand Down
4 changes: 4 additions & 0 deletions src/vs/platform/electron/common/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export interface ICommonElectronService {
updateTouchBar(items: ISerializableCommandAction[][]): Promise<void>;
moveItemToTrash(fullPath: string, deleteOnFail?: boolean): Promise<boolean>;
isAdmin(): Promise<boolean>;
getTotalMem(): Promise<number>;

// Process
killProcess(pid: number, code: string): Promise<void>;

// clipboard
readClipboardText(type?: 'selection' | 'clipboard'): Promise<string>;
Expand Down
14 changes: 14 additions & 0 deletions src/vs/platform/electron/electron-main/electronMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { ILogService } from 'vs/platform/log/common/log';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes';
import { totalmem } from 'os';

export interface IElectronMainService extends AddFirstParameterToFunctions<ICommonElectronService, Promise<unknown> /* only methods, not events */, number | undefined /* window ID */> { }

Expand Down Expand Up @@ -313,6 +314,19 @@ export class ElectronMainService implements IElectronMainService {
return isAdmin;
}

async getTotalMem(): Promise<number> {
return totalmem();
}

//#endregion


//#region Process

async killProcess(windowId: number | undefined, pid: number, code: string): Promise<void> {
process.kill(pid, code);
}

//#endregion


Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/issue/common/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export interface ProcessExplorerStyles extends WindowStyles {
export interface ProcessExplorerData extends WindowData {
pid: number;
styles: ProcessExplorerStyles;
platform: string;
}

export interface ICommonIssueService {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/platform/issue/electron-main/issueMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class IssueMainService implements ICommonIssueService {
};

this._processExplorerWindow.loadURL(
toLauchUrl('vs/code/electron-browser/processExplorer/processExplorer.html', windowConfiguration));
toLauchUrl('vs/code/electron-sandbox/processExplorer/processExplorer.html', windowConfiguration));

this._processExplorerWindow.on('close', () => this._processExplorerWindow = null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-brow
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { platform } from 'process';

export class WorkbenchIssueService implements IWorkbenchIssueService {
declare readonly _serviceBrand: undefined;
Expand Down Expand Up @@ -67,7 +68,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService {
hoverBackground: getColor(theme, listHoverBackground),
hoverForeground: getColor(theme, listHoverForeground),
highlightForeground: getColor(theme, listHighlightForeground),
}
},
platform
};
return this.issueService.openProcessExplorer(data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ export class TestElectronService implements IElectronService {
async showItemInFolder(path: string): Promise<void> { }
async setRepresentedFilename(path: string): Promise<void> { }
async isAdmin(): Promise<boolean> { return false; }
async getTotalMem(): Promise<number> { return 0; }
async killProcess(): Promise<void> { }
async setDocumentEdited(edited: boolean): Promise<void> { }
async openExternal(url: string): Promise<boolean> { return false; }
async updateTouchBar(): Promise<void> { }
Expand Down

0 comments on commit a8b8907

Please sign in to comment.