Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View File

@@ -3,14 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./media/shell';
import * as platform from 'vs/base/common/platform';
import * as perf from 'vs/base/common/performance';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import * as errors from 'vs/base/common/errors';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import product from 'vs/platform/node/product';
@@ -19,8 +17,8 @@ import pkg from 'vs/platform/node/package';
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService, configurationTelemetry, LogAppender, combinedAppender } from 'vs/platform/telemetry/common/telemetryUtils';
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { NullTelemetryService, configurationTelemetry, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
@@ -42,11 +40,10 @@ import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ILifecycleService, LifecyclePhase, ShutdownReason, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { InstantiationService } from 'vs/platform/instantiation/node/instantiationService';
import { ILifecycleService, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ISearchService, ISearchHistoryService } from 'vs/platform/search/common/search';
@@ -58,19 +55,17 @@ import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/work
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/common/ipc';
import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/node/ipc';
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
import { DefaultURITransformer } from 'vs/base/common/uriIpc';
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc';
import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
import * as browser from 'vs/base/browser/browser';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
import { registerThemingParticipant, ITheme, ICssStyleCollector, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
@@ -80,10 +75,11 @@ import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/elect
import { HashService } from 'vs/workbench/services/hash/node/hashService';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
import { ILogService } from 'vs/platform/log/common/log';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { DelegatingStorageService } from 'vs/platform/storage/node/storageService';
import { Event, Emitter } from 'vs/base/common/event';
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
import { stat } from 'fs';
import { join } from 'path';
import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc';
import { LocalizationsChannelClient } from 'vs/platform/localizations/node/localizationsIpc';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue';
import { WorkbenchIssueService } from 'vs/workbench/services/issue/electron-browser/workbenchIssueService';
@@ -91,13 +87,24 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { DialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
import { DialogChannel } from 'vs/platform/dialogs/common/dialogIpc';
import { EventType, addDisposableListener, addClass } from 'vs/base/browser/dom';
import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc';
import { EventType, addDisposableListener, addClass, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { IRemoteAgentService } from 'vs/workbench/services/remote/node/remoteAgentService';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { OpenerService } from 'vs/editor/browser/services/openerService';
import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService';
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement';
import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc';
import { ILabelService, LabelService } from 'vs/platform/label/common/label';
import { IDownloadService } from 'vs/platform/download/common/download';
import { DownloadService } from 'vs/platform/download/node/downloadService';
import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc';
import { TextResourcePropertiesService } from 'vs/workbench/services/textfile/electron-browser/textResourcePropertiesService';
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/node/multiExtensionManagement';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService';
// {{SQL CARBON EDIT}}
import { FileTelemetryService } from 'sql/workbench/services/telemetry/node/fileTelemetryService';
@@ -110,8 +117,7 @@ export interface ICoreServices {
configurationService: IConfigurationService;
environmentService: IEnvironmentService;
logService: ILogService;
timerService: ITimerService;
storageService: IStorageService;
storageService: DelegatingStorageService;
}
/**
@@ -119,15 +125,17 @@ export interface ICoreServices {
* With the Shell being the top level element in the page, it is also responsible for driving the layouting.
*/
export class WorkbenchShell extends Disposable {
private storageService: IStorageService;
private readonly _onWillShutdown = this._register(new Emitter<WillShutdownEvent>());
get onWillShutdown(): Event<WillShutdownEvent> { return this._onWillShutdown.event; }
private storageService: DelegatingStorageService;
private environmentService: IEnvironmentService;
private logService: ILogService;
private configurationService: IConfigurationService;
private contextService: IWorkspaceContextService;
private telemetryService: ITelemetryService;
private extensionService: ExtensionService;
private broadcastService: IBroadcastService;
private timerService: ITimerService;
private themeService: WorkbenchThemeService;
private lifecycleService: LifecycleService;
private mainProcessServices: ServiceCollection;
@@ -151,7 +159,6 @@ export class WorkbenchShell extends Disposable {
this.configurationService = coreServices.configurationService;
this.environmentService = coreServices.environmentService;
this.logService = coreServices.logService;
this.timerService = coreServices.timerService;
this.storageService = coreServices.storageService;
this.mainProcessServices = mainProcessServices;
@@ -160,12 +167,20 @@ export class WorkbenchShell extends Disposable {
}
private renderContents(): void {
// ARIA
aria.setARIAContainer(document.body);
// Instantiation service with services
const [instantiationService, serviceCollection] = this.initServiceCollection(this.container);
// Warm up font cache information before building up too many dom elements
restoreFontInfo(this.storageService);
readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
this._register(this.storageService.onWillSaveState(() => {
saveFontInfo(this.storageService); // Keep font info for next startup around
}));
// Workbench
this.workbench = this.createWorkbench(instantiationService, serviceCollection, this.container);
@@ -177,53 +192,42 @@ export class WorkbenchShell extends Disposable {
this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
}, 10000);
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
this.lifecycleService.when(LifecyclePhase.Restored).then(() => {
clearTimeout(timeoutHandle);
});
}
private createWorkbench(instantiationService: IInstantiationService, serviceCollection: ServiceCollection, container: HTMLElement): Workbench {
function handleStartupError(logService: ILogService, error: Error): void {
// Log it
logService.error(toErrorMessage(error, true));
// Rethrow
throw error;
}
try {
const workbench = instantiationService.createInstance(Workbench, container, this.configuration, serviceCollection, this.lifecycleService, this.mainProcessClient);
// Set lifecycle phase to `Restoring`
this.lifecycleService.phase = LifecyclePhase.Restoring;
// Startup Workbench
workbench.startup().done(startupInfos => {
// Set lifecycle phase to `Runnning` so that other contributions can now do something
this.lifecycleService.phase = LifecyclePhase.Running;
workbench.startup().then(startupInfos => {
// Startup Telemetry
this.logStartupTelemetry(startupInfos);
// Set lifecycle phase to `Runnning For A Bit` after a short delay
let eventuallPhaseTimeoutHandle = setTimeout(() => {
eventuallPhaseTimeoutHandle = void 0;
this.lifecycleService.phase = LifecyclePhase.Eventually;
}, 3000);
this._register(toDisposable(() => {
if (eventuallPhaseTimeoutHandle) {
clearTimeout(eventuallPhaseTimeoutHandle);
}
}));
// localStorage metrics (TODO@Ben remove me later)
if (!this.environmentService.extensionTestsPath && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
this.logLocalStorageMetrics();
// Storage Telemetry (TODO@Ben remove me later, including storage errors)
if (!this.environmentService.extensionTestsPath) {
this.logStorageTelemetry();
}
});
}, error => handleStartupError(this.logService, error));
return workbench;
} catch (error) {
handleStartupError(this.logService, error);
// Log it
this.logService.error(toErrorMessage(error, true));
// Rethrow
throw error;
return void 0;
}
}
@@ -272,9 +276,9 @@ export class WorkbenchShell extends Disposable {
// {{SQL CARBON EDIT}}
private sendUsageEvents(): void {
const dailyLastUseDate = Date.parse(this.storageService.get('telemetry.dailyLastUseDate'));
const weeklyLastUseDate = Date.parse(this.storageService.get('telemetry.weeklyLastUseDate'));
const monthlyLastUseDate = Date.parse(this.storageService.get('telemetry.monthlyLastUseDate'));
const dailyLastUseDate = Date.parse(this.storageService.get('telemetry.dailyLastUseDate', StorageScope.GLOBAL, '0'));
const weeklyLastUseDate = Date.parse(this.storageService.get('telemetry.weeklyLastUseDate', StorageScope.GLOBAL, '0'));
const monthlyLastUseDate = Date.parse(this.storageService.get('telemetry.monthlyLastUseDate', StorageScope.GLOBAL, '0'));
let today = new Date().toUTCString();
@@ -282,68 +286,124 @@ export class WorkbenchShell extends Disposable {
if (this.diffInDays(Date.parse(today), dailyLastUseDate) >= 1) {
// daily first use
this.telemetryService.publicLog('telemetry.dailyFirstUse', { dailyFirstUse: true });
this.storageService.store('telemetry.dailyLastUseDate', today);
this.storageService.store('telemetry.dailyLastUseDate', today, StorageScope.GLOBAL);
}
// weekly user event
if (this.diffInDays(Date.parse(today), weeklyLastUseDate) >= 7) {
// weekly first use
this.telemetryService.publicLog('telemetry.weeklyFirstUse', { weeklyFirstUse: true });
this.storageService.store('telemetry.weeklyLastUseDate', today);
this.storageService.store('telemetry.weeklyLastUseDate', today, StorageScope.GLOBAL);
}
// monthly user events
if (this.diffInDays(Date.parse(today), monthlyLastUseDate) >= 30) {
this.telemetryService.publicLog('telemetry.monthlyUse', { monthlyFirstUse: true });
this.storageService.store('telemetry.monthlyLastUseDate', today);
this.storageService.store('telemetry.monthlyLastUseDate', today, StorageScope.GLOBAL);
}
}
private logLocalStorageMetrics(): void {
if (this.lifecycleService.startupKind === StartupKind.ReloadedWindow || this.lifecycleService.startupKind === StartupKind.ReopenedWindow) {
return; // avoid logging localStorage metrics for reload/reopen, we prefer cold startup numbers
}
private logStorageTelemetry(): void {
const initialStartup = !!this.configuration.isInitialStartup;
perf.mark('willReadLocalStorage');
const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend2');
perf.mark('didReadLocalStorage');
const appReadyDuration = initialStartup ? perf.getDuration('main:started', 'main:appReady') : 0;
const workbenchReadyDuration = perf.getDuration(initialStartup ? 'main:started' : 'main:loadWindow', 'didStartWorkbench');
const workspaceStorageRequireDuration = perf.getDuration('willRequireSQLite', 'didRequireSQLite');
const workspaceStorageSchemaDuration = perf.getDuration('willSetupSQLiteSchema', 'didSetupSQLiteSchema');
const globalStorageInitDurationMain = perf.getDuration('main:willInitGlobalStorage', 'main:didInitGlobalStorage');
const globalStorageInitDuratioRenderer = perf.getDuration('willInitGlobalStorage', 'didInitGlobalStorage');
const workspaceStorageInitDuration = perf.getDuration('willInitWorkspaceStorage', 'didInitWorkspaceStorage');
const workspaceStorageFileExistsDuration = perf.getDuration('willCheckWorkspaceStorageExists', 'didCheckWorkspaceStorageExists');
const workspaceStorageMigrationDuration = perf.getDuration('willMigrateWorkspaceStorageKeys', 'didMigrateWorkspaceStorageKeys');
const workbenchLoadDuration = perf.getDuration('willLoadWorkbenchMain', 'didLoadWorkbenchMain');
const localStorageDuration = perf.getDuration('willReadLocalStorage', 'didReadLocalStorage');
if (!readyToSend) {
this.storageService.store('localStorageMetricsReadyToSend2', true);
return; // avoid logging localStorage metrics directly after the update, we prefer cold startup numbers
}
// Handle errors (avoid duplicates to reduce spam)
const loggedStorageErrors = new Set<string>();
this._register(this.storageService.storage.onWorkspaceStorageError(error => {
const errorStr = `${error}`;
if (!this.storageService.getBoolean('localStorageMetricsSent2')) {
perf.mark('willWriteLocalStorage');
this.storageService.store('localStorageMetricsSent2', true);
perf.mark('didWriteLocalStorage');
perf.mark('willStatLocalStorage');
stat(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage'), (error, stat) => {
perf.mark('didStatLocalStorage');
if (!loggedStorageErrors.has(errorStr)) {
loggedStorageErrors.add(errorStr);
/* __GDPR__
"localStorageTimers<NUMBER>" : {
"statTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"accessTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"firstReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"subsequentReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"writeTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"keys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"size": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
"sqliteStorageError<NUMBER>" : {
"appReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbenchReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceExistsTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceMigrationTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceSchemaTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"globalReadTimeMain" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"globalReadTimeRenderer" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"localStorageTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbenchRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceKeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"storageError": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('localStorageTimers2', {
'statTime': perf.getDuration('willStatLocalStorage', 'didStatLocalStorage'),
'accessTime': perf.getDuration('willAccessLocalStorage', 'didAccessLocalStorage'),
'firstReadTime': perf.getDuration('willReadWorkspaceIdentifier', 'didReadWorkspaceIdentifier'),
'subsequentReadTime': perf.getDuration('willReadLocalStorage', 'didReadLocalStorage'),
'writeTime': perf.getDuration('willWriteLocalStorage', 'didWriteLocalStorage'),
'keys': window.localStorage.length,
'size': stat ? stat.size : -1
this.telemetryService.publicLog('sqliteStorageError5', {
'appReadyTime': appReadyDuration,
'workbenchReadyTime': workbenchReadyDuration,
'workspaceExistsTime': workspaceStorageFileExistsDuration,
'workspaceMigrationTime': workspaceStorageMigrationDuration,
'workspaceRequireTime': workspaceStorageRequireDuration,
'workspaceSchemaTime': workspaceStorageSchemaDuration,
'globalReadTimeMain': globalStorageInitDurationMain,
'globalReadTimeRenderer': globalStorageInitDuratioRenderer,
'workspaceReadTime': workspaceStorageInitDuration,
'localStorageTime': localStorageDuration,
'workbenchRequireTime': workbenchLoadDuration,
'workspaceKeys': this.storageService.storage.getSize(StorageScope.WORKSPACE),
'startupKind': this.lifecycleService.startupKind,
'storageError': errorStr
});
});
}
}));
if (this.storageService.storage.hasErrors) {
return; // do not log performance numbers when errors occured
}
if (this.environmentService.verbose) {
return; // do not log when running in verbose mode
}
/* __GDPR__
"sqliteStorageTimers<NUMBER>" : {
"appReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbenchReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceExistsTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceMigrationTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceSchemaTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"globalReadTimeMain" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"globalReadTimeRenderer" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"localStorageTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbenchRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workspaceKeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('sqliteStorageTimers5', {
'appReadyTime': appReadyDuration,
'workbenchReadyTime': workbenchReadyDuration,
'workspaceExistsTime': workspaceStorageFileExistsDuration,
'workspaceMigrationTime': workspaceStorageMigrationDuration,
'workspaceRequireTime': workspaceStorageRequireDuration,
'workspaceSchemaTime': workspaceStorageSchemaDuration,
'globalReadTimeMain': globalStorageInitDurationMain,
'globalReadTimeRenderer': globalStorageInitDuratioRenderer,
'workspaceReadTime': workspaceStorageInitDuration,
'localStorageTime': localStorageDuration,
'workbenchRequireTime': workbenchLoadDuration,
'workspaceKeys': this.storageService.storage.getSize(StorageScope.WORKSPACE),
'startupKind': this.lifecycleService.startupKind
});
}
private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
@@ -351,10 +411,10 @@ export class WorkbenchShell extends Disposable {
serviceCollection.set(IWorkspaceContextService, this.contextService);
serviceCollection.set(IConfigurationService, this.configurationService);
serviceCollection.set(IEnvironmentService, this.environmentService);
serviceCollection.set(ILabelService, new SyncDescriptor(LabelService));
serviceCollection.set(ILogService, this._register(this.logService));
serviceCollection.set(ITimerService, this.timerService);
serviceCollection.set(IStorageService, this.storageService);
this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
serviceCollection.set(serviceIdentifier, serviceInstance);
});
@@ -367,17 +427,14 @@ export class WorkbenchShell extends Disposable {
this.broadcastService = instantiationService.createInstance(BroadcastService, this.configuration.windowId);
serviceCollection.set(IBroadcastService, this.broadcastService);
serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, this.configuration.windowId, this.configuration));
serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, [this.configuration.windowId, this.configuration]));
const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${this.configuration.windowId}`));
sharedProcess
.done(client => client.registerChannel('dialog', instantiationService.createInstance(DialogChannel)));
// Warm up font cache information before building up too many dom elements
restoreFontInfo(this.storageService);
readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
sharedProcess.then(client => {
client.registerChannel('dialog', instantiationService.createInstance(DialogChannel));
});
// Hash
serviceCollection.set(IHashService, new SyncDescriptor(HashService));
@@ -386,9 +443,9 @@ export class WorkbenchShell extends Disposable {
if (this.environmentService.args['perf-test']) {
let telemetryOutput = this.environmentService.args['telemetry-output'];
this.telemetryService = new FileTelemetryService(telemetryOutput);
// Telemetry
} else if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
// Telemetry
} else if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender')));
const config: ITelemetryServiceConfig = {
appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(this.logService)),
commonProperties: resolveWorkbenchCommonProperties(this.storageService, product.commit, pkg.version, this.configuration.machineId, this.environmentService.installSourcePath),
@@ -416,27 +473,37 @@ export class WorkbenchShell extends Disposable {
serviceCollection.set(IDialogService, instantiationService.createInstance(DialogService));
const lifecycleService = instantiationService.createInstance(LifecycleService);
this._register(lifecycleService.onShutdown(reason => this.dispose(reason)));
this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event)));
this._register(lifecycleService.onShutdown(() => this.dispose()));
serviceCollection.set(ILifecycleService, lifecycleService);
this.lifecycleService = lifecycleService;
const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel, DefaultURITransformer);
serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, extensionManagementChannelClient));
serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
serviceCollection.set(IDownloadService, new SyncDescriptor(DownloadService));
serviceCollection.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
const remoteAuthorityResolverService = new RemoteAuthorityResolverService();
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
const remoteAgentService = new RemoteAgentService(this.configuration, this.notificationService, this.environmentService, remoteAuthorityResolverService);
serviceCollection.set(IRemoteAgentService, remoteAgentService);
const remoteAgentConnection = remoteAgentService.getConnection();
if (remoteAgentConnection) {
remoteAgentConnection.registerChannel('dialog', instantiationService.createInstance(DialogChannel));
remoteAgentConnection.registerChannel('download', new DownloadServiceChannel());
remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService));
}
const extensionManagementChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('extensions')));
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel);
serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, [extensionManagementChannelClient]));
serviceCollection.set(IExtensionManagementService, new SyncDescriptor(MulitExtensionManagementService));
const extensionEnablementService = this._register(instantiationService.createInstance(ExtensionEnablementService));
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
this.extensionService = instantiationService.createInstance(ExtensionService);
serviceCollection.set(IExtensionService, this.extensionService);
perf.mark('willLoadExtensions');
this.extensionService.whenInstalledExtensionsRegistered().done(() => {
perf.mark('didLoadExtensions');
});
serviceCollection.set(IExtensionService, instantiationService.createInstance(ExtensionService));
this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
serviceCollection.set(IWorkbenchThemeService, this.themeService);
@@ -447,10 +514,12 @@ export class WorkbenchShell extends Disposable {
serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));
serviceCollection.set(ITextResourcePropertiesService, new SyncDescriptor(TextResourcePropertiesService));
serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
@@ -469,8 +538,8 @@ export class WorkbenchShell extends Disposable {
serviceCollection.set(IIntegrityService, new SyncDescriptor(IntegrityServiceImpl));
const localizationsChannel = getDelayedChannel<ILocalizationsChannel>(sharedProcess.then(c => c.getChannel('localizations')));
serviceCollection.set(ILocalizationsService, new SyncDescriptor(LocalizationsChannelClient, localizationsChannel));
const localizationsChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('localizations')));
serviceCollection.set(ILocalizationsService, new SyncDescriptor(LocalizationsChannelClient, [localizationsChannel]));
return [instantiationService, serviceCollection];
}
@@ -478,9 +547,10 @@ export class WorkbenchShell extends Disposable {
open(): void {
// Listen on unhandled rejection events
window.addEventListener('unhandledrejection', (event) => {
window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) => {
// See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
errors.onUnexpectedError((<any>event).reason);
errors.onUnexpectedError(event.reason);
// Prevent the printing of this event to the console
event.preventDefault();
@@ -502,16 +572,31 @@ export class WorkbenchShell extends Disposable {
// Listeners
this.registerListeners();
// Set lifecycle phase to `Ready`
this.lifecycleService.phase = LifecyclePhase.Ready;
}
private registerListeners(): void {
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true)));
}
// Resize
this._register(addDisposableListener(window, EventType.RESIZE, e => {
if (e.target === window) {
this.layout();
private onWindowResize(e: any, retry: boolean): void {
if (e.target === window) {
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
// TODO@Ben this is an electron issue on macOS when simple fullscreen is enabled
// where for some reason the window clientWidth is reported as 0 when switching
// between simple fullscreen and normal screen. In that case we schedule the layout
// call at the next animation frame once, in the hope that the dimensions are
// proper then.
if (retry) {
scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false));
}
return;
}
}));
this.layout();
}
}
// {{SQL CARBON EDIT}}
@@ -546,20 +631,18 @@ export class WorkbenchShell extends Disposable {
this.workbench.layout();
}
dispose(reason = ShutdownReason.QUIT): void {
dispose(): void {
super.dispose();
// Keep font info for next startup around
saveFontInfo(this.storageService);
// Dispose Workbench
if (this.workbench) {
this.workbench.dispose(reason);
this.workbench.dispose();
}
this.mainProcessClient.dispose();
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
// Foreground