environmentService.ts 9.2 KB
Newer Older
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6
import { Schemas } from 'vs/base/common/network';
7
import { ExportData } from 'vs/base/common/performance';
8
import { IProcessEnvironment } from 'vs/base/common/platform';
9
import { joinPath } from 'vs/base/common/resources';
10 11 12 13 14 15
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { BACKUPS, IDebugParams, IExtensionHostDebugParams } from 'vs/platform/environment/common/environment';
import { LogLevel } from 'vs/platform/log/common/log';
import { IPath, IPathsToWaitFor, IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
16 17
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
M
Matt Bierner 已提交
18
import product from 'vs/platform/product/common/product';
19
import { serializableToMap } from 'vs/base/common/map';
20
import { memoize } from 'vs/base/common/decorators';
21 22 23

export class BrowserWindowConfiguration implements IWindowConfiguration {

B
Benjamin Pasero 已提交
24
	constructor(private readonly options: IBrowserWorkbenchEnvironemntConstructionOptions, private readonly environment: IWorkbenchEnvironmentService) { }
25 26 27

	//#region PROPERLY CONFIGURED

B
Benjamin Pasero 已提交
28
	@memoize
29 30
	get remoteAuthority(): string | undefined { return this.options.remoteAuthority; }

B
Benjamin Pasero 已提交
31 32 33 34 35 36
	@memoize
	get connectionToken(): string | undefined { return this.options.connectionToken || this.getCookieValue('vscode-tkn'); }

	@memoize
	get backupWorkspaceResource(): URI { return joinPath(this.environment.backupHome, this.options.workspaceId); }

37 38 39 40 41
	//#endregion


	//#region TODO@ben TO BE DONE

B
Benjamin Pasero 已提交
42
	_!: any[];
43

44
	readonly machineId = generateUuid();
B
Benjamin Pasero 已提交
45
	windowId!: number;
J
Joao Moreno 已提交
46
	sessionId!: string;
B
Benjamin Pasero 已提交
47
	logLevel!: LogLevel;
48

B
Benjamin Pasero 已提交
49
	mainPid!: number;
50

B
Benjamin Pasero 已提交
51 52
	appRoot!: string;
	execPath!: string;
53 54
	isInitialStartup?: boolean;

B
Benjamin Pasero 已提交
55
	userEnv!: IProcessEnvironment;
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
	nodeCachedDataDir?: string;

	backupPath?: string;

	workspace?: IWorkspaceIdentifier;
	folderUri?: ISingleFolderWorkspaceIdentifier;

	zoomLevel?: number;
	fullscreen?: boolean;
	maximized?: boolean;
	highContrast?: boolean;
	frameless?: boolean;
	accessibilitySupport?: boolean;
	partsSplashPath?: string;

	perfStartTime?: number;
	perfAppReady?: number;
	perfWindowLoadTime?: number;
B
Benjamin Pasero 已提交
74
	perfEntries!: ExportData;
75 76 77 78 79

	filesToOpenOrCreate?: IPath[];
	filesToDiff?: IPath[];
	filesToWait?: IPathsToWaitFor;
	termProgram?: string;
80 81

	//#endregion
B
Benjamin Pasero 已提交
82 83 84 85 86 87

	private getCookieValue(name: string): string | undefined {
		const m = document.cookie.match('(^|[^;]+)\\s*' + name + '\\s*=\\s*([^;]+)'); // See https://stackoverflow.com/a/25490531

		return m ? m.pop() : undefined;
	}
88 89
}

90
interface IBrowserWorkbenchEnvironemntConstructionOptions extends IWorkbenchConstructionOptions {
S
Sandeep Somavarapu 已提交
91
	workspaceId: string;
92
	logsPath: URI;
S
Sandeep Somavarapu 已提交
93 94
}

B
Benjamin Pasero 已提交
95 96 97 98 99 100
interface IExtensionHostDebugEnvironment {
	params: IExtensionHostDebugParams;
	isExtensionDevelopment: boolean;
	extensionDevelopmentLocationURI: URI[];
}

101
export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService {
102

103
	_serviceBrand: undefined;
104

105
	//#region PROPERLY CONFIGURED
106

107 108
	@memoize
	get logsPath(): string { return this.options.logsPath.path; }
109

110 111
	@memoize
	get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
112

113 114
	@memoize
	get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
115

116 117
	@memoize
	get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
118

119 120
	@memoize
	get settingsSyncPreviewResource(): URI { return joinPath(this.userRoamingDataHome, '.settings.json'); }
121

122 123 124 125 126 127
	@memoize
	get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }

	@memoize
	get keybindingsResource(): URI { return joinPath(this.userRoamingDataHome, 'keybindings.json'); }

B
Benjamin Pasero 已提交
128
	@memoize
129 130
	get keyboardLayoutResource(): URI { return joinPath(this.userRoamingDataHome, 'keyboardLayout.json'); }

B
Benjamin Pasero 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
	@memoize
	get backupHome(): URI { return joinPath(this.userRoamingDataHome, BACKUPS); }

	@memoize
	get untitledWorkspacesHome(): URI { return joinPath(this.userRoamingDataHome, 'Workspaces'); }

	private _extensionHostDebugEnvironment: IExtensionHostDebugEnvironment | undefined = undefined;
	get debugExtensionHost(): IExtensionHostDebugParams {
		if (!this._extensionHostDebugEnvironment) {
			this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment();
		}

		return this._extensionHostDebugEnvironment.params;
	}

	get isExtensionDevelopment(): boolean {
		if (!this._extensionHostDebugEnvironment) {
			this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment();
		}

		return this._extensionHostDebugEnvironment.isExtensionDevelopment;
	}

	get extensionDevelopmentLocationURI(): URI[] {
		if (!this._extensionHostDebugEnvironment) {
			this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment();
		}

		return this._extensionHostDebugEnvironment.extensionDevelopmentLocationURI;
	}

	@memoize
	get webviewExternalEndpoint(): string {
		// TODO: get fallback from product.json
		return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}').replace('{{commit}}', product.commit || 'c58aaab8a1cc22a7139b761166a0d4f37d41e998');
	}

	@memoize
	get webviewResourceRoot(): string {
		return `${this.webviewExternalEndpoint}/vscode-resource/{{resource}}`;
	}

	@memoize
	get webviewCspSource(): string {
		return this.webviewExternalEndpoint.replace('{{uuid}}', '*');
	}

178 179 180 181 182 183 184 185
	//#endregion


	//#region TODO@ben TO BE DONE

	private _configuration: IWindowConfiguration | undefined = undefined;
	get configuration(): IWindowConfiguration {
		if (!this._configuration) {
B
Benjamin Pasero 已提交
186
			this._configuration = new BrowserWindowConfiguration(this.options, this);
187
		}
188 189

		return this._configuration;
190 191
	}

192 193 194
	readonly args = { _: [] };
	readonly appRoot = '/web/';

B
Benjamin Pasero 已提交
195 196 197 198
	argvResource!: URI;

	//#endregion

199
	extensionTestsLocationURI?: URI;
200

B
Benjamin Pasero 已提交
201 202 203 204 205
	execPath!: string;
	cliPath!: string;
	userHome!: string;
	userDataPath!: string;
	appSettingsHome!: URI;
B
Benjamin Pasero 已提交
206

B
Benjamin Pasero 已提交
207 208 209 210 211 212
	machineSettingsHome!: URI;
	machineSettingsResource!: URI;
	globalStorageHome!: string;
	workspaceStorageHome!: string;
	backupWorkspacesPath!: string;
	workspacesHome!: string;
B
Benjamin Pasero 已提交
213

B
Benjamin Pasero 已提交
214 215
	disableExtensions!: boolean | string[];
	builtinExtensionsPath!: string;
216
	extensionsPath?: string;
217
	extensionTestsPath?: string;
B
Benjamin Pasero 已提交
218 219 220 221 222
	debugSearch!: IDebugParams;
	logExtensionHostCommunication!: boolean;
	isBuilt!: boolean;
	wait!: boolean;
	status!: boolean;
223
	log?: string;
224

B
Benjamin Pasero 已提交
225 226 227 228
	verbose!: boolean;
	skipReleaseNotes!: boolean;
	mainIPCHandle!: string;
	sharedIPCHandle!: string;
229
	nodeCachedDataDir?: string;
B
Benjamin Pasero 已提交
230 231 232
	installSourcePath!: string;
	disableUpdates!: boolean;
	disableCrashReporter!: boolean;
233
	driverHandle?: string;
B
Benjamin Pasero 已提交
234
	driverVerbose!: boolean;
235
	galleryMachineIdResource?: URI;
236

B
Benjamin Pasero 已提交
237
	constructor(readonly options: IBrowserWorkbenchEnvironemntConstructionOptions) { }
238

B
Benjamin Pasero 已提交
239 240 241 242 243 244 245 246
	private resolveExtensionHostDebugEnvironment(): IExtensionHostDebugEnvironment {
		const extensionHostDebugEnvironment: IExtensionHostDebugEnvironment = {
			params: {
				port: null,
				break: false
			},
			isExtensionDevelopment: false,
			extensionDevelopmentLocationURI: []
247
		};
M
Matt Bierner 已提交
248

249
		// Fill in selected extra environmental properties
B
Benjamin Pasero 已提交
250 251
		if (this.options.workspaceProvider && Array.isArray(this.options.workspaceProvider.payload)) {
			const environment = serializableToMap(this.options.workspaceProvider.payload);
252 253 254
			for (const [key, value] of environment) {
				switch (key) {
					case 'extensionDevelopmentPath':
B
Benjamin Pasero 已提交
255 256
						extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(value)];
						extensionHostDebugEnvironment.isExtensionDevelopment = true;
257 258
						break;
					case 'debugId':
B
Benjamin Pasero 已提交
259
						extensionHostDebugEnvironment.params.debugId = value;
260 261
						break;
					case 'inspect-brk-extensions':
B
Benjamin Pasero 已提交
262 263
						extensionHostDebugEnvironment.params.port = parseInt(value);
						extensionHostDebugEnvironment.params.break = false;
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
						break;
				}
			}
		} else {
			// TODO@Ben remove me once environment is adopted
			if (document && document.location && document.location.search) {
				const map = new Map<string, string>();
				const query = document.location.search.substring(1);
				const vars = query.split('&');
				for (let p of vars) {
					const pair = p.split('=');
					if (pair.length >= 2) {
						map.set(pair[0], decodeURIComponent(pair[1]));
					}
				}
S
Sandeep Somavarapu 已提交
279

280 281
				const edp = map.get('extensionDevelopmentPath');
				if (edp) {
B
Benjamin Pasero 已提交
282 283
					extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(edp)];
					extensionHostDebugEnvironment.isExtensionDevelopment = true;
284 285 286 287
				}

				const di = map.get('debugId');
				if (di) {
B
Benjamin Pasero 已提交
288
					extensionHostDebugEnvironment.params.debugId = di;
289 290 291 292
				}

				const ibe = map.get('inspect-brk-extensions');
				if (ibe) {
B
Benjamin Pasero 已提交
293 294
					extensionHostDebugEnvironment.params.port = parseInt(ibe);
					extensionHostDebugEnvironment.params.break = false;
295 296 297
				}
			}
		}
S
Sandeep Somavarapu 已提交
298

B
Benjamin Pasero 已提交
299 300
		return extensionHostDebugEnvironment;
	}
301
}