From 8099ff1f33798f01bb94c9be036c5f5f230b687b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 13 Jun 2022 14:31:22 +0200 Subject: [PATCH] implement feedback --- .../sharedProcess/sharedProcessMain.ts | 4 +- src/vs/code/electron-main/main.ts | 20 ++++--- src/vs/code/node/cliProcessMain.ts | 2 +- .../common/configurationService.ts | 32 ++++------- .../test/common/configurationService.test.ts | 54 +++++++++---------- .../environment/common/environment.ts | 1 + .../environment/common/environmentService.ts | 3 ++ .../electron-main/protocolMainService.ts | 2 +- .../electron-main/sharedProcess.ts | 3 +- .../sharedProcess/node/sharedProcess.ts | 5 +- .../state/electron-main/stateMainService.ts | 6 +-- .../storage/electron-main/storageMain.ts | 2 +- .../electron-main/storageMainService.ts | 2 +- .../electron-sandbox/storageService.ts | 2 +- .../userData/common/fileUserDataProvider.ts | 4 +- .../userDataProfile/common/userDataProfile.ts | 15 ++++++ .../test/common/userDataSyncClient.ts | 2 +- src/vs/platform/window/common/window.ts | 5 +- .../electron-main/windowsMainService.ts | 3 +- .../node/remoteExtensionHostAgentCli.ts | 2 +- src/vs/server/node/serverServices.ts | 4 +- .../electron-sandbox/desktop.main.ts | 3 +- .../environment/browser/environmentService.ts | 3 ++ .../electron-browser/workbenchTestServices.ts | 7 ++- 24 files changed, 94 insertions(+), 92 deletions(-) diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index e5081de7797..a02d7747b9c 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -231,11 +231,11 @@ class SharedProcessMain extends Disposable { fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider); // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesService(revive(this.configuration.defaultProfile), revive(this.configuration.currentProfile), environmentService, fileService, logService)); + const userDataProfilesService = this._register(new UserDataProfilesService(revive(this.configuration.profiles.default), revive(this.configuration.profiles.current), environmentService, fileService, logService)); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration - const configurationService = this._register(new ConfigurationService(userDataProfilesService, fileService, policyService, logService)); + const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService)); services.set(IConfigurationService, configurationService); // Storage (global access only) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 5bc3d986af5..9208ce15944 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -173,6 +173,10 @@ class CodeMain { // Logger services.set(ILoggerService, new LoggerService(logService, fileService)); + // State + const stateMainService = new StateMainService(environmentMainService, logService, fileService); + services.set(IStateMainService, stateMainService); + // User Data Profiles const userDataProfilesMainService = new UserDataProfilesMainService(environmentMainService, fileService, logService); services.set(IUserDataProfilesService, userDataProfilesMainService); @@ -184,16 +188,12 @@ class CodeMain { services.set(IPolicyService, policyService); // Configuration - const configurationService = new ConfigurationService(userDataProfilesMainService, fileService, policyService, logService); + const configurationService = new ConfigurationService(userDataProfilesMainService.defaultProfile.settingsResource, fileService, policyService, logService); services.set(IConfigurationService, configurationService); // Lifecycle services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService)); - // State - const stateMainService = new StateMainService(userDataProfilesMainService, logService, fileService); - services.set(IStateMainService, stateMainService); - // Request services.set(IRequestService, new SyncDescriptor(RequestMainService)); @@ -229,10 +229,7 @@ class CodeMain { return instanceEnvironment; } - private async initServices(environmentMainService: IEnvironmentMainService, userDataProfilesMainService: UserDataProfilesMainService, configurationService: ConfigurationService, stateMainService: StateMainService): Promise { - // State service - await stateMainService.init(); - + private initServices(environmentMainService: IEnvironmentMainService, userDataProfilesMainService: UserDataProfilesMainService, configurationService: ConfigurationService, stateMainService: StateMainService): Promise { return Promises.settled([ // Environment service (paths) @@ -246,9 +243,10 @@ class CodeMain { environmentMainService.backupHome ].map(path => path ? FSPromises.mkdir(path, { recursive: true }) : undefined)), + stateMainService.init(), + // User Data Profiles Service - userDataProfilesMainService.init(stateMainService) - .then(() => userDataProfilesMainService.currentProfile.globalStorageHome.fsPath !== userDataProfilesMainService.defaultProfile.globalStorageHome.fsPath ? FSPromises.mkdir(userDataProfilesMainService.currentProfile.globalStorageHome.fsPath, { recursive: true }) : undefined), + userDataProfilesMainService.init(stateMainService), // Configuration service configurationService.initialize() diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index ccfab39f2c4..e8895029080 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -145,7 +145,7 @@ class CliMain extends Disposable { services.set(IPolicyService, policyService); // Configuration - const configurationService = this._register(new ConfigurationService(userDataProfilesService, fileService, policyService, logService)); + const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService)); services.set(IConfigurationService, configurationService); // Init config diff --git a/src/vs/platform/configuration/common/configurationService.ts b/src/vs/platform/configuration/common/configurationService.ts index af758ed4512..99da4050566 100644 --- a/src/vs/platform/configuration/common/configurationService.ts +++ b/src/vs/platform/configuration/common/configurationService.ts @@ -5,14 +5,13 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ConfigurationTarget, IConfigurationChange, IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService, IConfigurationValue, isConfigurationOverrides } from 'vs/platform/configuration/common/configuration'; import { Configuration, ConfigurationChangeEvent, ConfigurationModel, UserSettings } from 'vs/platform/configuration/common/configurationModels'; import { DefaultConfiguration, IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations'; import { IFileService } from 'vs/platform/files/common/files'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ILogService } from 'vs/platform/log/common/log'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; @@ -21,42 +20,35 @@ export class ConfigurationService extends Disposable implements IConfigurationSe declare readonly _serviceBrand: undefined; private configuration: Configuration; - private readonly userConfiguration: MutableDisposable; private readonly defaultConfiguration: DefaultConfiguration; private readonly policyConfiguration: IPolicyConfiguration; + private readonly userConfiguration: UserSettings; private readonly reloadConfigurationScheduler: RunOnceScheduler; private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; constructor( - private readonly userDataProfilesService: IUserDataProfilesService, - private readonly fileService: IFileService, + private readonly settingsResource: URI, + fileService: IFileService, policyService: IPolicyService, logService: ILogService, ) { super(); this.defaultConfiguration = this._register(new DefaultConfiguration()); this.policyConfiguration = policyService instanceof NullPolicyService ? new NullPolicyConfiguration() : this._register(new PolicyConfiguration(this.defaultConfiguration, policyService, logService)); + this.userConfiguration = this._register(new UserSettings(this.settingsResource, undefined, extUriBiasedIgnorePathCase, fileService)); this.configuration = new Configuration(this.defaultConfiguration.configurationModel, this.policyConfiguration.configurationModel, new ConfigurationModel()); - this.userConfiguration = this._register(new MutableDisposable()); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reloadConfiguration(), 50)); this._register(this.defaultConfiguration.onDidChangeConfiguration(({ defaults, properties }) => this.onDidDefaultConfigurationChange(defaults, properties))); this._register(this.policyConfiguration.onDidChangeConfiguration(model => this.onDidPolicyConfigurationChange(model))); + this._register(this.userConfiguration.onDidChange(() => this.reloadConfigurationScheduler.schedule())); } - private initPromise: Promise | undefined; - initialize(settingsResource?: URI): Promise { - if (!this.initPromise) { - this.initPromise = (async () => { - this.userConfiguration.value = new UserSettings(settingsResource ?? this.userDataProfilesService.currentProfile.settingsResource, undefined, extUriBiasedIgnorePathCase, this.fileService); - this._register(this.userConfiguration.value.onDidChange(() => this.reloadConfigurationScheduler.schedule())); - const [defaultModel, policyModel, userModel] = await Promise.all([this.defaultConfiguration.initialize(), this.policyConfiguration.initialize(), this.userConfiguration.value.loadConfiguration()]); - this.configuration = new Configuration(defaultModel, policyModel, userModel); - })(); - } - return this.initPromise; + async initialize(): Promise { + const [defaultModel, policyModel, userModel] = await Promise.all([this.defaultConfiguration.initialize(), this.policyConfiguration.initialize(), this.userConfiguration.loadConfiguration()]); + this.configuration = new Configuration(defaultModel, policyModel, userModel); } getConfigurationData(): IConfigurationData { @@ -95,10 +87,8 @@ export class ConfigurationService extends Disposable implements IConfigurationSe } async reloadConfiguration(): Promise { - if (this.userConfiguration.value) { - const configurationModel = await this.userConfiguration.value.loadConfiguration(); - this.onDidChangeUserConfiguration(configurationModel); - } + const configurationModel = await this.userConfiguration.loadConfiguration(); + this.onDidChangeUserConfiguration(configurationModel); } private onDidChangeUserConfiguration(userConfigurationModel: ConfigurationModel): void { diff --git a/src/vs/platform/configuration/test/common/configurationService.test.ts b/src/vs/platform/configuration/test/common/configurationService.test.ts index 7379ee38204..451a52e4917 100644 --- a/src/vs/platform/configuration/test/common/configurationService.test.ts +++ b/src/vs/platform/configuration/test/common/configurationService.test.ts @@ -12,34 +12,31 @@ import { URI } from 'vs/base/common/uri'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { ConfigurationService } from 'vs/platform/configuration/common/configurationService'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; import { NullLogService } from 'vs/platform/log/common/log'; import { NullPolicyService } from 'vs/platform/policy/common/policy'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; - suite('ConfigurationService', () => { let fileService: IFileService; - let userDataProfileService: IUserDataProfilesService; + let settingsResource: URI; const disposables: DisposableStore = new DisposableStore(); setup(async () => { fileService = disposables.add(new FileService(new NullLogService())); const diskFileSystemProvider = disposables.add(new InMemoryFileSystemProvider()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - userDataProfileService = new UserDataProfilesService(undefined, undefined, { userRoamingDataHome: URI.file('User') }, fileService, new NullLogService()); + settingsResource = URI.file('settings.json'); }); teardown(() => disposables.clear()); test('simple', async () => { - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); const config = testObject.getValue<{ foo: string; @@ -50,9 +47,9 @@ suite('ConfigurationService', () => { }); test('config gets flattened', async () => { - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }')); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); const config = testObject.getValue<{ testworkbench: { @@ -69,9 +66,9 @@ suite('ConfigurationService', () => { }); test('error case does not explode', async () => { - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString(',,,,')); + await fileService.writeFile(settingsResource, VSBuffer.fromString(',,,,')); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); const config = testObject.getValue<{ foo: string; @@ -81,7 +78,7 @@ suite('ConfigurationService', () => { }); test('missing file does not explode', async () => { - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(URI.file('__testFile'), fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); const config = testObject.getValue<{ foo: string }>(); @@ -90,21 +87,21 @@ suite('ConfigurationService', () => { }); test('trigger configuration change event when file does not exist', async () => { - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); return new Promise((c, e) => { disposables.add(Event.filter(testObject.onDidChangeConfiguration, e => e.source === ConfigurationTarget.USER)(() => { assert.strictEqual(testObject.getValue('foo'), 'bar'); c(); })); - fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "bar" }')).catch(e); + fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')).catch(e); }); }); test('trigger configuration change event when file exists', async () => { - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); await testObject.initialize(); return new Promise((c) => { @@ -112,21 +109,21 @@ suite('ConfigurationService', () => { assert.strictEqual(testObject.getValue('foo'), 'barz'); c(); })); - fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "barz" }')); + fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "barz" }')); }); }); test('reloadConfiguration', async () => { - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); let config = testObject.getValue<{ foo: string; }>(); assert.ok(config); assert.strictEqual(config.foo, 'bar'); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "foo": "changed" }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "changed" }')); // force a reload to get latest await testObject.reloadConfiguration(); @@ -158,23 +155,22 @@ suite('ConfigurationService', () => { } }); - let testObject = disposables.add(new ConfigurationService(new UserDataProfilesService(undefined, undefined, { userRoamingDataHome: URI.file('User1') }, fileService, new NullLogService()), fileService, new NullPolicyService(), new NullLogService())); + let testObject = disposables.add(new ConfigurationService(URI.file('__testFile'), fileService, new NullPolicyService(), new NullLogService())); await testObject.initialize(); let setting = testObject.getValue(); assert.ok(setting); assert.strictEqual(setting.configuration.service.testSetting, 'isSet'); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }')); - testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); - await testObject.initialize(); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }')); + testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); setting = testObject.getValue(); assert.ok(setting); assert.strictEqual(setting.configuration.service.testSetting, 'isSet'); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configuration.service.testSetting": "isChanged" }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "configuration.service.testSetting": "isChanged" }')); await testObject.reloadConfiguration(); setting = testObject.getValue(); @@ -195,7 +191,7 @@ suite('ConfigurationService', () => { } }); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); testObject.initialize(); let res = testObject.inspect('something.missing'); @@ -208,7 +204,7 @@ suite('ConfigurationService', () => { assert.strictEqual(res.value, 'isSet'); assert.strictEqual(res.userValue, undefined); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "lookup.service.testSetting": "bar" }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "lookup.service.testSetting": "bar" }')); await testObject.reloadConfiguration(); res = testObject.inspect('lookup.service.testSetting'); @@ -230,7 +226,7 @@ suite('ConfigurationService', () => { } }); - const testObject = disposables.add(new ConfigurationService(userDataProfileService, fileService, new NullPolicyService(), new NullLogService())); + const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService())); testObject.initialize(); let res = testObject.inspect('lookup.service.testNullSetting'); @@ -238,7 +234,7 @@ suite('ConfigurationService', () => { assert.strictEqual(res.value, null); assert.strictEqual(res.userValue, undefined); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "lookup.service.testNullSetting": null }')); + await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "lookup.service.testNullSetting": null }')); await testObject.reloadConfiguration(); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 06165993fc1..731b51f40eb 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -48,6 +48,7 @@ export interface IEnvironmentService { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // --- user roaming data + stateHome: URI; userRoamingDataHome: URI; keyboardLayoutResource: URI; argvResource: URI; diff --git a/src/vs/platform/environment/common/environmentService.ts b/src/vs/platform/environment/common/environmentService.ts index 702fedb2f29..dc4ab505862 100644 --- a/src/vs/platform/environment/common/environmentService.ts +++ b/src/vs/platform/environment/common/environmentService.ts @@ -59,6 +59,9 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron @memoize get cacheHome(): URI { return URI.file(this.userDataPath); } + @memoize + get stateHome(): URI { return joinPath(this.appSettingsHome, 'globalStorage'); } + @memoize get userRoamingDataHome(): URI { return this.appSettingsHome; } diff --git a/src/vs/platform/protocol/electron-main/protocolMainService.ts b/src/vs/platform/protocol/electron-main/protocolMainService.ts index 9ac374962f6..b6ef8e8018c 100644 --- a/src/vs/platform/protocol/electron-main/protocolMainService.ts +++ b/src/vs/platform/protocol/electron-main/protocolMainService.ts @@ -39,7 +39,7 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ // - storage : all files in global and workspace storage (https://github.com/microsoft/vscode/issues/116735) this.addValidFileRoot(environmentService.appRoot); this.addValidFileRoot(environmentService.extensionsPath); - this.addValidFileRoot(userDataProfilesService.currentProfile.globalStorageHome.fsPath); + this.addValidFileRoot(userDataProfilesService.defaultProfile.globalStorageHome.fsPath); this.addValidFileRoot(environmentService.workspaceStorageHome.fsPath); // Handle protocols diff --git a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts index 6205c49e0fc..81bb26375b2 100644 --- a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts @@ -242,8 +242,7 @@ export class SharedProcess extends Disposable implements ISharedProcess { appRoot: this.environmentMainService.appRoot, codeCachePath: this.environmentMainService.codeCachePath, backupWorkspacesPath: this.environmentMainService.backupWorkspacesPath, - defaultProfile: this.userDataProfilesService.defaultProfile, - currentProfile: this.userDataProfilesService.currentProfile, + profiles: this.userDataProfilesService.serialize(), userEnv: this.userEnv, args: this.environmentMainService.args, logLevel: this.logService.getLevel(), diff --git a/src/vs/platform/sharedProcess/node/sharedProcess.ts b/src/vs/platform/sharedProcess/node/sharedProcess.ts index 20905e14a30..b5656e2d080 100644 --- a/src/vs/platform/sharedProcess/node/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/node/sharedProcess.ts @@ -7,7 +7,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; import { ISandboxConfiguration } from 'vs/base/parts/sandbox/common/sandboxTypes'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { LogLevel } from 'vs/platform/log/common/log'; -import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesDto } from 'vs/platform/userDataProfile/common/userDataProfile'; import { PolicyDefinition, PolicyValue } from 'vs/platform/policy/common/policy'; export interface ISharedProcess { @@ -28,8 +28,7 @@ export interface ISharedProcessConfiguration extends ISandboxConfiguration { readonly backupWorkspacesPath: string; - readonly defaultProfile: IUserDataProfile; - readonly currentProfile: IUserDataProfile; + readonly profiles: IUserDataProfilesDto; readonly policiesData?: IStringDictionary<{ definition: PolicyDefinition; value: PolicyValue }>; } diff --git a/src/vs/platform/state/electron-main/stateMainService.ts b/src/vs/platform/state/electron-main/stateMainService.ts index e351508b049..ee48760719c 100644 --- a/src/vs/platform/state/electron-main/stateMainService.ts +++ b/src/vs/platform/state/electron-main/stateMainService.ts @@ -8,10 +8,10 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { joinPath } from 'vs/base/common/resources'; import { isUndefined, isUndefinedOrNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; type StorageDatabase = { [key: string]: unknown }; @@ -151,12 +151,12 @@ export class StateMainService implements IStateMainService { private static readonly STATE_FILE = 'storage.json'; - private readonly stateFilePath = joinPath(this.userDataProfilesService.defaultProfile.globalStorageHome, StateMainService.STATE_FILE); + private readonly stateFilePath = joinPath(this.environmentService.stateHome, StateMainService.STATE_FILE); private readonly fileStorage: FileStorage; constructor( - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, @ILogService logService: ILogService, @IFileService fileService: IFileService ) { diff --git a/src/vs/platform/storage/electron-main/storageMain.ts b/src/vs/platform/storage/electron-main/storageMain.ts index a23a9d3ae7a..7faf5ee69cd 100644 --- a/src/vs/platform/storage/electron-main/storageMain.ts +++ b/src/vs/platform/storage/electron-main/storageMain.ts @@ -261,7 +261,7 @@ export class GlobalStorageMain extends BaseStorageMain implements IStorageMain { get path(): string | undefined { if (!this.options.useInMemoryStorage) { - return join(this.userDataProfilesService.currentProfile.globalStorageHome.fsPath, GlobalStorageMain.STORAGE_NAME); + return join(this.userDataProfilesService.defaultProfile.globalStorageHome.fsPath, GlobalStorageMain.STORAGE_NAME); } return undefined; diff --git a/src/vs/platform/storage/electron-main/storageMainService.ts b/src/vs/platform/storage/electron-main/storageMainService.ts index c96bb6261cb..3c5e483fcb0 100644 --- a/src/vs/platform/storage/electron-main/storageMainService.ts +++ b/src/vs/platform/storage/electron-main/storageMainService.ts @@ -232,7 +232,7 @@ export class GlobalStorageMainService extends AbstractStorageService implements } protected getLogDetails(scope: StorageScope): string | undefined { - return scope === StorageScope.GLOBAL ? this.userDataProfilesService.currentProfile.globalStorageHome.fsPath : undefined; + return scope === StorageScope.GLOBAL ? this.userDataProfilesService.defaultProfile.globalStorageHome.fsPath : undefined; } protected override shouldFlushWhenIdle(): boolean { diff --git a/src/vs/platform/storage/electron-sandbox/storageService.ts b/src/vs/platform/storage/electron-sandbox/storageService.ts index 95a0a110a9a..fd69b47c141 100644 --- a/src/vs/platform/storage/electron-sandbox/storageService.ts +++ b/src/vs/platform/storage/electron-sandbox/storageService.ts @@ -81,7 +81,7 @@ export class NativeStorageService extends AbstractStorageService { } protected getLogDetails(scope: StorageScope): string | undefined { - return scope === StorageScope.GLOBAL ? this.userDataProfilesService.currentProfile.globalStorageHome.fsPath : this.workspaceStorageId ? `${joinPath(this.environmentService.workspaceStorageHome, this.workspaceStorageId, 'state.vscdb').fsPath}` : undefined; + return scope === StorageScope.GLOBAL ? this.userDataProfilesService.defaultProfile.globalStorageHome.fsPath : this.workspaceStorageId ? `${joinPath(this.environmentService.workspaceStorageHome, this.workspaceStorageId, 'state.vscdb').fsPath}` : undefined; } async close(): Promise { diff --git a/src/vs/platform/userData/common/fileUserDataProvider.ts b/src/vs/platform/userData/common/fileUserDataProvider.ts index b0f5e864a11..6addcd0379c 100644 --- a/src/vs/platform/userData/common/fileUserDataProvider.ts +++ b/src/vs/platform/userData/common/fileUserDataProvider.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Event, Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability } from 'vs/platform/files/common/files'; +import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { CancellationToken } from 'vs/base/common/cancellation'; import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream'; @@ -93,7 +93,7 @@ export class FileUserDataProvider extends Disposable implements } copy(from: URI, to: URI, opts: IFileOverwriteOptions): Promise { - if (this.fileSystemProvider.copy) { + if (hasFileFolderCopyCapability(this.fileSystemProvider)) { return this.fileSystemProvider.copy(this.toFileSystemResource(from), this.toFileSystemResource(to), opts); } throw new Error('copy not supported'); diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 3ccc42c7453..4e62561b9b9 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -7,6 +7,7 @@ import { coalesce } from 'vs/base/common/arrays'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; +import { UriDto } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; @@ -24,6 +25,12 @@ export interface IUserDataProfile { readonly extensionsResource: URI | undefined; } +export type IUserDataProfileDto = UriDto; +export type IUserDataProfilesDto = { + readonly current: IUserDataProfileDto; + readonly default: IUserDataProfileDto; +}; + export const IUserDataProfilesService = createDecorator('IUserDataProfilesService'); export interface IUserDataProfilesService { readonly _serviceBrand: undefined; @@ -38,6 +45,7 @@ export interface IUserDataProfilesService { setProfile(name: string): Promise; getAllProfiles(): Promise; + serialize(): IUserDataProfilesDto; } function reviveProfile(profile: IUserDataProfile, scheme: string): IUserDataProfile { @@ -116,4 +124,11 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf } setProfile(name: string): Promise { throw new Error('Not implemented'); } + + serialize(): IUserDataProfilesDto { + return { + default: this.defaultProfile, + current: this.currentProfile + }; + } } diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts index f3355aa1230..968ba2d0e3c 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts @@ -87,7 +87,7 @@ export class UserDataSyncClient extends Disposable { this.instantiationService.stub(IStorageService, this._register(new InMemoryStorageService())); - const configurationService = this._register(new ConfigurationService(userDataProfilesService, fileService, new NullPolicyService(), logService)); + const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, new NullPolicyService(), logService)); await configurationService.initialize(); this.instantiationService.stub(IConfigurationService, configurationService); this.instantiationService.stub(IUriIdentityService, this.instantiationService.createInstance(UriIdentityService)); diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index 8c3c9b43e4b..c675d3e5b13 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -16,7 +16,7 @@ import { FileType } from 'vs/platform/files/common/files'; import { LogLevel } from 'vs/platform/log/common/log'; import { PolicyDefinition, PolicyValue } from 'vs/platform/policy/common/policy'; import { IPartsSplash } from 'vs/platform/theme/common/themeService'; -import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesDto } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; export const WindowMinimumSize = { @@ -283,8 +283,7 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native execPath: string; backupPath?: string; - defaultProfile: IUserDataProfile; - currentProfile: IUserDataProfile; + profiles: IUserDataProfilesDto; homeDir: string; tmpDir: string; diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index f7fa3c971f3..43375f06971 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1300,8 +1300,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic // loading the window. backupPath: options.emptyWindowBackupInfo ? join(this.environmentMainService.backupHome, options.emptyWindowBackupInfo.backupFolder) : undefined, - defaultProfile: this.userDataProfilesService.defaultProfile, - currentProfile: this.userDataProfilesService.currentProfile, + profiles: this.userDataProfilesService.serialize(), homeDir: this.environmentMainService.userHome.fsPath, tmpDir: this.environmentMainService.tmpDir.fsPath, diff --git a/src/vs/server/node/remoteExtensionHostAgentCli.ts b/src/vs/server/node/remoteExtensionHostAgentCli.ts index b32c221dfea..f862fc4a7be 100644 --- a/src/vs/server/node/remoteExtensionHostAgentCli.ts +++ b/src/vs/server/node/remoteExtensionHostAgentCli.ts @@ -98,7 +98,7 @@ class CliMain extends Disposable { services.set(IUserDataProfilesService, userDataProfilesService); // Configuration - const configurationService = this._register(new ConfigurationService(userDataProfilesService, fileService, new NullPolicyService(), logService)); + const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, new NullPolicyService(), logService)); await configurationService.initialize(); services.set(IConfigurationService, configurationService); diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index 3b6aa999830..4f5a7eb718c 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -112,9 +112,9 @@ export async function setupServerServices(connectionToken: ServerConnectionToken // Configuration const userDataProfilesService = new UserDataProfilesService(undefined, undefined, environmentService, fileService, logService); - const configurationService = new ConfigurationService(userDataProfilesService, fileService, new NullPolicyService(), logService); + const configurationService = new ConfigurationService(environmentService.machineSettingsResource, fileService, new NullPolicyService(), logService); services.set(IConfigurationService, configurationService); - configurationService.initialize(environmentService.machineSettingsResource); + await configurationService.initialize(); const extensionHostStatusService = new ExtensionHostStatusService(); services.set(IExtensionHostStatusService, extensionHostStatusService); diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 9a9dfb9f89f..2dd345d1d19 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -54,6 +54,7 @@ import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/use import { UserDataProfilesNativeService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfile'; import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; +import { revive } from 'vs/base/common/marshalling'; export class DesktopMain extends Disposable { @@ -239,7 +240,7 @@ export class DesktopMain extends Disposable { serviceCollection.set(IUriIdentityService, uriIdentityService); // User Data Profiles - const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.defaultProfile, this.configuration.currentProfile, mainProcessService.getChannel('userDataProfiles'), environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesNativeService(revive(this.configuration.profiles.default), revive(this.configuration.profiles.current), mainProcessService.getChannel('userDataProfiles'), environmentService, fileService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index e2d3658fa8c..9cf0aad1bf9 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -67,6 +67,9 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi @memoize get localHistoryHome(): URI { return joinPath(this.userRoamingDataHome, 'History'); } + @memoize + get stateHome(): URI { return joinPath(this.userRoamingDataHome, 'State'); } + /** * In Web every workspace can potentially have scoped user-data * and/or extensions and if Sync state is shared then it can make diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index a98d8000e8c..9680287b287 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -48,14 +48,14 @@ import { IElevatedFileService } from 'vs/workbench/services/files/common/elevate import { IDecorationsService } from 'vs/workbench/services/decorations/common/decorations'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IPartsSplash } from 'vs/platform/theme/common/themeService'; -import { IUserDataProfile, IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { FileService } from 'vs/platform/files/common/fileService'; import { joinPath } from 'vs/base/common/resources'; const args = parseArgs(process.argv, OPTIONS); const homeDir = homedir(); -const NULL_PROFILE: IUserDataProfile = { +const NULL_PROFILE = { name: '', location: URI.file(homeDir), settingsResource: joinPath(URI.file(homeDir), 'settings.json'), @@ -81,8 +81,7 @@ export const TestNativeWindowConfiguration: INativeWindowConfiguration = { homeDir: homeDir, tmpDir: tmpdir(), userDataDir: getUserDataPath(args), - defaultProfile: NULL_PROFILE, - currentProfile: NULL_PROFILE, + profiles: { current: NULL_PROFILE, default: NULL_PROFILE }, ...args };