diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 9cf505e2470..7c128863922 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -232,7 +232,7 @@ class SharedProcessMain extends Disposable { fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider); // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesNativeService(this.configuration.profiles, mainProcessService, environmentService, fileService, logService)); + const userDataProfilesService = this._register(new UserDataProfilesNativeService(this.configuration.profiles, mainProcessService, environmentService)); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration diff --git a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts index 8409d699f37..b0a7ec8ad9a 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts @@ -18,6 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; let translations: Translations = Object.create(null); @@ -72,7 +73,7 @@ suite('NativeExtensionsScanerService Test', () => { }); instantiationService.stub(IProductService, { version: '1.66.0' }); instantiationService.stub(IExtensionsProfileScannerService, new ExtensionsProfileScannerService(fileService, logService)); - instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService)); await fileService.createFolder(systemExtensionsLocation); await fileService.createFolder(userExtensionsLocation); }); diff --git a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts index f6a9b0d6993..58fd53e21ec 100644 --- a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts +++ b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts @@ -19,6 +19,7 @@ import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import product from 'vs/platform/product/common/product'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); @@ -52,7 +53,7 @@ suite('FileUserDataProvider', () => { await testObject.createFolder(backupWorkspaceHomeOnDisk); environmentService = new TestEnvironmentService(userDataHomeOnDisk); - userDataProfilesService = new UserDataProfilesService(environmentService, testObject, logService); + userDataProfilesService = new UserDataProfilesService(environmentService, testObject, new UriIdentityService(testObject), logService); fileUserDataProvider = new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService); disposables.add(fileUserDataProvider); diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts index c0cc477ed01..56edfc09480 100644 --- a/src/vs/platform/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -3,20 +3,64 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { revive } from 'vs/base/common/marshalling'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export class BrowserUserDataProfilesService extends UserDataProfilesService implements IUserDataProfilesService { + protected override readonly defaultProfileShouldIncludeExtensionsResourceAlways: boolean = true; + constructor( @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); - this._profiles = [this.createDefaultUserDataProfile(true)]; + super(environmentService, fileService, uriIdentityService, logService); + super.setEnablement(window.localStorage.getItem(PROFILES_ENABLEMENT_CONFIG) === 'true'); + } + + override setEnablement(enabled: boolean): void { + super.setEnablement(enabled); + window.localStorage.setItem(PROFILES_ENABLEMENT_CONFIG, enabled ? 'true' : 'false'); + } + + protected override getStoredProfiles(): StoredUserDataProfile[] { + try { + const value = window.localStorage.getItem(UserDataProfilesService.PROFILES_KEY); + if (value) { + return revive(JSON.parse(value)); + } + } catch (error) { + /* ignore */ + this.logService.error(error); + } + return []; + } + + protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { + window.localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles)); + } + + protected override getStoredProfileAssociations(): StoredProfileAssociations { + try { + const value = window.localStorage.getItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY); + if (value) { + return revive(JSON.parse(value)); + } + } catch (error) { + /* ignore */ + this.logService.error(error); + } + return {}; + } + + protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { + window.localStorage.setItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, JSON.stringify(storedProfileAssociations)); } } diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 89a181cda49..53ab77f58ec 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -14,7 +14,11 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IFileService } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { ResourceMap } from 'vs/base/common/map'; +import { IStringDictionary } from 'vs/base/common/collections'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { Promises } from 'vs/base/common/async'; /** * Flags to indicate whether to use the default profile or not. @@ -66,6 +70,16 @@ export type WorkspaceIdentifier = ISingleFolderWorkspaceIdentifier | IWorkspaceI export type DidChangeProfilesEvent = { readonly added: IUserDataProfile[]; readonly removed: IUserDataProfile[]; readonly all: IUserDataProfile[] }; +export type WillCreateProfileEvent = { + profile: IUserDataProfile; + join(promise: Promise): void; +}; + +export type WillRemoveProfileEvent = { + profile: IUserDataProfile; + join(promise: Promise): void; +}; + export const IUserDataProfilesService = createDecorator('IUserDataProfilesService'); export interface IUserDataProfilesService { readonly _serviceBrand: undefined; @@ -115,34 +129,249 @@ export function toUserDataProfile(name: string, location: URI, useDefaultFlags?: }; } +export type UserDataProfilesObject = { + profiles: IUserDataProfile[]; + workspaces: ResourceMap; + emptyWindow?: IUserDataProfile; +}; + +export type StoredUserDataProfile = { + name: string; + location: URI; + useDefaultFlags?: UseDefaultProfileFlags; +}; + +export type StoredProfileAssociations = { + workspaces?: IStringDictionary; + emptyWindow?: string; +}; + export class UserDataProfilesService extends Disposable implements IUserDataProfilesService { + + protected static readonly PROFILES_KEY = 'userDataProfiles'; + protected static readonly PROFILE_ASSOCIATIONS_KEY = 'profileAssociations'; + readonly _serviceBrand: undefined; + private enabled: boolean = false; + protected readonly defaultProfileShouldIncludeExtensionsResourceAlways: boolean = false; readonly profilesHome: URI; get defaultProfile(): IUserDataProfile { return this.profiles[0]; } - protected _profiles: IUserDataProfile[] = [this.createDefaultUserDataProfile(false)]; - get profiles(): IUserDataProfile[] { return this._profiles; } + get profiles(): IUserDataProfile[] { return this.profilesObject.profiles; } protected readonly _onDidChangeProfiles = this._register(new Emitter()); readonly onDidChangeProfiles = this._onDidChangeProfiles.event; + protected readonly _onWillCreateProfile = this._register(new Emitter()); + readonly onWillCreateProfile = this._onWillCreateProfile.event; + + protected readonly _onWillRemoveProfile = this._register(new Emitter()); + readonly onWillRemoveProfile = this._onWillRemoveProfile.event; + constructor( @IEnvironmentService protected readonly environmentService: IEnvironmentService, @IFileService protected readonly fileService: IFileService, + @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, @ILogService protected readonly logService: ILogService ) { super(); this.profilesHome = joinPath(this.environmentService.userRoamingDataHome, 'profiles'); } - protected createDefaultUserDataProfile(extensions: boolean): IUserDataProfile { - const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); - return { ...profile, isDefault: true, extensionsResource: extensions ? profile.extensionsResource : undefined }; + setEnablement(enabled: boolean): void { + if (this.enabled !== enabled) { + this._profilesObject = undefined; + this.enabled = enabled; + } } - createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } - setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } - getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } - removeProfile(profile: IUserDataProfile): Promise { throw new Error('Not implemented'); } + protected _profilesObject: UserDataProfilesObject | undefined; + protected get profilesObject(): UserDataProfilesObject { + if (!this._profilesObject) { + const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; + let emptyWindow: IUserDataProfile | undefined; + const workspaces = new ResourceMap(); + if (profiles.length) { + const profileAssicaitions = this.getStoredProfileAssociations(); + if (profileAssicaitions.workspaces) { + for (const [workspacePath, profilePath] of Object.entries(profileAssicaitions.workspaces)) { + const workspace = URI.parse(workspacePath); + const profileLocation = URI.parse(profilePath); + const profile = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profileLocation)); + if (profile) { + workspaces.set(workspace, profile); + } + } + } + if (profileAssicaitions.emptyWindow) { + const emptyWindowProfileLocation = URI.parse(profileAssicaitions.emptyWindow); + emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); + } + } + const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); + profiles.unshift({ ...profile, isDefault: true, extensionsResource: this.defaultProfileShouldIncludeExtensionsResourceAlways || profiles.length > 0 ? profile.extensionsResource : undefined }); + this._profilesObject = { profiles, workspaces, emptyWindow }; + } + return this._profilesObject; + } + + getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { + const workspace = this.getWorkspace(workspaceIdentifier); + const profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; + return profile ?? this.defaultProfile; + } + + protected getWorkspace(workspaceIdentifier: WorkspaceIdentifier): URI | EmptyWindowWorkspaceIdentifier { + if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { + return workspaceIdentifier.uri; + } + if (isWorkspaceIdentifier(workspaceIdentifier)) { + return workspaceIdentifier.configPath; + } + return 'empty-window'; + } + + async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + if (this.getStoredProfiles().some(p => p.name === name)) { + throw new Error(`Profile with name ${name} already exists`); + } + + const profile = toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); + await this.fileService.createFolder(profile.location); + + const joiners: Promise[] = []; + this._onWillCreateProfile.fire({ + profile, + join(promise) { + joiners.push(promise); + } + }); + await Promises.settled(joiners); + + this.updateProfiles([profile], []); + + if (workspaceIdentifier) { + await this.setProfileForWorkspace(profile, workspaceIdentifier); + } + + return profile; + } + + async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + + const profile = this.profiles.find(p => p.id === profileToSet.id); + if (!profile) { + throw new Error(`Profile '${profileToSet.name}' does not exist`); + } + + this.updateWorkspaceAssociation(workspaceIdentifier, profile); + } + + async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + this.updateWorkspaceAssociation(workspaceIdentifier); + } + + async removeProfile(profileToRemove: IUserDataProfile): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + if (profileToRemove.isDefault) { + throw new Error('Cannot remove default profile'); + } + const profile = this.profiles.find(p => p.id === profileToRemove.id); + if (!profile) { + throw new Error(`Profile '${profileToRemove.name}' does not exist`); + } + + const joiners: Promise[] = []; + this._onWillRemoveProfile.fire({ + profile, + join(promise) { + joiners.push(promise); + } + }); + await Promises.settled(joiners); + + if (profile.id === this.profilesObject.emptyWindow?.id) { + this.profilesObject.emptyWindow = undefined; + } + for (const workspace of [...this.profilesObject.workspaces.keys()]) { + if (profile.id === this.profilesObject.workspaces.get(workspace)?.id) { + this.profilesObject.workspaces.delete(workspace); + } + } + this.updateStoredProfileAssociations(); + + this.updateProfiles([], [profile]); + + try { + if (this.profiles.length === 1) { + await this.fileService.del(this.profilesHome, { recursive: true }); + } else { + await this.fileService.del(profile.location, { recursive: true }); + } + } catch (error) { + this.logService.error(error); + } + } + + private updateProfiles(added: IUserDataProfile[], removed: IUserDataProfile[]) { + const storedProfiles: StoredUserDataProfile[] = []; + for (const profile of [...this.profilesObject.profiles, ...added]) { + if (profile.isDefault) { + continue; + } + if (removed.some(p => profile.id === p.id)) { + continue; + } + storedProfiles.push({ location: profile.location, name: profile.name, useDefaultFlags: profile.useDefaultFlags }); + } + this.saveStoredProfiles(storedProfiles); + this._profilesObject = undefined; + this._onDidChangeProfiles.fire({ added, removed, all: this.profiles }); + } + + private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile) { + const workspace = this.getWorkspace(workspaceIdentifier); + + // Folder or Multiroot workspace + if (URI.isUri(workspace)) { + this.profilesObject.workspaces.delete(workspace); + if (newProfile && !newProfile.isDefault) { + this.profilesObject.workspaces.set(workspace, newProfile); + } + } + // Empty Window + else { + this.profilesObject.emptyWindow = !newProfile?.isDefault ? newProfile : undefined; + } + + this.updateStoredProfileAssociations(); + } + + private updateStoredProfileAssociations() { + const workspaces: IStringDictionary = {}; + for (const [workspace, profile] of this.profilesObject.workspaces.entries()) { + workspaces[workspace.toString()] = profile.location.toString(); + } + const emptyWindow = this.profilesObject.emptyWindow?.location.toString(); + this.saveStoredProfileAssociations({ workspaces, emptyWindow }); + this._profilesObject = undefined; + } + + protected getStoredProfiles(): StoredUserDataProfile[] { return []; } + protected saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { throw new Error('not implemented'); } + + protected getStoredProfileAssociations(): StoredProfileAssociations { return {}; } + protected saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { throw new Error('not implemented'); } } diff --git a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts index e52855d4867..0ac191f058a 100644 --- a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter, Event } from 'vs/base/common/event'; +import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; @@ -11,22 +11,9 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instant import { ILogService } from 'vs/platform/log/common/log'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier, UseDefaultProfileFlags, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { Promises } from 'vs/base/common/async'; -import { StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; +import { IUserDataProfilesService, WorkspaceIdentifier, StoredUserDataProfile, StoredProfileAssociations, WillCreateProfileEvent, WillRemoveProfileEvent } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; -import { joinPath } from 'vs/base/common/resources'; -import { hash } from 'vs/base/common/hash'; - -export type WillCreateProfileEvent = { - profile: IUserDataProfile; - join(promise: Promise): void; -}; - -export type WillRemoveProfileEvent = { - profile: IUserDataProfile; - join(promise: Promise): void; -}; export const IUserDataProfilesMainService = refineServiceDecorator(IUserDataProfilesService); export interface IUserDataProfilesMainService extends IUserDataProfilesService { @@ -37,12 +24,6 @@ export interface IUserDataProfilesMainService extends IUserDataProfilesService { export class UserDataProfilesMainService extends UserDataProfilesService implements IUserDataProfilesMainService { - private readonly _onWillCreateProfile = this._register(new Emitter()); - readonly onWillCreateProfile = this._onWillCreateProfile.event; - - private readonly _onWillRemoveProfile = this._register(new Emitter()); - readonly onWillRemoveProfile = this._onWillRemoveProfile.event; - constructor( @IStateMainService private readonly stateMainService: IStateMainService, @IUriIdentityService uriIdentityService: IUriIdentityService, @@ -53,141 +34,12 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme super(stateMainService, uriIdentityService, environmentService, fileService, logService); } - override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - if (this.getStoredProfiles().some(p => p.name === name)) { - throw new Error(`Profile with name ${name} already exists`); - } - - const profile = toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); - await this.fileService.createFolder(profile.location); - - const joiners: Promise[] = []; - this._onWillCreateProfile.fire({ - profile, - join(promise) { - joiners.push(promise); - } - }); - await Promises.settled(joiners); - - this.updateProfiles([profile], []); - - if (workspaceIdentifier) { - await this.setProfileForWorkspace(profile, workspaceIdentifier); - } - - return profile; - } - - override async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - - const profile = this.profiles.find(p => p.id === profileToSet.id); - if (!profile) { - throw new Error(`Profile '${profileToSet.name}' does not exist`); - } - - this.updateWorkspaceAssociation(workspaceIdentifier, profile); - } - - async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - this.updateWorkspaceAssociation(workspaceIdentifier); - } - - override async removeProfile(profileToRemove: IUserDataProfile): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - if (profileToRemove.isDefault) { - throw new Error('Cannot remove default profile'); - } - const profile = this.profiles.find(p => p.id === profileToRemove.id); - if (!profile) { - throw new Error(`Profile '${profileToRemove.name}' does not exist`); - } - - const joiners: Promise[] = []; - this._onWillRemoveProfile.fire({ - profile, - join(promise) { - joiners.push(promise); - } - }); - await Promises.settled(joiners); - - if (profile.id === this.profilesObject.emptyWindow?.id) { - this.profilesObject.emptyWindow = undefined; - } - for (const workspace of [...this.profilesObject.workspaces.keys()]) { - if (profile.id === this.profilesObject.workspaces.get(workspace)?.id) { - this.profilesObject.workspaces.delete(workspace); - } - } - this.saveStoredProfileAssociations(); - - this.updateProfiles([], [profile]); - - try { - if (this.profiles.length === 1) { - await this.fileService.del(this.profilesHome, { recursive: true }); - } else { - await this.fileService.del(profile.location, { recursive: true }); - } - } catch (error) { - this.logService.error(error); - } - } - - private updateProfiles(added: IUserDataProfile[], removed: IUserDataProfile[]) { - const storedProfiles: StoredUserDataProfile[] = []; - for (const profile of [...this.profilesObject.profiles, ...added]) { - if (profile.isDefault) { - continue; - } - if (removed.some(p => profile.id === p.id)) { - continue; - } - storedProfiles.push({ location: profile.location, name: profile.name, useDefaultFlags: profile.useDefaultFlags }); - } + protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { this.stateMainService.setItem(UserDataProfilesMainService.PROFILES_KEY, storedProfiles); - this._profilesObject = undefined; - this._onDidChangeProfiles.fire({ added, removed, all: this.profiles }); } - private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile) { - const workspace = this.getWorkspace(workspaceIdentifier); - - // Folder or Multiroot workspace - if (URI.isUri(workspace)) { - this.profilesObject.workspaces.delete(workspace); - if (newProfile && !newProfile.isDefault) { - this.profilesObject.workspaces.set(workspace, newProfile); - } - } - // Empty Window - else { - this.profilesObject.emptyWindow = !newProfile?.isDefault ? newProfile : undefined; - } - - this.saveStoredProfileAssociations(); - } - - private saveStoredProfileAssociations() { - const workspaces: IStringDictionary = {}; - for (const [workspace, profile] of this.profilesObject.workspaces.entries()) { - workspaces[workspace.toString()] = profile.location.toString(); - } - const emptyWindow = this.profilesObject.emptyWindow?.location.toString(); - this.stateMainService.setItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY, { workspaces, emptyWindow }); - this._profilesObject = undefined; + protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { + this.stateMainService.setItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY, storedProfileAssociations); } protected override getStoredProfileAssociations(): StoredProfileAssociations { diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 57e02b114e1..085e035b676 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -3,28 +3,40 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Emitter } 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 { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IFileService } from 'vs/platform/files/common/files'; import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; -import { ILogService } from 'vs/platform/log/common/log'; -import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UseDefaultProfileFlags, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UseDefaultProfileFlags, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; -export class UserDataProfilesNativeService extends UserDataProfilesService implements IUserDataProfilesService { +export class UserDataProfilesNativeService extends Disposable implements IUserDataProfilesService { + + readonly _serviceBrand: undefined; private readonly channel: IChannel; + readonly profilesHome: URI; + + get defaultProfile(): IUserDataProfile { return this.profiles[0]; } + private _profiles: IUserDataProfile[] = []; + get profiles(): IUserDataProfile[] { return this._profiles; } + + private readonly _onDidChangeProfiles = this._register(new Emitter()); + readonly onDidChangeProfiles = this._onDidChangeProfiles.event; + constructor( profiles: UriDto[], @IMainProcessService mainProcessService: IMainProcessService, @IEnvironmentService environmentService: IEnvironmentService, - @IFileService fileService: IFileService, - @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); + super(); this.channel = mainProcessService.getChannel('userDataProfiles'); + this.profilesHome = joinPath(environmentService.userRoamingDataHome, 'profiles'); this._profiles = profiles.map(profile => reviveProfile(profile, this.profilesHome.scheme)); this._register(this.channel.listen('onDidChangeProfiles')(e => { const added = e.added.map(profile => reviveProfile(profile, this.profilesHome.scheme)); @@ -34,17 +46,19 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple })); } - override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { const result = await this.channel.call>('createProfile', [name, useDefaultFlags, workspaceIdentifier]); return reviveProfile(result, this.profilesHome.scheme); } - override async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { await this.channel.call>('setProfileForWorkspace', [profile, workspaceIdentifier]); } - override removeProfile(profile: IUserDataProfile): Promise { + removeProfile(profile: IUserDataProfile): Promise { return this.channel.call('removeProfile', [profile]); } + + getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } } diff --git a/src/vs/platform/userDataProfile/node/userDataProfile.ts b/src/vs/platform/userDataProfile/node/userDataProfile.ts index 34428dd9689..1405ca08e76 100644 --- a/src/vs/platform/userDataProfile/node/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/node/userDataProfile.ts @@ -3,110 +3,32 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IStringDictionary } from 'vs/base/common/collections'; -import { ResourceMap } from 'vs/base/common/map'; import { revive } from 'vs/base/common/marshalling'; import { UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { IStateService } from 'vs/platform/state/node/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { UseDefaultProfileFlags, IUserDataProfile, IUserDataProfilesService, UserDataProfilesService as BaseUserDataProfilesService, toUserDataProfile, WorkspaceIdentifier, EmptyWindowWorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; - -export type UserDataProfilesObject = { - profiles: IUserDataProfile[]; - workspaces: ResourceMap; - emptyWindow?: IUserDataProfile; -}; - -export type StoredUserDataProfile = { - name: string; - location: URI; - useDefaultFlags?: UseDefaultProfileFlags; -}; - -export type StoredProfileAssociations = { - workspaces?: IStringDictionary; - emptyWindow?: string; -}; +import { IUserDataProfilesService, UserDataProfilesService as BaseUserDataProfilesService, StoredUserDataProfile, StoredProfileAssociations } from 'vs/platform/userDataProfile/common/userDataProfile'; export class UserDataProfilesService extends BaseUserDataProfilesService implements IUserDataProfilesService { - protected static readonly PROFILES_KEY = 'userDataProfiles'; - protected static readonly PROFILE_ASSOCIATIONS_KEY = 'profileAssociations'; - - protected enabled: boolean = false; - constructor( @IStateService private readonly stateService: IStateService, - @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); + super(environmentService, fileService, uriIdentityService, logService); } - setEnablement(enabled: boolean): void { - this._profilesObject = undefined; - this.enabled = enabled; - } - - protected _profilesObject: UserDataProfilesObject | undefined; - protected get profilesObject(): UserDataProfilesObject { - if (!this._profilesObject) { - const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; - let emptyWindow: IUserDataProfile | undefined; - const workspaces = new ResourceMap(); - if (profiles.length) { - const profileAssicaitions = this.getStoredProfileAssociations(); - if (profileAssicaitions.workspaces) { - for (const [workspacePath, profilePath] of Object.entries(profileAssicaitions.workspaces)) { - const workspace = URI.parse(workspacePath); - const profileLocation = URI.parse(profilePath); - const profile = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profileLocation)); - if (profile) { - workspaces.set(workspace, profile); - } - } - } - if (profileAssicaitions.emptyWindow) { - const emptyWindowProfileLocation = URI.parse(profileAssicaitions.emptyWindow); - emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); - } - } - profiles.unshift(this.createDefaultUserDataProfile(profiles.length > 0)); - this._profilesObject = { profiles, workspaces, emptyWindow }; - } - return this._profilesObject; - } - - override get profiles(): IUserDataProfile[] { return this.profilesObject.profiles; } - - override getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { - const workspace = this.getWorkspace(workspaceIdentifier); - const profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; - return profile ?? this.defaultProfile; - } - - protected getWorkspace(workspaceIdentifier: WorkspaceIdentifier): URI | EmptyWindowWorkspaceIdentifier { - if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { - return workspaceIdentifier.uri; - } - if (isWorkspaceIdentifier(workspaceIdentifier)) { - return workspaceIdentifier.configPath; - } - return 'empty-window'; - } - - protected getStoredProfiles(): StoredUserDataProfile[] { + protected override getStoredProfiles(): StoredUserDataProfile[] { return revive(this.stateService.getItem[]>(UserDataProfilesService.PROFILES_KEY, [])); } - protected getStoredProfileAssociations(): StoredProfileAssociations { + protected override getStoredProfileAssociations(): StoredProfileAssociations { return revive(this.stateService.getItem>(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, {})); } diff --git a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts index 549c686644c..662a70fe033 100644 --- a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts +++ b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts @@ -14,6 +14,7 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService'; import product from 'vs/platform/product/common/product'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); @@ -37,7 +38,7 @@ suite('UserDataProfileService (Common)', () => { disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider)); environmentService = new TestEnvironmentService(joinPath(ROOT, 'User')); - testObject = new UserDataProfilesService(environmentService, fileService, logService); + testObject = new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService); }); teardown(() => disposables.clear()); diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts index 645181d8a3c..2252b873b35 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts @@ -83,14 +83,16 @@ export class UserDataSyncClient extends Disposable { fileService.registerProvider(Schemas.inMemory, new InMemoryFileSystemProvider()); this.instantiationService.stub(IFileService, fileService); - const userDataProfilesService = this.instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = this.instantiationService.createInstance(UriIdentityService); + this.instantiationService.stub(IUriIdentityService, uriIdentityService); + + const userDataProfilesService = this.instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); this.instantiationService.stub(IStorageService, this._register(new InMemoryStorageService())); 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)); this.instantiationService.stub(IRequestService, this.testServer); diff --git a/src/vs/server/node/remoteExtensionHostAgentCli.ts b/src/vs/server/node/remoteExtensionHostAgentCli.ts index 653748724e0..52647624f79 100644 --- a/src/vs/server/node/remoteExtensionHostAgentCli.ts +++ b/src/vs/server/node/remoteExtensionHostAgentCli.ts @@ -93,8 +93,11 @@ class CliMain extends Disposable { services.set(IFileService, fileService); fileService.registerProvider(Schemas.file, this._register(new DiskFileSystemProvider(logService))); + const uriIdentityService = new UriIdentityService(fileService); + services.set(IUriIdentityService, uriIdentityService); + // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesService(environmentService, fileService, logService)); + const userDataProfilesService = this._register(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration @@ -102,7 +105,6 @@ class CliMain extends Disposable { await configurationService.initialize(); services.set(IConfigurationService, configurationService); - services.set(IUriIdentityService, new UriIdentityService(fileService)); services.set(IRequestService, new SyncDescriptor(RequestService)); services.set(IDownloadService, new SyncDescriptor(DownloadService)); services.set(ITelemetryService, NullTelemetryService); diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index c20bd776c55..ab5f5cb7d57 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -110,8 +110,12 @@ export async function setupServerServices(connectionToken: ServerConnectionToken services.set(IFileService, fileService); fileService.registerProvider(Schemas.file, disposables.add(new DiskFileSystemProvider(logService))); + // URI Identity + const uriIdentityService = new UriIdentityService(fileService); + services.set(IUriIdentityService, uriIdentityService); + // User Data Profiles - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration @@ -122,9 +126,6 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const extensionHostStatusService = new ExtensionHostStatusService(); services.set(IExtensionHostStatusService, extensionHostStatusService); - // URI Identity - services.set(IUriIdentityService, new UriIdentityService(fileService)); - // Request services.set(IRequestService, new SyncDescriptor(RequestService)); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 6dd97deb256..d0791572ccf 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -22,7 +22,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { IWorkbenchFileService } from 'vs/workbench/services/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas, connectionTokenCookieName } from 'vs/base/common/network'; -import { IAnyWorkspaceIdentifier, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IAnyWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { onUnexpectedError } from 'vs/base/common/errors'; import { setFullscreen } from 'vs/base/browser/browser'; @@ -73,7 +73,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel'; import { dirname, joinPath } from 'vs/base/common/resources'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG } from 'vs/platform/userDataProfile/common/userDataProfile'; import { NullPolicyService } from 'vs/platform/policy/common/policy'; import { IRemoteExplorerService, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { DisposableTunnel } from 'vs/platform/tunnel/common/tunnel'; @@ -260,17 +260,16 @@ export class BrowserMain extends Disposable { serviceCollection.set(IWorkbenchFileService, fileService); await this.registerFileSystemProviders(environmentService, fileService, remoteAgentService, logService, logsPath); - // User Data Profiles - const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, logService); - serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - - const userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); - serviceCollection.set(IUserDataProfileService, userDataProfileService); - // URI Identity const uriIdentityService = new UriIdentityService(fileService); serviceCollection.set(IUriIdentityService, uriIdentityService); + // User Data Profiles + const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + serviceCollection.set(IUserDataProfilesService, userDataProfilesService); + const userDataProfileService = new UserDataProfileService(userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window'), userDataProfilesService); + serviceCollection.set(IUserDataProfileService, userDataProfileService); + // Long running services (workspace, config, storage) const [configurationService, storageService] = await Promise.all([ this.createWorkspaceService(payload, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, logService).then(service => { @@ -293,6 +292,7 @@ export class BrowserMain extends Disposable { }) ]); + userDataProfilesService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 44aa262be18..d86d86f4cf8 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -6,7 +6,6 @@ import { Codicon } from 'vs/base/common/codicons'; import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { isWeb } from 'vs/base/common/platform'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; import { Action2, ISubmenuItem, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -53,7 +52,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements } private registerConfiguration(): void { - if (!isWeb && this.productService.quality !== 'stable') { + if (this.productService.quality !== 'stable') { Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ ...workbenchConfigurationNodeBase, 'properties': { diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index f5878699fdf..4986c87d42a 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -239,7 +239,7 @@ export class DesktopMain extends Disposable { serviceCollection.set(IUriIdentityService, uriIdentityService); // User Data Profiles - const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.current, userDataProfilesService.profilesHome.scheme), userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); diff --git a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts index 6412bd0e4c3..867ff2532bf 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts @@ -110,13 +110,14 @@ suite('ConfigurationEditingService', () => { environmentService = TestEnvironmentService; environmentService.policyFile = joinPath(workspaceFolder, 'policies.json'); instantiationService.stub(IEnvironmentService, environmentService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService, null)); disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService)))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); await workspaceService.initialize({ id: hash(workspaceFolder.toString()).toString(16), uri: workspaceFolder diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index 41573109ed5..fb05bed96f1 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -86,8 +86,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); }); @@ -127,8 +128,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); const actual = testObject.getWorkspaceFolder(joinPath(folder, 'a')); @@ -148,8 +150,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); @@ -196,8 +199,9 @@ suite('WorkspaceContextService - Workspace', () => { const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService, null)); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -255,8 +259,9 @@ suite('WorkspaceContextService - Workspace Editing', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -499,9 +504,10 @@ suite('WorkspaceService - Initialization', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -759,9 +765,10 @@ suite('WorkspaceConfigurationService - Folder', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -1425,9 +1432,10 @@ suite('WorkspaceConfigurationService - Profiles', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(toUserDataProfile('custom', joinPath(environmentService.userRoamingDataHome, 'profiles', 'temp')), userDataProfilesService)); - workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -1613,9 +1621,10 @@ suite('WorkspaceConfigurationService-Multiroot', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - const workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -2276,9 +2285,10 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve(), needsCaching: () => false }; - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - testObject = disposables.add(new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); instantiationService.stub(IEnvironmentService, environmentService); diff --git a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts index 74a3cac60bb..eaa0069f098 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts @@ -36,6 +36,8 @@ import { IExtensionHostManager } from 'vs/workbench/services/extensions/common/e import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; suite('BrowserExtensionService', () => { test('pickRunningLocation', () => { @@ -181,6 +183,7 @@ suite('ExtensionService', () => { [IWorkspaceTrustEnablementService, WorkspaceTrustEnablementService], [IUserDataProfilesService, UserDataProfilesService], [IUserDataProfileService, UserDataProfileService], + [IUriIdentityService, UriIdentityService], ]); extService = instantiationService.get(IExtensionService); }); diff --git a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts index d6843185c30..a02b86def5c 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts @@ -22,6 +22,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; suite('ExtensionStorageMigration', () => { @@ -38,7 +39,7 @@ suite('ExtensionStorageMigration', () => { fileService.registerProvider(ROOT.scheme, disposables.add(new InMemoryFileSystemProvider())); instantiationService.stub(IFileService, fileService); const environmentService = instantiationService.stub(IEnvironmentService, >{ userRoamingDataHome: ROOT, workspaceStorageHome }); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); instantiationService.stub(IExtensionStorageService, instantiationService.createInstance(ExtensionStorageService)); diff --git a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts index a20bd496d4b..40e00516362 100644 --- a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts @@ -31,6 +31,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; interface Modifiers { metaKey?: boolean; @@ -66,7 +67,7 @@ suite('KeybindingsEditing', () => { const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'eol': '\n' }); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService); userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); instantiationService = workbenchInstantiationService({ diff --git a/src/vs/workbench/services/storage/test/browser/storageService.test.ts b/src/vs/workbench/services/storage/test/browser/storageService.test.ts index 4205c92d7a8..8491d3f9301 100644 --- a/src/vs/workbench/services/storage/test/browser/storageService.test.ts +++ b/src/vs/workbench/services/storage/test/browser/storageService.test.ts @@ -16,6 +16,7 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { NullLogService } from 'vs/platform/log/common/log'; import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { createSuite } from 'vs/platform/storage/test/common/storageService.test'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { BrowserStorageService, IndexedDBStorageDatabase } from 'vs/workbench/services/storage/browser/storageService'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; @@ -46,7 +47,7 @@ async function createStorageService(): Promise<[DisposableStore, BrowserStorageS extensionsResource: joinPath(inMemoryExtraProfileRoot, 'extensionsResource') }; - const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile, new UserDataProfilesService(TestEnvironmentService, fileService, logService)), logService)); + const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile, new UserDataProfilesService(TestEnvironmentService, fileService, new UriIdentityService(fileService), logService)), logService)); await storageService.initialize(); diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index bed76364445..6e09fd1d153 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -10,7 +10,7 @@ import { MenuId } from 'vs/platform/actions/common/actions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IUserDataProfile, PROFILES_ENABLEMENT_CONFIG, UseDefaultProfileFlags } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ContextKeyDefinedExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { IsWebContext, ProductQualityContext } from 'vs/platform/contextkey/common/contextkeys'; +import { ProductQualityContext } from 'vs/platform/contextkey/common/contextkeys'; export interface DidChangeUserDataProfileEvent { readonly preserveData: boolean; @@ -73,4 +73,4 @@ export const PROFILES_TTILE = { value: localize('settings profiles', "Settings P export const PROFILES_CATEGORY = PROFILES_TTILE.value; export const PROFILE_EXTENSION = 'code-profile'; export const PROFILE_FILTER = [{ name: localize('profile', "Settings Profile"), extensions: [PROFILE_EXTENSION] }]; -export const PROFILES_ENABLEMENT_CONTEXT = ContextKeyExpr.and(ProductQualityContext.notEqualsTo('stable'), IsWebContext.negate(), ContextKeyDefinedExpr.create(`config.${PROFILES_ENABLEMENT_CONFIG}`)); +export const PROFILES_ENABLEMENT_CONTEXT = ContextKeyExpr.and(ProductQualityContext.notEqualsTo('stable'), ContextKeyDefinedExpr.create(`config.${PROFILES_ENABLEMENT_CONFIG}`)); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 763878dc76d..9b0dc8d9c43 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -286,9 +286,10 @@ export function workbenchInstantiationService( instantiationService.stub(IModelService, disposables.add(instantiationService.createInstance(ModelService))); const fileService = overrides?.fileService ? overrides.fileService(instantiationService) : new TestFileService(); instantiationService.stub(IFileService, fileService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); + const uriIdentityService = new UriIdentityService(fileService); + instantiationService.stub(IUriIdentityService, uriIdentityService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService)); instantiationService.stub(IWorkingCopyBackupService, new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(INotificationService, new TestNotificationService()); @@ -2003,6 +2004,7 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens export class TestWebExtensionsScannerService implements IWebExtensionsScannerService { _serviceBrand: undefined; + onDidChangeProfileExtensions = Event.None; async scanSystemExtensions(): Promise { return []; } async scanUserExtensions(): Promise { return []; } async scanExtensionsUnderDevelopment(): Promise { return []; } diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 1880f3377d6..3a35d0f4018 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -53,6 +53,7 @@ import { FileService } from 'vs/platform/files/common/fileService'; import { joinPath } from 'vs/base/common/resources'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const args = parseArgs(process.argv, OPTIONS); @@ -289,7 +290,8 @@ export function workbenchInstantiationService(disposables = new DisposableStore( instantiationService.stub(INativeEnvironmentService, TestEnvironmentService); instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService); instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, new FileService(new NullLogService()), new NullLogService())); + const fileService = new FileService(new NullLogService()); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, fileService, new UriIdentityService(fileService), new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); return instantiationService;