environmentService.ts 9.4 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 22 23

export class BrowserWindowConfiguration implements IWindowConfiguration {

S
SteVen Batten 已提交
24
	constructor(private readonly options: IBrowserWorkbenchEnvironmentConstructionOptions, private readonly environment: IWorkbenchEnvironmentService) { }
25

B
Benjamin Pasero 已提交
26
	//#region PROPERLY CONFIGURED IN DESKTOP + WEB
27

B
Benjamin Pasero 已提交
28 29 30
	@memoize
	get sessionId(): string { return generateUuid(); }

B
Benjamin Pasero 已提交
31
	@memoize
32 33
	get remoteAuthority(): string | undefined { return this.options.remoteAuthority; }

B
Benjamin Pasero 已提交
34 35 36 37 38 39
	@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); }

B
Benjamin Pasero 已提交
40 41 42 43 44 45 46 47
	// TODO@rachel TODO@sbatten fix me, should be stable between sessions
	@memoize
	get machineId(): string { return generateUuid(); }

	// Currently unsupported in web
	get filesToOpenOrCreate(): IPath[] | undefined { return undefined; }
	get filesToDiff(): IPath[] | undefined { return undefined; }

48 49 50
	//#endregion


B
Benjamin Pasero 已提交
51
	//#region TODO MOVE TO NODE LAYER
52

B
Benjamin Pasero 已提交
53
	_!: any[];
54

B
Benjamin Pasero 已提交
55 56
	windowId!: number;
	mainPid!: number;
57

B
Benjamin Pasero 已提交
58 59
	logLevel!: LogLevel;

B
Benjamin Pasero 已提交
60 61
	appRoot!: string;
	execPath!: string;
B
Benjamin Pasero 已提交
62
	backupPath?: string;
63 64
	nodeCachedDataDir?: string;

B
Benjamin Pasero 已提交
65
	userEnv!: IProcessEnvironment;
66 67 68 69 70 71 72 73 74 75 76

	workspace?: IWorkspaceIdentifier;
	folderUri?: ISingleFolderWorkspaceIdentifier;

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

B
Benjamin Pasero 已提交
77
	isInitialStartup?: boolean;
B
Benjamin Pasero 已提交
78
	perfEntries!: ExportData;
79 80

	filesToWait?: IPathsToWaitFor;
81 82

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

	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;
	}
89 90
}

S
SteVen Batten 已提交
91
interface IBrowserWorkbenchEnvironmentConstructionOptions extends IWorkbenchConstructionOptions {
S
Sandeep Somavarapu 已提交
92
	workspaceId: string;
93
	logsPath: URI;
S
Sandeep Somavarapu 已提交
94 95
}

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

102
export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService {
103

104
	_serviceBrand: undefined;
105

B
Benjamin Pasero 已提交
106
	//#region PROPERLY CONFIGURED IN DESKTOP + WEB
107

108 109 110
	@memoize
	get isBuilt(): boolean { return !!product.commit; }

111 112
	@memoize
	get logsPath(): string { return this.options.logsPath.path; }
113

114 115
	@memoize
	get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
116

117 118
	@memoize
	get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
119

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

123 124
	@memoize
	get settingsSyncPreviewResource(): URI { return joinPath(this.userRoamingDataHome, '.settings.json'); }
125

126 127 128 129 130 131
	@memoize
	get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }

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

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

B
Benjamin Pasero 已提交
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 178 179 180 181
	@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}}', '*');
	}

B
Benjamin Pasero 已提交
182 183 184 185 186 187 188
	// 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; }

189 190 191
	//#endregion


B
Benjamin Pasero 已提交
192
	//#region TODO MOVE TO NODE LAYER
193 194 195 196

	private _configuration: IWindowConfiguration | undefined = undefined;
	get configuration(): IWindowConfiguration {
		if (!this._configuration) {
B
Benjamin Pasero 已提交
197
			this._configuration = new BrowserWindowConfiguration(this.options, this);
198
		}
199 200

		return this._configuration;
201 202
	}

B
Benjamin Pasero 已提交
203
	args = { _: [] };
204

B
Benjamin Pasero 已提交
205 206
	wait!: boolean;
	status!: boolean;
207
	log?: string;
208

B
Benjamin Pasero 已提交
209 210
	mainIPCHandle!: string;
	sharedIPCHandle!: string;
B
Benjamin Pasero 已提交
211

212
	nodeCachedDataDir?: string;
B
Benjamin Pasero 已提交
213 214 215

	argvResource!: URI;

B
Benjamin Pasero 已提交
216
	disableCrashReporter!: boolean;
B
Benjamin Pasero 已提交
217

218
	driverHandle?: string;
B
Benjamin Pasero 已提交
219
	driverVerbose!: boolean;
B
Benjamin Pasero 已提交
220 221 222 223 224 225 226 227 228 229 230 231 232

	installSourcePath!: string;

	builtinExtensionsPath!: string;

	globalStorageHome!: string;
	workspaceStorageHome!: string;

	backupWorkspacesPath!: string;

	machineSettingsHome!: URI;
	machineSettingsResource!: URI;

233
	userHome!: string;
B
Benjamin Pasero 已提交
234 235 236 237 238 239 240 241 242 243 244 245 246
	userDataPath!: string;
	appRoot!: string;
	appSettingsHome!: URI;
	execPath!: string;
	cliPath!: string;

	//#endregion


	//#region TODO ENABLE IN WEB

	extensionTestsLocationURI?: URI;

247
	galleryMachineIdResource?: URI;
248

249 250
	//#endregion

S
SteVen Batten 已提交
251
	constructor(readonly options: IBrowserWorkbenchEnvironmentConstructionOptions) { }
252

B
Benjamin Pasero 已提交
253 254 255 256 257 258 259 260
	private resolveExtensionHostDebugEnvironment(): IExtensionHostDebugEnvironment {
		const extensionHostDebugEnvironment: IExtensionHostDebugEnvironment = {
			params: {
				port: null,
				break: false
			},
			isExtensionDevelopment: false,
			extensionDevelopmentLocationURI: []
261
		};
M
Matt Bierner 已提交
262

263
		// Fill in selected extra environmental properties
B
Benjamin Pasero 已提交
264 265
		if (this.options.workspaceProvider && Array.isArray(this.options.workspaceProvider.payload)) {
			const environment = serializableToMap(this.options.workspaceProvider.payload);
266 267 268
			for (const [key, value] of environment) {
				switch (key) {
					case 'extensionDevelopmentPath':
B
Benjamin Pasero 已提交
269 270
						extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(value)];
						extensionHostDebugEnvironment.isExtensionDevelopment = true;
271 272
						break;
					case 'debugId':
B
Benjamin Pasero 已提交
273
						extensionHostDebugEnvironment.params.debugId = value;
274 275
						break;
					case 'inspect-brk-extensions':
B
Benjamin Pasero 已提交
276 277
						extensionHostDebugEnvironment.params.port = parseInt(value);
						extensionHostDebugEnvironment.params.break = false;
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
						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 已提交
293

294 295
				const edp = map.get('extensionDevelopmentPath');
				if (edp) {
B
Benjamin Pasero 已提交
296 297
					extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(edp)];
					extensionHostDebugEnvironment.isExtensionDevelopment = true;
298 299 300 301
				}

				const di = map.get('debugId');
				if (di) {
B
Benjamin Pasero 已提交
302
					extensionHostDebugEnvironment.params.debugId = di;
303 304 305 306
				}

				const ibe = map.get('inspect-brk-extensions');
				if (ibe) {
B
Benjamin Pasero 已提交
307 308
					extensionHostDebugEnvironment.params.port = parseInt(ibe);
					extensionHostDebugEnvironment.params.break = false;
309 310 311
				}
			}
		}
S
Sandeep Somavarapu 已提交
312

B
Benjamin Pasero 已提交
313 314
		return extensionHostDebugEnvironment;
	}
315
}