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 22 23

export class BrowserWindowConfiguration implements IWindowConfiguration {

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

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

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

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

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

44 45 46 47 48 49 50 51 52 53 54 55
	@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 已提交
56 57 58
	// Currently unsupported in web
	get filesToDiff(): IPath[] | undefined { return undefined; }

59 60 61
	//#endregion


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

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

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

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

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

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

	workspace?: IWorkspaceIdentifier;
	folderUri?: ISingleFolderWorkspaceIdentifier;

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

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

	filesToWait?: IPathsToWaitFor;
92 93

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

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

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

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

114
export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService {
115

116
	_serviceBrand: undefined;
117

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

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

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

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

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

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

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

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

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

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

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

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

		return this._extensionHostDebugEnvironment.extensionTestsLocationURI;
	}

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

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

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

B
Benjamin Pasero 已提交
202 203 204 205 206 207 208
	// 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; }

209 210 211
	//#endregion


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

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

		return this._configuration;
221 222
	}

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

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

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

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

	argvResource!: URI;

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

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

	installSourcePath!: string;

	builtinExtensionsPath!: string;

	globalStorageHome!: string;
	workspaceStorageHome!: string;

	backupWorkspacesPath!: string;

	machineSettingsHome!: URI;
	machineSettingsResource!: URI;

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

	//#endregion


	//#region TODO ENABLE IN WEB

265
	galleryMachineIdResource?: URI;
266

267 268
	//#endregion

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

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

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

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

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

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

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

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