diff --git a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts index b67a779c2858a39ad0845c84b3de532421440b86..b3e6041730cafcecbf4b9f7762589f7b034a6d78 100644 --- a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts +++ b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts @@ -14,8 +14,8 @@ export class GlobalExtensionEnablementService extends Disposable implements IGlo _serviceBrand: undefined; - private _onDidChangeEnablement = new Emitter(); - readonly onDidChangeEnablement: Event = this._onDidChangeEnablement.event; + private _onDidChangeEnablement = new Emitter<{ readonly extensions: IExtensionIdentifier[], readonly source?: string }>(); + readonly onDidChangeEnablement: Event<{ readonly extensions: IExtensionIdentifier[], readonly source?: string }> = this._onDidChangeEnablement.event; private readonly storageManger: StorageManager; constructor( @@ -23,20 +23,20 @@ export class GlobalExtensionEnablementService extends Disposable implements IGlo ) { super(); this.storageManger = this._register(new StorageManager(storageService)); - this._register(this.storageManger.onDidChange(extensions => this._onDidChangeEnablement.fire(extensions))); + this._register(this.storageManger.onDidChange(extensions => this._onDidChangeEnablement.fire({ extensions, source: 'storage' }))); } - async enableExtension(extension: IExtensionIdentifier): Promise { + async enableExtension(extension: IExtensionIdentifier, source?: string): Promise { if (this._removeFromDisabledExtensions(extension)) { - this._onDidChangeEnablement.fire([extension]); + this._onDidChangeEnablement.fire({ extensions: [extension], source }); return true; } return false; } - async disableExtension(extension: IExtensionIdentifier): Promise { + async disableExtension(extension: IExtensionIdentifier, source?: string): Promise { if (this._addToDisabledExtensions(extension)) { - this._onDidChangeEnablement.fire([extension]); + this._onDidChangeEnablement.fire({ extensions: [extension], source }); return true; } return false; diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 1c73c5ad34603e2d60df5e7dd127cc4adf743135..9612407ed0747cf3d5dd4d026bdd16d26fddeeb0 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -213,11 +213,11 @@ export const IGlobalExtensionEnablementService = createDecorator; + readonly onDidChangeEnablement: Event<{ readonly extensions: IExtensionIdentifier[], readonly source?: string }>; getDisabledExtensions(): IExtensionIdentifier[]; - enableExtension(extension: IExtensionIdentifier): Promise; - disableExtension(extension: IExtensionIdentifier): Promise; + enableExtension(extension: IExtensionIdentifier, source?: string): Promise; + disableExtension(extension: IExtensionIdentifier, source?: string): Promise; // Async method until storage service is available in shared process getDisabledExtensionsAsync(): Promise; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index b5f8114efe0be7d087fcdfa27d0098aff8506509..41544466ab59ec3273c9f2cab7be82669509ec76 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -156,7 +156,7 @@ export class GlobalExtensionEnablementServiceClient implements IGlobalExtensionE _serviceBrand: undefined; - get onDidChangeEnablement(): Event { return this.channel.listen('onDidChangeEnablement'); } + get onDidChangeEnablement(): Event<{ readonly extensions: IExtensionIdentifier[], readonly source?: string }> { return this.channel.listen('onDidChangeEnablement'); } constructor(private readonly channel: IChannel) { } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 82170eaa199368be854e910ec2d55b2739d5fefa..57095928076ed1e0ac740fc2cfbca859bd16b0df 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -942,16 +942,6 @@ suite('ExtensionsWorkbenchServiceTest', () => { }); }); - test('test installing an extension re-eanbles it when disabled globally', async () => { - testObject = await aWorkbenchService(); - const local = aLocalExtension('pub.a'); - await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally); - didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install }); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - const actual = await testObject.queryLocal(); - assert.equal(actual[0].enablementState, EnablementState.EnabledGlobally); - }); - test('test updating an extension does not re-eanbles it when disabled globally', async () => { testObject = await aWorkbenchService(); const local = aLocalExtension('pub.a'); @@ -962,16 +952,6 @@ suite('ExtensionsWorkbenchServiceTest', () => { assert.equal(actual[0].enablementState, EnablementState.DisabledGlobally); }); - test('test installing an extension re-eanbles it when workspace disabled', async () => { - testObject = await aWorkbenchService(); - const local = aLocalExtension('pub.a'); - await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledWorkspace); - didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install }); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - const actual = await testObject.queryLocal(); - assert.equal(actual[0].enablementState, EnablementState.EnabledGlobally); - }); - test('test updating an extension does not re-eanbles it when workspace disabled', async () => { testObject = await aWorkbenchService(); const local = aLocalExtension('pub.a'); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionEnablementService.ts index ceeee11b03300095c20b0cf1aaa87d74d950032e..d64573ec6dcb923afb10b88608da0de5912a647d 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionEnablementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionEnablementService.ts @@ -19,6 +19,8 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IProductService } from 'vs/platform/product/common/productService'; import { StorageManager } from 'vs/platform/extensionManagement/common/extensionEnablementService'; +const SOURCE = 'IWorkbenchExtensionEnablementService'; + export class ExtensionEnablementService extends Disposable implements IWorkbenchExtensionEnablementService { _serviceBrand: undefined; @@ -40,7 +42,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench ) { super(); this.storageManger = this._register(new StorageManager(storageService)); - this._register(this.globalExtensionEnablementService.onDidChangeEnablement(extensions => this.onDidChangeExtensions(extensions))); + this._register(this.globalExtensionEnablementService.onDidChangeEnablement(({ extensions, source }) => this.onDidChangeExtensions(extensions, source))); this._register(extensionManagementService.onDidUninstallExtension(this._onDidUninstallExtension, this)); } @@ -169,13 +171,13 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench private _enableExtension(identifier: IExtensionIdentifier): Promise { this._removeFromWorkspaceDisabledExtensions(identifier); this._removeFromWorkspaceEnabledExtensions(identifier); - return this.globalExtensionEnablementService.enableExtension(identifier); + return this.globalExtensionEnablementService.enableExtension(identifier, SOURCE); } private _disableExtension(identifier: IExtensionIdentifier): Promise { this._removeFromWorkspaceDisabledExtensions(identifier); this._removeFromWorkspaceEnabledExtensions(identifier); - return this.globalExtensionEnablementService.disableExtension(identifier); + return this.globalExtensionEnablementService.disableExtension(identifier, SOURCE); } private _enableExtensionInWorkspace(identifier: IExtensionIdentifier): void { @@ -273,10 +275,12 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench this.storageManger.set(storageId, extensions, StorageScope.WORKSPACE); } - private async onDidChangeExtensions(extensionIdentifiers: ReadonlyArray): Promise { - const installedExtensions = await this.extensionManagementService.getInstalled(); - const extensions = installedExtensions.filter(installedExtension => extensionIdentifiers.some(identifier => areSameExtensions(identifier, installedExtension.identifier))); - this._onEnablementChanged.fire(extensions); + private async onDidChangeExtensions(extensionIdentifiers: ReadonlyArray, source?: string): Promise { + if (source !== SOURCE) { + const installedExtensions = await this.extensionManagementService.getInstalled(); + const extensions = installedExtensions.filter(installedExtension => extensionIdentifiers.some(identifier => areSameExtensions(identifier, installedExtension.identifier))); + this._onEnablementChanged.fire(extensions); + } } private _onDidUninstallExtension({ identifier, error }: DidUninstallExtensionEvent): void {