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

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

B
Benjamin Pasero 已提交
136 137 138
	@memoize
	get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }

139
	@memoize
S
Sandeep Somavarapu 已提交
140
	get userDataSyncHome(): URI { return joinPath(this.userRoamingDataHome, '.sync'); }
141

142
	@memoize
S
Sandeep Somavarapu 已提交
143 144 145 146
	get settingsSyncPreviewResource(): URI { return joinPath(this.userDataSyncHome, 'settings.json'); }

	@memoize
	get keybindingsSyncPreviewResource(): URI { return joinPath(this.userDataSyncHome, 'keybindings.json'); }
147

148 149 150 151 152 153
	@memoize
	get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }

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

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

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

188 189 190 191 192 193 194 195
	get extensionTestsLocationURI(): URI | undefined {
		if (!this._extensionHostDebugEnvironment) {
			this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment();
		}

		return this._extensionHostDebugEnvironment.extensionTestsLocationURI;
	}

B
Benjamin Pasero 已提交
196 197 198
	@memoize
	get webviewExternalEndpoint(): string {
		// TODO: get fallback from product.json
M
Matt Bierner 已提交
199
		return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}').replace('{{commit}}', product.commit || '0d728c31ebdf03869d2687d9be0b017667c9ff37');
B
Benjamin Pasero 已提交
200 201 202 203 204 205 206 207 208 209 210 211
	}

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

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

B
Benjamin Pasero 已提交
212 213 214 215 216 217 218
	// 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; }

219 220 221
	//#endregion


B
Benjamin Pasero 已提交
222
	//#region TODO MOVE TO NODE LAYER
223 224 225 226

	private _configuration: IWindowConfiguration | undefined = undefined;
	get configuration(): IWindowConfiguration {
		if (!this._configuration) {
227
			this._configuration = new BrowserWindowConfiguration(this.options, this.payload, this);
228
		}
229 230

		return this._configuration;
231 232
	}

B
Benjamin Pasero 已提交
233
	args = { _: [] };
234

B
Benjamin Pasero 已提交
235 236
	wait!: boolean;
	status!: boolean;
237
	log?: string;
238

B
Benjamin Pasero 已提交
239 240
	mainIPCHandle!: string;
	sharedIPCHandle!: string;
B
Benjamin Pasero 已提交
241

242
	nodeCachedDataDir?: string;
B
Benjamin Pasero 已提交
243

B
Benjamin Pasero 已提交
244
	disableCrashReporter!: boolean;
B
Benjamin Pasero 已提交
245

246
	driverHandle?: string;
B
Benjamin Pasero 已提交
247
	driverVerbose!: boolean;
B
Benjamin Pasero 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260

	installSourcePath!: string;

	builtinExtensionsPath!: string;

	globalStorageHome!: string;
	workspaceStorageHome!: string;

	backupWorkspacesPath!: string;

	machineSettingsHome!: URI;
	machineSettingsResource!: URI;

261
	userHome!: string;
B
Benjamin Pasero 已提交
262 263 264 265 266 267 268 269 270 271 272
	userDataPath!: string;
	appRoot!: string;
	appSettingsHome!: URI;
	execPath!: string;
	cliPath!: string;

	//#endregion


	//#region TODO ENABLE IN WEB

273
	galleryMachineIdResource?: URI;
274

275 276
	//#endregion

277 278 279 280 281 282 283
	private payload: Map<string, string> | undefined;

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

B
Benjamin Pasero 已提交
285 286 287 288 289 290 291 292
	private resolveExtensionHostDebugEnvironment(): IExtensionHostDebugEnvironment {
		const extensionHostDebugEnvironment: IExtensionHostDebugEnvironment = {
			params: {
				port: null,
				break: false
			},
			isExtensionDevelopment: false,
			extensionDevelopmentLocationURI: []
293
		};
M
Matt Bierner 已提交
294

295
		// Fill in selected extra environmental properties
296 297
		if (this.payload) {
			for (const [key, value] of this.payload) {
298 299
				switch (key) {
					case 'extensionDevelopmentPath':
B
Benjamin Pasero 已提交
300 301
						extensionHostDebugEnvironment.extensionDevelopmentLocationURI = [URI.parse(value)];
						extensionHostDebugEnvironment.isExtensionDevelopment = true;
302
						break;
A
Andre Weinand 已提交
303 304 305
					case 'extensionTestsPath':
						extensionHostDebugEnvironment.extensionTestsLocationURI = URI.parse(value);
						break;
306
					case 'debugId':
B
Benjamin Pasero 已提交
307
						extensionHostDebugEnvironment.params.debugId = value;
308 309
						break;
					case 'inspect-brk-extensions':
B
Benjamin Pasero 已提交
310
						extensionHostDebugEnvironment.params.port = parseInt(value);
311
						extensionHostDebugEnvironment.params.break = true;
312 313 314 315
						break;
				}
			}
		}
S
Sandeep Somavarapu 已提交
316

B
Benjamin Pasero 已提交
317 318
		return extensionHostDebugEnvironment;
	}
319
}