environmentService.ts 7.9 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 {

24 25 26 27 28 29 30 31 32 33 34
	constructor(private readonly options: IBrowserWorkbenchEnvironemntConstructionOptions) { }

	//#region PROPERLY CONFIGURED

	get remoteAuthority(): string | undefined { return this.options.remoteAuthority; }

	//#endregion


	//#region TODO@ben TO BE DONE

B
Benjamin Pasero 已提交
35
	_!: any[];
36

37
	readonly machineId = generateUuid();
B
Benjamin Pasero 已提交
38 39
	windowId!: number;
	logLevel!: LogLevel;
40

B
Benjamin Pasero 已提交
41
	mainPid!: number;
42

B
Benjamin Pasero 已提交
43 44
	appRoot!: string;
	execPath!: string;
45 46
	isInitialStartup?: boolean;

B
Benjamin Pasero 已提交
47
	userEnv!: IProcessEnvironment;
48 49 50
	nodeCachedDataDir?: string;

	backupPath?: string;
B
Benjamin Pasero 已提交
51
	backupWorkspaceResource?: URI;
52 53 54 55

	workspace?: IWorkspaceIdentifier;
	folderUri?: ISingleFolderWorkspaceIdentifier;

B
Benjamin Pasero 已提交
56
	connectionToken?: string;
57 58 59 60 61 62 63 64 65 66 67 68

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

	perfStartTime?: number;
	perfAppReady?: number;
	perfWindowLoadTime?: number;
B
Benjamin Pasero 已提交
69
	perfEntries!: ExportData;
70 71 72 73 74

	filesToOpenOrCreate?: IPath[];
	filesToDiff?: IPath[];
	filesToWait?: IPathsToWaitFor;
	termProgram?: string;
75 76

	//#endregion
77 78
}

79
interface IBrowserWorkbenchEnvironemntConstructionOptions extends IWorkbenchConstructionOptions {
S
Sandeep Somavarapu 已提交
80
	workspaceId: string;
81
	logsPath: URI;
S
Sandeep Somavarapu 已提交
82 83
}

84
export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService {
85

86
	_serviceBrand: undefined;
87

88
	//#region PROPERLY CONFIGURED
89

90 91
	@memoize
	get logsPath(): string { return this.options.logsPath.path; }
92

93 94
	@memoize
	get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
95

96 97
	@memoize
	get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
98

99 100
	@memoize
	get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
101

102 103
	@memoize
	get settingsSyncPreviewResource(): URI { return joinPath(this.userRoamingDataHome, '.settings.json'); }
104

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
	@memoize
	get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }

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

	get keyboardLayoutResource(): URI { return joinPath(this.userRoamingDataHome, 'keyboardLayout.json'); }

	//#endregion


	//#region TODO@ben TO BE DONE

	private _configuration: IWindowConfiguration | undefined = undefined;
	get configuration(): IWindowConfiguration {
		if (!this._configuration) {
			this._configuration = new BrowserWindowConfiguration(this.options);
122
		}
123 124

		return this._configuration;
125 126
	}

127 128 129 130 131 132
	readonly args = { _: [] };
	readonly appRoot = '/web/';

	// TODO@Ben get out of product.json?!
	readonly appNameLong = 'Visual Studio Code - Web';

133 134
	untitledWorkspacesHome: URI;
	extensionTestsLocationURI?: URI;
135

B
Benjamin Pasero 已提交
136 137 138 139
	execPath!: string;
	cliPath!: string;
	userHome!: string;
	userDataPath!: string;
140
	appQuality?: string;
B
Benjamin Pasero 已提交
141
	appSettingsHome!: URI;
142
	argvResource: URI;
B
Benjamin Pasero 已提交
143 144 145 146
	machineSettingsHome!: URI;
	machineSettingsResource!: URI;
	globalStorageHome!: string;
	workspaceStorageHome!: string;
S
Sandeep Somavarapu 已提交
147
	backupHome: URI;
B
Benjamin Pasero 已提交
148 149 150 151 152
	backupWorkspacesPath!: string;
	workspacesHome!: string;
	isExtensionDevelopment!: boolean;
	disableExtensions!: boolean | string[];
	builtinExtensionsPath!: string;
153
	extensionsPath?: string;
154 155 156
	extensionDevelopmentLocationURI?: URI[];
	extensionTestsPath?: string;
	debugExtensionHost: IExtensionHostDebugParams;
B
Benjamin Pasero 已提交
157 158 159 160 161
	debugSearch!: IDebugParams;
	logExtensionHostCommunication!: boolean;
	isBuilt!: boolean;
	wait!: boolean;
	status!: boolean;
162
	log?: string;
163

B
Benjamin Pasero 已提交
164 165 166 167
	verbose!: boolean;
	skipReleaseNotes!: boolean;
	mainIPCHandle!: string;
	sharedIPCHandle!: string;
168
	nodeCachedDataDir?: string;
B
Benjamin Pasero 已提交
169 170 171
	installSourcePath!: string;
	disableUpdates!: boolean;
	disableCrashReporter!: boolean;
172
	driverHandle?: string;
B
Benjamin Pasero 已提交
173
	driverVerbose!: boolean;
174
	galleryMachineIdResource?: URI;
175

176 177
	get webviewExternalEndpoint(): string {
		// TODO: get fallback from product.json
178
		return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}')
M
Matt Bierner 已提交
179
			.replace('{{commit}}', product.commit || 'c58aaab8a1cc22a7139b761166a0d4f37d41e998');
180 181
	}

182
	get webviewResourceRoot(): string {
183
		return `${this.webviewExternalEndpoint}/vscode-resource/{{resource}}`;
184
	}
M
Matt Bierner 已提交
185

186
	get webviewCspSource(): string {
187 188
		return this.webviewExternalEndpoint
			.replace('{{uuid}}', '*');
M
Matt Bierner 已提交
189
	}
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

	//#endregion

	constructor(readonly options: IBrowserWorkbenchEnvironemntConstructionOptions) {
		this.argvResource = joinPath(this.userRoamingDataHome, 'argv.json');
		this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS);
		this.untitledWorkspacesHome = joinPath(this.userRoamingDataHome, 'Workspaces');
		this.configuration.backupWorkspaceResource = joinPath(this.backupHome, options.workspaceId);
		this.configuration.connectionToken = options.connectionToken || getCookieValue('vscode-tkn');

		this.debugExtensionHost = {
			port: null,
			break: false
		};

		// Fill in selected extra environmental properties
		if (options.workspaceProvider && Array.isArray(options.workspaceProvider.payload)) {
			const environment = serializableToMap(options.workspaceProvider.payload);
			for (const [key, value] of environment) {
				switch (key) {
					case 'extensionDevelopmentPath':
						this.extensionDevelopmentLocationURI = [URI.parse(value)];
						this.isExtensionDevelopment = true;
						break;
					case 'debugId':
						this.debugExtensionHost.debugId = value;
						break;
					case 'inspect-brk-extensions':
						this.debugExtensionHost.port = parseInt(value);
						this.debugExtensionHost.break = false;
						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]));
					}
				}

				const edp = map.get('extensionDevelopmentPath');
				if (edp) {
					this.extensionDevelopmentLocationURI = [URI.parse(edp)];
					this.isExtensionDevelopment = true;
				}

				const di = map.get('debugId');
				if (di) {
					this.debugExtensionHost.debugId = di;
				}

				const ibe = map.get('inspect-brk-extensions');
				if (ibe) {
					this.debugExtensionHost.port = parseInt(ibe);
					this.debugExtensionHost.break = false;
				}
			}
		}
	}
255
}
S
Sandeep Somavarapu 已提交
256

257 258 259 260 261 262
/**
 * See https://stackoverflow.com/a/25490531
 */
function getCookieValue(name: string): string | undefined {
	const m = document.cookie.match('(^|[^;]+)\\s*' + name + '\\s*=\\s*([^;]+)');
	return m ? m.pop() : undefined;
263
}