environmentService.ts 10.0 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
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
B
Benjamin Pasero 已提交
12
import { BACKUPS, IExtensionHostDebugParams } from 'vs/platform/environment/common/environment';
13 14 15
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

B
Benjamin Pasero 已提交
22
// TODO@ben remove properties that are node/electron only
23 24
export class BrowserWindowConfiguration implements IWindowConfiguration {

25 26 27 28 29
	constructor(
		private readonly options: IBrowserWorkbenchEnvironmentConstructionOptions,
		private readonly payload: Map<string, string> | undefined,
		private readonly environment: IWorkbenchEnvironmentService
	) { }
30

B
Benjamin Pasero 已提交
31
	//#region PROPERLY CONFIGURED IN DESKTOP + WEB
32

B
Benjamin Pasero 已提交
33 34 35
	@memoize
	get sessionId(): string { return generateUuid(); }

B
Benjamin Pasero 已提交
36
	@memoize
37 38
	get remoteAuthority(): string | undefined { return this.options.remoteAuthority; }

B
Benjamin Pasero 已提交
39 40 41 42 43 44
	@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); }

45 46 47 48 49 50 51 52 53 54 55 56
	@memoize
	get filesToOpenOrCreate(): IPath[] | undefined {
		if (this.payload) {
			const fileToOpen = this.payload.get('openFile');
			if (fileToOpen) {
				return [{ fileUri: URI.parse(fileToOpen) }];
			}
		}

		return undefined;
	}

B
Benjamin Pasero 已提交
57 58 59
	// Currently unsupported in web
	get filesToDiff(): IPath[] | undefined { return undefined; }

60 61 62
	//#endregion


B
Benjamin Pasero 已提交
63
	//#region TODO MOVE TO NODE LAYER
64

B
Benjamin Pasero 已提交
65
	_!: any[];
66

B
Benjamin Pasero 已提交
67 68
	windowId!: number;
	mainPid!: number;
69

B
Benjamin Pasero 已提交
70 71
	logLevel!: LogLevel;

B
Benjamin Pasero 已提交
72 73
	appRoot!: string;
	execPath!: string;
B
Benjamin Pasero 已提交
74
	backupPath?: string;
75 76
	nodeCachedDataDir?: string;

B
Benjamin Pasero 已提交
77
	userEnv!: IProcessEnvironment;
78 79 80 81 82 83 84 85 86 87 88

	workspace?: IWorkspaceIdentifier;
	folderUri?: ISingleFolderWorkspaceIdentifier;

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

B
Benjamin Pasero 已提交
89
	isInitialStartup?: boolean;
B
Benjamin Pasero 已提交
90
	perfEntries!: ExportData;
91 92

	filesToWait?: IPathsToWaitFor;
93 94

	//#endregion
B
Benjamin Pasero 已提交
95 96 97 98 99 100

	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;
	}
101 102
}

S
SteVen Batten 已提交
103
interface IBrowserWorkbenchEnvironmentConstructionOptions extends IWorkbenchConstructionOptions {
S
Sandeep Somavarapu 已提交
104
	workspaceId: string;
105
	logsPath: URI;
S
Sandeep Somavarapu 已提交
106 107
}

B
Benjamin Pasero 已提交
108 109 110 111
interface IExtensionHostDebugEnvironment {
	params: IExtensionHostDebugParams;
	isExtensionDevelopment: boolean;
	extensionDevelopmentLocationURI: URI[];
112
	extensionTestsLocationURI?: URI;
B
Benjamin Pasero 已提交
113 114
}

115
export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService {
116

117
	_serviceBrand: undefined;
118

B
Benjamin Pasero 已提交
119
	//#region PROPERLY CONFIGURED IN DESKTOP + WEB
120

121 122 123
	@memoize
	get isBuilt(): boolean { return !!product.commit; }

124 125
	@memoize
	get logsPath(): string { return this.options.logsPath.path; }
126

127 128
	@memoize
	get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
129

130 131
	@memoize
	get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
132

133 134
	@memoize
	get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
135

136 137
	@memoize
	get settingsSyncPreviewResource(): URI { return joinPath(this.userRoamingDataHome, '.settings.json'); }
138

139 140 141 142 143 144
	@memoize
	get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }

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

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

B
Benjamin Pasero 已提交
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 178
	@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;
	}

179 180 181 182 183 184 185 186
	get extensionTestsLocationURI(): URI | undefined {
		if (!this._extensionHostDebugEnvironment) {
			this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment();
		}

		return this._extensionHostDebugEnvironment.extensionTestsLocationURI;
	}

B
Benjamin Pasero 已提交
187 188 189
	@memoize
	get webviewExternalEndpoint(): string {
		// TODO: get fallback from product.json
M
Matt Bierner 已提交
190
		return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}').replace('{{commit}}', product.commit || 'b53811e67e65c6a564a80e1c412ca2b13de02907');
B
Benjamin Pasero 已提交
191 192 193 194 195 196 197 198 199 200 201 202
	}

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

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

B
Benjamin Pasero 已提交
203 204 205 206 207 208 209
	// Currently not configurable in web
	get disableExtensions() { return false; }
	get extensionsPath(): string | undefined { return undefined; }
	get verbose(): boolean { return false; }
	get disableUpdates(): boolean { return false; }
	get logExtensionHostCommunication(): boolean { return false; }

210 211 212
	//#endregion


B
Benjamin Pasero 已提交
213
	//#region TODO MOVE TO NODE LAYER
214 215 216 217

	private _configuration: IWindowConfiguration | undefined = undefined;
	get configuration(): IWindowConfiguration {
		if (!this._configuration) {
218
			this._configuration = new BrowserWindowConfiguration(this.options, this.payload, this);
219
		}
220 221

		return this._configuration;
222 223
	}

B
Benjamin Pasero 已提交
224
	args = { _: [] };
225

B
Benjamin Pasero 已提交
226 227
	wait!: boolean;
	status!: boolean;
228
	log?: string;
229

B
Benjamin Pasero 已提交
230 231
	mainIPCHandle!: string;
	sharedIPCHandle!: string;
B
Benjamin Pasero 已提交
232

233
	nodeCachedDataDir?: string;
B
Benjamin Pasero 已提交
234 235 236

	argvResource!: URI;

B
Benjamin Pasero 已提交
237
	disableCrashReporter!: boolean;
B
Benjamin Pasero 已提交
238

239
	driverHandle?: string;
B
Benjamin Pasero 已提交
240
	driverVerbose!: boolean;
B
Benjamin Pasero 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253

	installSourcePath!: string;

	builtinExtensionsPath!: string;

	globalStorageHome!: string;
	workspaceStorageHome!: string;

	backupWorkspacesPath!: string;

	machineSettingsHome!: URI;
	machineSettingsResource!: URI;

254
	userHome!: string;
B
Benjamin Pasero 已提交
255 256 257 258 259 260 261 262 263 264 265
	userDataPath!: string;
	appRoot!: string;
	appSettingsHome!: URI;
	execPath!: string;
	cliPath!: string;

	//#endregion


	//#region TODO ENABLE IN WEB

266
	galleryMachineIdResource?: URI;
267

268 269
	//#endregion

270 271 272 273 274 275 276
	private payload: Map<string, string> | undefined;

	constructor(readonly options: IBrowserWorkbenchEnvironmentConstructionOptions) {
		if (options.workspaceProvider && Array.isArray(options.workspaceProvider.payload)) {
			this.payload = serializableToMap(options.workspaceProvider.payload);
		}
	}
277

B
Benjamin Pasero 已提交
278 279 280 281 282 283 284 285
	private resolveExtensionHostDebugEnvironment(): IExtensionHostDebugEnvironment {
		const extensionHostDebugEnvironment: IExtensionHostDebugEnvironment = {
			params: {
				port: null,
				break: false
			},
			isExtensionDevelopment: false,
			extensionDevelopmentLocationURI: []
286
		};
M
Matt Bierner 已提交
287

288
		// Fill in selected extra environmental properties
289 290
		if (this.payload) {
			for (const [key, value] of this.payload) {
291 292
				switch (key) {
					case 'extensionDevelopmentPath':
B
Benjamin Pasero 已提交
293 294
						extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(value)];
						extensionHostDebugEnvironment.isExtensionDevelopment = true;
295
						break;
A
Andre Weinand 已提交
296 297 298
					case 'extensionTestsPath':
						extensionHostDebugEnvironment.extensionTestsLocationURI = URI.parse(value);
						break;
299
					case 'debugId':
B
Benjamin Pasero 已提交
300
						extensionHostDebugEnvironment.params.debugId = value;
301 302
						break;
					case 'inspect-brk-extensions':
B
Benjamin Pasero 已提交
303
						extensionHostDebugEnvironment.params.port = parseInt(value);
304
						extensionHostDebugEnvironment.params.break = true;
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
						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 已提交
320

321 322
				const edp = map.get('extensionDevelopmentPath');
				if (edp) {
B
Benjamin Pasero 已提交
323 324
					extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(edp)];
					extensionHostDebugEnvironment.isExtensionDevelopment = true;
325 326 327 328
				}

				const di = map.get('debugId');
				if (di) {
B
Benjamin Pasero 已提交
329
					extensionHostDebugEnvironment.params.debugId = di;
330 331 332 333
				}

				const ibe = map.get('inspect-brk-extensions');
				if (ibe) {
B
Benjamin Pasero 已提交
334 335
					extensionHostDebugEnvironment.params.port = parseInt(ibe);
					extensionHostDebugEnvironment.params.break = false;
336 337 338
				}
			}
		}
S
Sandeep Somavarapu 已提交
339

B
Benjamin Pasero 已提交
340 341
		return extensionHostDebugEnvironment;
	}
342
}