Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts
5243 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { hostname, release } from 'os';
7
import { MessagePortMain, MessageEvent } from '../../../base/parts/sandbox/node/electronTypes.js';
8
import { toErrorMessage } from '../../../base/common/errorMessage.js';
9
import { onUnexpectedError, setUnexpectedErrorHandler } from '../../../base/common/errors.js';
10
import { combinedDisposable, Disposable, toDisposable } from '../../../base/common/lifecycle.js';
11
import { Schemas } from '../../../base/common/network.js';
12
import { URI } from '../../../base/common/uri.js';
13
import { Emitter } from '../../../base/common/event.js';
14
import { ProxyChannel, StaticRouter } from '../../../base/parts/ipc/common/ipc.js';
15
import { IClientConnectionFilter, Server as UtilityProcessMessagePortServer, once } from '../../../base/parts/ipc/node/ipc.mp.js';
16
import { CodeCacheCleaner } from './contrib/codeCacheCleaner.js';
17
import { LanguagePackCachedDataCleaner } from './contrib/languagePackCachedDataCleaner.js';
18
import { LocalizationsUpdater } from './contrib/localizationsUpdater.js';
19
import { LogsDataCleaner } from './contrib/logsDataCleaner.js';
20
import { UnusedWorkspaceStorageDataCleaner } from './contrib/storageDataCleaner.js';
21
import { IChecksumService } from '../../../platform/checksum/common/checksumService.js';
22
import { ChecksumService } from '../../../platform/checksum/node/checksumService.js';
23
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
24
import { ConfigurationService } from '../../../platform/configuration/common/configurationService.js';
25
import { IDiagnosticsService } from '../../../platform/diagnostics/common/diagnostics.js';
26
import { DiagnosticsService } from '../../../platform/diagnostics/node/diagnosticsService.js';
27
import { IDownloadService } from '../../../platform/download/common/download.js';
28
import { DownloadService } from '../../../platform/download/common/downloadService.js';
29
import { INativeEnvironmentService } from '../../../platform/environment/common/environment.js';
30
import { GlobalExtensionEnablementService } from '../../../platform/extensionManagement/common/extensionEnablementService.js';
31
import { ExtensionGalleryService } from '../../../platform/extensionManagement/common/extensionGalleryService.js';
32
import { IAllowedExtensionsService, IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from '../../../platform/extensionManagement/common/extensionManagement.js';
33
import { ExtensionSignatureVerificationService, IExtensionSignatureVerificationService } from '../../../platform/extensionManagement/node/extensionSignatureVerificationService.js';
34
import { ExtensionManagementChannel, ExtensionTipsChannel } from '../../../platform/extensionManagement/common/extensionManagementIpc.js';
35
import { ExtensionManagementService, INativeServerExtensionManagementService } from '../../../platform/extensionManagement/node/extensionManagementService.js';
36
import { IExtensionRecommendationNotificationService } from '../../../platform/extensionRecommendations/common/extensionRecommendations.js';
37
import { IFileService } from '../../../platform/files/common/files.js';
38
import { FileService } from '../../../platform/files/common/fileService.js';
39
import { DiskFileSystemProvider } from '../../../platform/files/node/diskFileSystemProvider.js';
40
import { SyncDescriptor } from '../../../platform/instantiation/common/descriptors.js';
41
import { IInstantiationService, ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js';
42
import { InstantiationService } from '../../../platform/instantiation/common/instantiationService.js';
43
import { ServiceCollection } from '../../../platform/instantiation/common/serviceCollection.js';
44
import { ILanguagePackService } from '../../../platform/languagePacks/common/languagePacks.js';
45
import { NativeLanguagePackService } from '../../../platform/languagePacks/node/languagePacks.js';
46
import { ConsoleLogger, ILoggerService, ILogService, LoggerGroup } from '../../../platform/log/common/log.js';
47
import { LoggerChannelClient } from '../../../platform/log/common/logIpc.js';
48
import product from '../../../platform/product/common/product.js';
49
import { IProductService } from '../../../platform/product/common/productService.js';
50
import { IRequestService } from '../../../platform/request/common/request.js';
51
import { ISharedProcessConfiguration } from '../../../platform/sharedProcess/node/sharedProcess.js';
52
import { IStorageService } from '../../../platform/storage/common/storage.js';
53
import { resolveCommonProperties } from '../../../platform/telemetry/common/commonProperties.js';
54
import { ICustomEndpointTelemetryService, ITelemetryService } from '../../../platform/telemetry/common/telemetry.js';
55
import { TelemetryAppenderChannel } from '../../../platform/telemetry/common/telemetryIpc.js';
56
import { TelemetryLogAppender } from '../../../platform/telemetry/common/telemetryLogAppender.js';
57
import { TelemetryService } from '../../../platform/telemetry/common/telemetryService.js';
58
import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService, getPiiPathsFromEnvironment, isInternalTelemetry, isLoggingOnly } from '../../../platform/telemetry/common/telemetryUtils.js';
59
import { CustomEndpointTelemetryService } from '../../../platform/telemetry/node/customEndpointTelemetryService.js';
60
import { ExtensionStorageService, IExtensionStorageService } from '../../../platform/extensionManagement/common/extensionStorage.js';
61
import { IgnoredExtensionsManagementService, IIgnoredExtensionsManagementService } from '../../../platform/userDataSync/common/ignoredExtensions.js';
62
import { IUserDataSyncLocalStoreService, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncService, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, IUserDataSyncUtilService, registerConfiguration as registerUserDataSyncConfiguration, IUserDataSyncResourceProviderService } from '../../../platform/userDataSync/common/userDataSync.js';
63
import { IUserDataSyncAccountService, UserDataSyncAccountService } from '../../../platform/userDataSync/common/userDataSyncAccount.js';
64
import { UserDataSyncLocalStoreService } from '../../../platform/userDataSync/common/userDataSyncLocalStoreService.js';
65
import { UserDataSyncAccountServiceChannel, UserDataSyncStoreManagementServiceChannel } from '../../../platform/userDataSync/common/userDataSyncIpc.js';
66
import { UserDataSyncLogService } from '../../../platform/userDataSync/common/userDataSyncLog.js';
67
import { IUserDataSyncMachinesService, UserDataSyncMachinesService } from '../../../platform/userDataSync/common/userDataSyncMachines.js';
68
import { UserDataSyncEnablementService } from '../../../platform/userDataSync/common/userDataSyncEnablementService.js';
69
import { UserDataSyncService } from '../../../platform/userDataSync/common/userDataSyncService.js';
70
import { UserDataSyncServiceChannel } from '../../../platform/userDataSync/common/userDataSyncServiceIpc.js';
71
import { UserDataSyncStoreManagementService, UserDataSyncStoreService } from '../../../platform/userDataSync/common/userDataSyncStoreService.js';
72
import { IUserDataProfileStorageService } from '../../../platform/userDataProfile/common/userDataProfileStorageService.js';
73
import { SharedProcessUserDataProfileStorageService } from '../../../platform/userDataProfile/node/userDataProfileStorageService.js';
74
import { ActiveWindowManager } from '../../../platform/windows/node/windowTracker.js';
75
import { ISignService } from '../../../platform/sign/common/sign.js';
76
import { SignService } from '../../../platform/sign/node/signService.js';
77
import { ISharedTunnelsService } from '../../../platform/tunnel/common/tunnel.js';
78
import { SharedTunnelsService } from '../../../platform/tunnel/node/tunnelService.js';
79
import { ipcSharedProcessTunnelChannelName, ISharedProcessTunnelService } from '../../../platform/remote/common/sharedProcessTunnelService.js';
80
import { SharedProcessTunnelService } from '../../../platform/tunnel/node/sharedProcessTunnelService.js';
81
import { IUriIdentityService } from '../../../platform/uriIdentity/common/uriIdentity.js';
82
import { UriIdentityService } from '../../../platform/uriIdentity/common/uriIdentityService.js';
83
import { isLinux } from '../../../base/common/platform.js';
84
import { FileUserDataProvider } from '../../../platform/userData/common/fileUserDataProvider.js';
85
import { DiskFileSystemProviderClient, LOCAL_FILE_SYSTEM_CHANNEL_NAME } from '../../../platform/files/common/diskFileSystemProviderClient.js';
86
import { InspectProfilingService as V8InspectProfilingService } from '../../../platform/profiling/node/profilingService.js';
87
import { IV8InspectProfilingService } from '../../../platform/profiling/common/profiling.js';
88
import { IExtensionsScannerService } from '../../../platform/extensionManagement/common/extensionsScannerService.js';
89
import { ExtensionsScannerService } from '../../../platform/extensionManagement/node/extensionsScannerService.js';
90
import { IUserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfile.js';
91
import { IExtensionsProfileScannerService } from '../../../platform/extensionManagement/common/extensionsProfileScannerService.js';
92
import { PolicyChannelClient } from '../../../platform/policy/common/policyIpc.js';
93
import { IPolicyService, NullPolicyService } from '../../../platform/policy/common/policy.js';
94
import { UserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfileIpc.js';
95
import { OneDataSystemAppender } from '../../../platform/telemetry/node/1dsAppender.js';
96
import { UserDataProfilesCleaner } from './contrib/userDataProfilesCleaner.js';
97
import { IRemoteTunnelService } from '../../../platform/remoteTunnel/common/remoteTunnel.js';
98
import { UserDataSyncResourceProviderService } from '../../../platform/userDataSync/common/userDataSyncResourceProvider.js';
99
import { ExtensionsContributions } from './contrib/extensions.js';
100
import { localize } from '../../../nls.js';
101
import { LogService } from '../../../platform/log/common/logService.js';
102
import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from '../../../platform/lifecycle/node/sharedProcessLifecycleService.js';
103
import { RemoteTunnelService } from '../../../platform/remoteTunnel/node/remoteTunnelService.js';
104
import { ExtensionsProfileScannerService } from '../../../platform/extensionManagement/node/extensionsProfileScannerService.js';
105
import { ExtensionRecommendationNotificationServiceChannelClient } from '../../../platform/extensionRecommendations/common/extensionRecommendationsIpc.js';
106
import { INativeHostService } from '../../../platform/native/common/native.js';
107
import { NativeHostService } from '../../../platform/native/common/nativeHostService.js';
108
import { UserDataAutoSyncService } from '../../../platform/userDataSync/node/userDataAutoSyncService.js';
109
import { ExtensionTipsService } from '../../../platform/extensionManagement/node/extensionTipsService.js';
110
import { IMainProcessService, MainProcessService } from '../../../platform/ipc/common/mainProcessService.js';
111
import { RemoteStorageService } from '../../../platform/storage/common/storageService.js';
112
import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from '../../../platform/remote/common/remoteSocketFactoryService.js';
113
import { RemoteConnectionType } from '../../../platform/remote/common/remoteAuthorityResolver.js';
114
import { nodeSocketFactory } from '../../../platform/remote/node/nodeSocketFactory.js';
115
import { NativeEnvironmentService } from '../../../platform/environment/node/environmentService.js';
116
import { SharedProcessRawConnection, SharedProcessLifecycle } from '../../../platform/sharedProcess/common/sharedProcess.js';
117
import { getOSReleaseInfo } from '../../../base/node/osReleaseInfo.js';
118
import { getDesktopEnvironment } from '../../../base/common/desktopEnvironmentInfo.js';
119
import { getCodeDisplayProtocol, getDisplayProtocol } from '../../../base/node/osDisplayProtocolInfo.js';
120
import { RequestService } from '../../../platform/request/electron-utility/requestService.js';
121
import { DefaultExtensionsInitializer } from './contrib/defaultExtensionsInitializer.js';
122
import { AllowedExtensionsService } from '../../../platform/extensionManagement/common/allowedExtensionsService.js';
123
import { IExtensionGalleryManifestService } from '../../../platform/extensionManagement/common/extensionGalleryManifest.js';
124
import { ExtensionGalleryManifestIPCService } from '../../../platform/extensionManagement/common/extensionGalleryManifestServiceIpc.js';
125
import { ISharedWebContentExtractorService } from '../../../platform/webContentExtractor/common/webContentExtractor.js';
126
import { SharedWebContentExtractorService } from '../../../platform/webContentExtractor/node/sharedWebContentExtractorService.js';
127
import { McpManagementService } from '../../../platform/mcp/node/mcpManagementService.js';
128
import { IAllowedMcpServersService, IMcpGalleryService, IMcpManagementService } from '../../../platform/mcp/common/mcpManagement.js';
129
import { IMcpResourceScannerService, McpResourceScannerService } from '../../../platform/mcp/common/mcpResourceScannerService.js';
130
import { McpGalleryService } from '../../../platform/mcp/common/mcpGalleryService.js';
131
import { McpManagementChannel } from '../../../platform/mcp/common/mcpManagementIpc.js';
132
import { AllowedMcpServersService } from '../../../platform/mcp/common/allowedMcpServersService.js';
133
import { IMcpGalleryManifestService } from '../../../platform/mcp/common/mcpGalleryManifest.js';
134
import { McpGalleryManifestIPCService } from '../../../platform/mcp/common/mcpGalleryManifestServiceIpc.js';
135
import { IMeteredConnectionService } from '../../../platform/meteredConnection/common/meteredConnection.js';
136
import { MeteredConnectionChannelClient, METERED_CONNECTION_CHANNEL } from '../../../platform/meteredConnection/common/meteredConnectionIpc.js';
137
138
class SharedProcessMain extends Disposable implements IClientConnectionFilter {
139
140
private readonly server = this._register(new UtilityProcessMessagePortServer(this));
141
142
private lifecycleService: SharedProcessLifecycleService | undefined = undefined;
143
144
private readonly onDidWindowConnectRaw = this._register(new Emitter<MessagePortMain>());
145
146
constructor(private configuration: ISharedProcessConfiguration) {
147
super();
148
149
this.registerListeners();
150
}
151
152
private registerListeners(): void {
153
154
// Shared process lifecycle
155
let didExit = false;
156
const onExit = () => {
157
if (!didExit) {
158
didExit = true;
159
160
this.lifecycleService?.fireOnWillShutdown();
161
this.dispose();
162
}
163
};
164
process.once('exit', onExit);
165
once(process.parentPort, SharedProcessLifecycle.exit, onExit);
166
}
167
168
async init(): Promise<void> {
169
170
// Services
171
const instantiationService = await this.initServices();
172
173
// Config
174
registerUserDataSyncConfiguration();
175
176
instantiationService.invokeFunction(accessor => {
177
const logService = accessor.get(ILogService);
178
const telemetryService = accessor.get(ITelemetryService);
179
180
// Log info
181
logService.trace('sharedProcess configuration', JSON.stringify(this.configuration));
182
183
// Channels
184
this.initChannels(accessor);
185
186
// Error handler
187
this.registerErrorHandler(logService);
188
189
// Report Client OS/DE Info
190
this.reportClientOSInfo(telemetryService, logService);
191
});
192
193
// Instantiate Contributions
194
this._register(combinedDisposable(
195
instantiationService.createInstance(CodeCacheCleaner, this.configuration.codeCachePath),
196
instantiationService.createInstance(LanguagePackCachedDataCleaner),
197
instantiationService.createInstance(UnusedWorkspaceStorageDataCleaner),
198
instantiationService.createInstance(LogsDataCleaner),
199
instantiationService.createInstance(LocalizationsUpdater),
200
instantiationService.createInstance(ExtensionsContributions),
201
instantiationService.createInstance(UserDataProfilesCleaner),
202
instantiationService.createInstance(DefaultExtensionsInitializer)
203
));
204
}
205
206
private async initServices(): Promise<IInstantiationService> {
207
const services = new ServiceCollection();
208
209
// Product
210
const productService = { _serviceBrand: undefined, ...product };
211
services.set(IProductService, productService);
212
213
// Main Process
214
const mainRouter = new StaticRouter(ctx => ctx === 'main');
215
const mainProcessService = new MainProcessService(this.server, mainRouter);
216
services.set(IMainProcessService, mainProcessService);
217
218
// Policies
219
const policyService = this.configuration.policiesData ? new PolicyChannelClient(this.configuration.policiesData, mainProcessService.getChannel('policy')) : new NullPolicyService();
220
services.set(IPolicyService, policyService);
221
222
// Environment
223
const environmentService = new NativeEnvironmentService(this.configuration.args, productService);
224
services.set(INativeEnvironmentService, environmentService);
225
226
// Logger
227
const loggerService = new LoggerChannelClient(undefined, this.configuration.logLevel, environmentService.logsHome, this.configuration.loggers.map(loggerResource => ({ ...loggerResource, resource: URI.revive(loggerResource.resource) })), mainProcessService.getChannel('logger'));
228
services.set(ILoggerService, loggerService);
229
230
// Log
231
const sharedLogGroup: LoggerGroup = { id: 'shared', name: localize('sharedLog', "Shared") };
232
const logger = this._register(loggerService.createLogger('sharedprocess', { name: localize('sharedLog', "Shared"), group: sharedLogGroup }));
233
const consoleLogger = this._register(new ConsoleLogger(logger.getLevel()));
234
const logService = this._register(new LogService(logger, [consoleLogger]));
235
services.set(ILogService, logService);
236
237
// Lifecycle
238
this.lifecycleService = this._register(new SharedProcessLifecycleService(logService));
239
services.set(ISharedProcessLifecycleService, this.lifecycleService);
240
241
// Files
242
const fileService = this._register(new FileService(logService));
243
services.set(IFileService, fileService);
244
245
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService));
246
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
247
248
// URI Identity
249
const uriIdentityService = new UriIdentityService(fileService);
250
services.set(IUriIdentityService, uriIdentityService);
251
252
// User Data Profiles
253
const userDataProfilesService = this._register(new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles')));
254
services.set(IUserDataProfilesService, userDataProfilesService);
255
256
const userDataFileSystemProvider = this._register(new FileUserDataProvider(
257
Schemas.file,
258
// Specifically for user data, use the disk file system provider
259
// from the main process to enable atomic read/write operations.
260
// Since user data can change very frequently across multiple
261
// processes, we want a single process handling these operations.
262
this._register(new DiskFileSystemProviderClient(mainProcessService.getChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME), { pathCaseSensitive: isLinux })),
263
Schemas.vscodeUserData,
264
userDataProfilesService,
265
uriIdentityService,
266
logService
267
));
268
fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider);
269
270
// Configuration
271
const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService));
272
services.set(IConfigurationService, configurationService);
273
274
// Storage (global access only)
275
const storageService = new RemoteStorageService(undefined, { defaultProfile: userDataProfilesService.defaultProfile, currentProfile: userDataProfilesService.defaultProfile }, mainProcessService, environmentService);
276
services.set(IStorageService, storageService);
277
this._register(toDisposable(() => storageService.flush()));
278
279
// Initialize config & storage in parallel
280
await Promise.all([
281
configurationService.initialize(),
282
storageService.initialize()
283
]);
284
285
// Request
286
const networkLogger = this._register(loggerService.createLogger(`network-shared`, { name: localize('networkk', "Network"), group: sharedLogGroup }));
287
const requestService = new RequestService(configurationService, environmentService, this._register(new LogService(networkLogger)));
288
services.set(IRequestService, requestService);
289
290
// Checksum
291
services.set(IChecksumService, new SyncDescriptor(ChecksumService, undefined, false /* proxied to other processes */));
292
293
// V8 Inspect profiler
294
services.set(IV8InspectProfilingService, new SyncDescriptor(V8InspectProfilingService, undefined, false /* proxied to other processes */));
295
296
// Native Host
297
const nativeHostService = new NativeHostService(-1 /* we are not running in a browser window context */, mainProcessService) as INativeHostService;
298
services.set(INativeHostService, nativeHostService);
299
300
// Metered Connection
301
const meteredConnectionService = this._register(new MeteredConnectionChannelClient(mainProcessService.getChannel(METERED_CONNECTION_CHANNEL)));
302
services.set(IMeteredConnectionService, meteredConnectionService);
303
304
// Download
305
services.set(IDownloadService, new SyncDescriptor(DownloadService, undefined, true));
306
307
// Extension recommendations
308
const activeWindowManager = this._register(new ActiveWindowManager(nativeHostService));
309
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
310
services.set(IExtensionRecommendationNotificationService, new ExtensionRecommendationNotificationServiceChannelClient(this.server.getChannel('extensionRecommendationNotification', activeWindowRouter)));
311
312
// Telemetry
313
let telemetryService: ITelemetryService;
314
const appenders: ITelemetryAppender[] = [];
315
const internalTelemetry = isInternalTelemetry(productService, configurationService);
316
if (supportsTelemetry(productService, environmentService)) {
317
const logAppender = new TelemetryLogAppender('', false, loggerService, environmentService, productService);
318
appenders.push(logAppender);
319
if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) {
320
const collectorAppender = new OneDataSystemAppender(requestService, internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey);
321
this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data
322
appenders.push(collectorAppender);
323
}
324
325
telemetryService = new TelemetryService({
326
appenders,
327
commonProperties: resolveCommonProperties(release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, this.configuration.sqmId, this.configuration.devDeviceId, internalTelemetry, productService.date),
328
sendErrorTelemetry: true,
329
piiPaths: getPiiPathsFromEnvironment(environmentService),
330
meteredConnectionService,
331
}, configurationService, productService);
332
} else {
333
telemetryService = NullTelemetryService;
334
const nullAppender = NullAppender;
335
appenders.push(nullAppender);
336
}
337
338
this.server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appenders));
339
services.set(ITelemetryService, telemetryService);
340
341
// Custom Endpoint Telemetry
342
const customEndpointTelemetryService = new CustomEndpointTelemetryService(configurationService, telemetryService, loggerService, environmentService, productService);
343
services.set(ICustomEndpointTelemetryService, customEndpointTelemetryService);
344
345
// Extension Management
346
services.set(IExtensionsProfileScannerService, new SyncDescriptor(ExtensionsProfileScannerService, undefined, true));
347
services.set(IExtensionsScannerService, new SyncDescriptor(ExtensionsScannerService, undefined, true));
348
services.set(IExtensionSignatureVerificationService, new SyncDescriptor(ExtensionSignatureVerificationService, undefined, true));
349
services.set(IAllowedExtensionsService, new SyncDescriptor(AllowedExtensionsService, undefined, true));
350
services.set(INativeServerExtensionManagementService, new SyncDescriptor(ExtensionManagementService, undefined, true));
351
352
// MCP Management
353
services.set(IAllowedMcpServersService, new SyncDescriptor(AllowedMcpServersService, undefined, true));
354
services.set(IMcpGalleryManifestService, new McpGalleryManifestIPCService(this.server));
355
services.set(IMcpGalleryService, new SyncDescriptor(McpGalleryService, undefined, true));
356
services.set(IMcpResourceScannerService, new SyncDescriptor(McpResourceScannerService, undefined, true));
357
services.set(IMcpManagementService, new SyncDescriptor(McpManagementService, undefined, true));
358
359
// Extension Gallery
360
services.set(IExtensionGalleryManifestService, new ExtensionGalleryManifestIPCService(this.server, productService));
361
services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService, undefined, true));
362
363
// Extension Tips
364
services.set(IExtensionTipsService, new SyncDescriptor(ExtensionTipsService, undefined, false /* Eagerly scans and computes exe based recommendations */));
365
366
// Localizations
367
services.set(ILanguagePackService, new SyncDescriptor(NativeLanguagePackService, undefined, false /* proxied to other processes */));
368
369
// Diagnostics
370
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService, undefined, false /* proxied to other processes */));
371
372
// Settings Sync
373
services.set(IUserDataSyncAccountService, new SyncDescriptor(UserDataSyncAccountService, undefined, true));
374
services.set(IUserDataSyncLogService, new SyncDescriptor(UserDataSyncLogService, undefined, true));
375
services.set(IUserDataSyncUtilService, ProxyChannel.toService(this.server.getChannel('userDataSyncUtil', client => client.ctx !== 'main')));
376
services.set(IGlobalExtensionEnablementService, new SyncDescriptor(GlobalExtensionEnablementService, undefined, false /* Eagerly resets installed extensions */));
377
services.set(IIgnoredExtensionsManagementService, new SyncDescriptor(IgnoredExtensionsManagementService, undefined, true));
378
services.set(IExtensionStorageService, new SyncDescriptor(ExtensionStorageService));
379
services.set(IUserDataSyncStoreManagementService, new SyncDescriptor(UserDataSyncStoreManagementService, undefined, true));
380
services.set(IUserDataSyncStoreService, new SyncDescriptor(UserDataSyncStoreService, undefined, true));
381
services.set(IUserDataSyncMachinesService, new SyncDescriptor(UserDataSyncMachinesService, undefined, true));
382
services.set(IUserDataSyncLocalStoreService, new SyncDescriptor(UserDataSyncLocalStoreService, undefined, false /* Eagerly cleans up old backups */));
383
services.set(IUserDataSyncEnablementService, new SyncDescriptor(UserDataSyncEnablementService, undefined, true));
384
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService, undefined, false /* Initializes the Sync State */));
385
services.set(IUserDataProfileStorageService, new SyncDescriptor(SharedProcessUserDataProfileStorageService, undefined, true));
386
services.set(IUserDataSyncResourceProviderService, new SyncDescriptor(UserDataSyncResourceProviderService, undefined, true));
387
388
// Signing
389
services.set(ISignService, new SyncDescriptor(SignService, undefined, false /* proxied to other processes */));
390
391
// Tunnel
392
const remoteSocketFactoryService = new RemoteSocketFactoryService();
393
services.set(IRemoteSocketFactoryService, remoteSocketFactoryService);
394
remoteSocketFactoryService.register(RemoteConnectionType.WebSocket, nodeSocketFactory);
395
services.set(ISharedTunnelsService, new SyncDescriptor(SharedTunnelsService));
396
services.set(ISharedProcessTunnelService, new SyncDescriptor(SharedProcessTunnelService));
397
398
// Remote Tunnel
399
services.set(IRemoteTunnelService, new SyncDescriptor(RemoteTunnelService));
400
401
// Web Content Extractor
402
services.set(ISharedWebContentExtractorService, new SyncDescriptor(SharedWebContentExtractorService));
403
404
return new InstantiationService(services);
405
}
406
407
private initChannels(accessor: ServicesAccessor): void {
408
409
// Extensions Management
410
const channel = new ExtensionManagementChannel(accessor.get(IExtensionManagementService), () => null);
411
this.server.registerChannel('extensions', channel);
412
413
// Mcp Management
414
const mcpManagementChannel = new McpManagementChannel(accessor.get(IMcpManagementService), () => null);
415
this.server.registerChannel('mcpManagement', mcpManagementChannel);
416
417
// Language Packs
418
const languagePacksChannel = ProxyChannel.fromService(accessor.get(ILanguagePackService), this._store);
419
this.server.registerChannel('languagePacks', languagePacksChannel);
420
421
// Diagnostics
422
const diagnosticsChannel = ProxyChannel.fromService(accessor.get(IDiagnosticsService), this._store);
423
this.server.registerChannel('diagnostics', diagnosticsChannel);
424
425
// Extension Tips
426
const extensionTipsChannel = new ExtensionTipsChannel(accessor.get(IExtensionTipsService));
427
this.server.registerChannel('extensionTipsService', extensionTipsChannel);
428
429
// Checksum
430
const checksumChannel = ProxyChannel.fromService(accessor.get(IChecksumService), this._store);
431
this.server.registerChannel('checksum', checksumChannel);
432
433
// Profiling
434
const profilingChannel = ProxyChannel.fromService(accessor.get(IV8InspectProfilingService), this._store);
435
this.server.registerChannel('v8InspectProfiling', profilingChannel);
436
437
// Settings Sync
438
const userDataSyncMachineChannel = ProxyChannel.fromService(accessor.get(IUserDataSyncMachinesService), this._store);
439
this.server.registerChannel('userDataSyncMachines', userDataSyncMachineChannel);
440
441
// Custom Endpoint Telemetry
442
const customEndpointTelemetryChannel = ProxyChannel.fromService(accessor.get(ICustomEndpointTelemetryService), this._store);
443
this.server.registerChannel('customEndpointTelemetry', customEndpointTelemetryChannel);
444
445
const userDataSyncAccountChannel = new UserDataSyncAccountServiceChannel(accessor.get(IUserDataSyncAccountService));
446
this.server.registerChannel('userDataSyncAccount', userDataSyncAccountChannel);
447
448
const userDataSyncStoreManagementChannel = new UserDataSyncStoreManagementServiceChannel(accessor.get(IUserDataSyncStoreManagementService));
449
this.server.registerChannel('userDataSyncStoreManagement', userDataSyncStoreManagementChannel);
450
451
const userDataSyncChannel = new UserDataSyncServiceChannel(accessor.get(IUserDataSyncService), accessor.get(IUserDataProfilesService), accessor.get(ILogService));
452
this.server.registerChannel('userDataSync', userDataSyncChannel);
453
454
const userDataAutoSync = this._register(accessor.get(IInstantiationService).createInstance(UserDataAutoSyncService));
455
this.server.registerChannel('userDataAutoSync', ProxyChannel.fromService(userDataAutoSync, this._store));
456
457
this.server.registerChannel('IUserDataSyncResourceProviderService', ProxyChannel.fromService(accessor.get(IUserDataSyncResourceProviderService), this._store));
458
459
// Tunnel
460
const sharedProcessTunnelChannel = ProxyChannel.fromService(accessor.get(ISharedProcessTunnelService), this._store);
461
this.server.registerChannel(ipcSharedProcessTunnelChannelName, sharedProcessTunnelChannel);
462
463
// Remote Tunnel
464
const remoteTunnelChannel = ProxyChannel.fromService(accessor.get(IRemoteTunnelService), this._store);
465
this.server.registerChannel('remoteTunnel', remoteTunnelChannel);
466
467
// Web Content Extractor
468
const webContentExtractorChannel = ProxyChannel.fromService(accessor.get(ISharedWebContentExtractorService), this._store);
469
this.server.registerChannel('sharedWebContentExtractor', webContentExtractorChannel);
470
}
471
472
private registerErrorHandler(logService: ILogService): void {
473
474
// Listen on global error events
475
process.on('uncaughtException', error => onUnexpectedError(error));
476
process.on('unhandledRejection', (reason: unknown) => onUnexpectedError(reason));
477
478
// Install handler for unexpected errors
479
setUnexpectedErrorHandler(error => {
480
const message = toErrorMessage(error, true);
481
if (!message) {
482
return;
483
}
484
485
logService.error(`[uncaught exception in sharedProcess]: ${message}`);
486
});
487
}
488
489
private async reportClientOSInfo(telemetryService: ITelemetryService, logService: ILogService): Promise<void> {
490
if (isLinux) {
491
const [releaseInfo, displayProtocol] = await Promise.all([
492
getOSReleaseInfo(logService.error.bind(logService)),
493
getDisplayProtocol(logService.error.bind(logService))
494
]);
495
const desktopEnvironment = getDesktopEnvironment();
496
const codeSessionType = getCodeDisplayProtocol(displayProtocol, this.configuration.args['ozone-platform']);
497
if (releaseInfo) {
498
type ClientPlatformInfoClassification = {
499
platformId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system without any version information.' };
500
platformVersionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system version excluding any name information or release code.' };
501
platformIdLike: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system the current OS derivate is closely related to.' };
502
desktopEnvironment: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the desktop environment the user is using.' };
503
displayProtocol: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the users display protocol type.' };
504
codeDisplayProtocol: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the vscode display protocol type.' };
505
owner: 'benibenj';
506
comment: 'Provides insight into the distro and desktop environment information on Linux.';
507
};
508
type ClientPlatformInfoEvent = {
509
platformId: string;
510
platformVersionId: string | undefined;
511
platformIdLike: string | undefined;
512
desktopEnvironment: string | undefined;
513
displayProtocol: string | undefined;
514
codeDisplayProtocol: string | undefined;
515
};
516
telemetryService.publicLog2<ClientPlatformInfoEvent, ClientPlatformInfoClassification>('clientPlatformInfo', {
517
platformId: releaseInfo.id,
518
platformVersionId: releaseInfo.version_id,
519
platformIdLike: releaseInfo.id_like,
520
desktopEnvironment: desktopEnvironment,
521
displayProtocol: displayProtocol,
522
codeDisplayProtocol: codeSessionType
523
});
524
}
525
}
526
}
527
528
handledClientConnection(e: MessageEvent): boolean {
529
530
// This filter on message port messages will look for
531
// attempts of a window to connect raw to the shared
532
// process to handle these connections separate from
533
// our IPC based protocol.
534
535
if (e.data !== SharedProcessRawConnection.response) {
536
return false;
537
}
538
539
const port = e.ports.at(0);
540
if (port) {
541
this.onDidWindowConnectRaw.fire(port);
542
543
return true;
544
}
545
546
return false;
547
}
548
}
549
550
export async function main(configuration: ISharedProcessConfiguration): Promise<void> {
551
552
// create shared process and signal back to main that we are
553
// ready to accept message ports as client connections
554
555
try {
556
const sharedProcess = new SharedProcessMain(configuration);
557
process.parentPort.postMessage(SharedProcessLifecycle.ipcReady);
558
559
// await initialization and signal this back to electron-main
560
await sharedProcess.init();
561
562
process.parentPort.postMessage(SharedProcessLifecycle.initDone);
563
} catch (error) {
564
process.parentPort.postMessage({ error: error.toString() });
565
}
566
}
567
568
const handle = setTimeout(() => {
569
process.parentPort.postMessage({ warning: '[SharedProcess] did not receive configuration within 30s...' });
570
}, 30000);
571
572
process.parentPort.once('message', (e: Electron.MessageEvent) => {
573
clearTimeout(handle);
574
main(e.data as ISharedProcessConfiguration);
575
});
576
577