diff --git a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts index 4466945eb97..5f9eb66ab94 100644 --- a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -11,6 +11,7 @@ import { IPager } from 'vs/base/common/paging'; import { isWeb } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { IHeaders, IRequestContext, IRequestOptions } from 'vs/base/parts/request/common/request'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { CURRENT_TARGET_PLATFORM, DefaultIconPath, IExtensionGalleryService, IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IReportedExtension, isIExtensionIdentifier, ITranslation, SortBy, SortOrder, StatisticType, TargetPlatform, toTargetPlatform, WEB_EXTENSION_TAG } from 'vs/platform/extensionManagement/common/extensionManagement'; import { adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -24,6 +25,7 @@ import { asJson, asText, IRequestService, isSuccess } from 'vs/platform/request/ import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/serviceMachineId'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { getTelemetryLevel, TelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; interface IRawGalleryExtensionFile { readonly assetType: string; @@ -460,12 +462,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService { @ITelemetryService private readonly telemetryService: ITelemetryService, @IFileService private readonly fileService: IFileService, @IProductService private readonly productService: IProductService, + @IConfigurationService private readonly configurationService: IConfigurationService, @optional(IStorageService) storageService: IStorageService, ) { const config = productService.extensionsGallery; this.extensionsGalleryUrl = config && config.serviceUrl; this.extensionsControlUrl = config && config.controlUrl; - this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, this.environmentService, this.fileService, storageService); + this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, productService, this.environmentService, this.configurationService, this.fileService, storageService); } private api(path = ''): string { @@ -927,7 +930,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { } } -export async function resolveMarketplaceHeaders(version: string, environmentService: IEnvironmentService, fileService: IFileService, storageService: { +export async function resolveMarketplaceHeaders(version: string, productService: IProductService, environmentService: IEnvironmentService, configurationService: IConfigurationService, fileService: IFileService, storageService: { get: (key: string, scope: StorageScope) => string | undefined, store: (key: string, value: string, scope: StorageScope, target: StorageTarget) => void } | undefined): Promise<{ [key: string]: string; }> { @@ -936,6 +939,8 @@ export async function resolveMarketplaceHeaders(version: string, environmentServ 'User-Agent': `VSCode ${version}` }; const uuid = await getServiceMachineId(environmentService, fileService, storageService); - headers['X-Market-User-Id'] = uuid; + if (getTelemetryLevel(productService, environmentService) === TelemetryLevel.USER && configurationService.getValue('telemetry.enableTelemetry') === true) { + headers['X-Market-User-Id'] = uuid; + } return headers; } diff --git a/src/vs/platform/extensionManagement/test/common/extensionGalleryService.test.ts b/src/vs/platform/extensionManagement/test/common/extensionGalleryService.test.ts index 603165c8719..1c3d759990b 100644 --- a/src/vs/platform/extensionManagement/test/common/extensionGalleryService.test.ts +++ b/src/vs/platform/extensionManagement/test/common/extensionGalleryService.test.ts @@ -9,6 +9,8 @@ import { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { isUUID } from 'vs/base/common/uuid'; import { mock } from 'vs/base/test/common/mock'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IFileService } from 'vs/platform/files/common/files'; @@ -16,6 +18,7 @@ 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 product from 'vs/platform/product/common/product'; +import { IProductService } from 'vs/platform/product/common/productService'; import { InMemoryStorageService, IStorageService } from 'vs/platform/storage/common/storage'; class EnvironmentServiceMock extends mock() { @@ -28,7 +31,7 @@ class EnvironmentServiceMock extends mock() { suite('Extension Gallery Service', () => { const disposables: DisposableStore = new DisposableStore(); - let fileService: IFileService, environmentService: IEnvironmentService, storageService: IStorageService; + let fileService: IFileService, environmentService: IEnvironmentService, storageService: IStorageService, productService: IProductService, configurationService: IConfigurationService; setup(() => { const serviceMachineIdResource = joinPath(URI.file('tests').with({ scheme: 'vscode-tests' }), 'machineid'); @@ -37,14 +40,16 @@ suite('Extension Gallery Service', () => { const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider()); fileService.registerProvider(serviceMachineIdResource.scheme, fileSystemProvider); storageService = new InMemoryStorageService(); + configurationService = new TestConfigurationService(); + productService = { _serviceBrand: undefined, ...product }; }); teardown(() => disposables.clear()); test('marketplace machine id', async () => { - const headers = await resolveMarketplaceHeaders(product.version, environmentService, fileService, storageService); + const headers = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService); assert.ok(isUUID(headers['X-Market-User-Id'])); - const headers2 = await resolveMarketplaceHeaders(product.version, environmentService, fileService, storageService); + const headers2 = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService); assert.strictEqual(headers['X-Market-User-Id'], headers2['X-Market-User-Id']); }); }); diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 13ac211dfd1..8046bf6c331 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -175,7 +175,6 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync const headers: IHeaders = { 'X-Client-Name': `${productService.applicationName}${isWeb ? '-web' : ''}`, 'X-Client-Version': productService.version, - 'X-Machine-Id': uuid }; if (productService.commit) { headers['X-Client-Commit'] = productService.commit; diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts b/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts index 4bd5b838ff7..4fd656fa644 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts @@ -88,7 +88,6 @@ suite('UserDataSyncStoreService', () => { assert.strictEqual(target.requestsWithAllHeaders.length, 1); assert.strictEqual(target.requestsWithAllHeaders[0].headers!['X-Client-Name'], `${productService.applicationName}${isWeb ? '-web' : ''}`); assert.strictEqual(target.requestsWithAllHeaders[0].headers!['X-Client-Version'], productService.version); - assert.notStrictEqual(target.requestsWithAllHeaders[0].headers!['X-Machine-Id'], undefined); assert.notStrictEqual(target.requestsWithAllHeaders[0].headers!['X-Machine-Session-Id'], undefined); assert.strictEqual(target.requestsWithAllHeaders[0].headers!['X-User-Session-Id'], undefined); }); diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index 8e3e960e028..7483dee08ab 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -302,7 +302,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.createTouchBar(); // Request handling - this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.productService.version, this.environmentMainService, this.fileService, { + this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.productService.version, this.productService, this.environmentMainService, this.configurationService, this.fileService, { get: key => storageMainService.globalStorage.get(key), store: (key, value) => storageMainService.globalStorage.set(key, value) }); diff --git a/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts b/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts index 0178c4a175f..06a61593eca 100644 --- a/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts +++ b/src/vs/workbench/services/extensionResourceLoader/browser/extensionResourceLoaderService.ts @@ -14,6 +14,8 @@ import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/service import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isWeb } from 'vs/base/common/platform'; import { ILogService } from 'vs/platform/log/common/log'; +import { getTelemetryLevel, TelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; class ExtensionResourceLoaderService implements IExtensionResourceLoaderService { @@ -27,6 +29,7 @@ class ExtensionResourceLoaderService implements IExtensionResourceLoaderService @IStorageService private readonly _storageService: IStorageService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, @ILogService private readonly _logService: ILogService, + @IConfigurationService private readonly _configurationService: IConfigurationService ) { if (_productService.extensionsGallery) { this._extensionGalleryResourceAuthority = this._getExtensionResourceAuthority(URI.parse(_productService.extensionsGallery.resourceUrlTemplate)); @@ -46,9 +49,11 @@ class ExtensionResourceLoaderService implements IExtensionResourceLoaderService const machineId = await this._getServiceMachineId(); requestInit.headers = { 'X-Client-Name': `${this._productService.applicationName}${isWeb ? '-web' : ''}`, - 'X-Client-Version': this._productService.version, - 'X-Machine-Id': machineId + 'X-Client-Version': this._productService.version }; + if (getTelemetryLevel(this._productService, this._environmentService) === TelemetryLevel.USER && this._configurationService.getValue('telemetry.enableTelemetry') === true) { + requestInit.headers['X-Machine-Id'] = machineId; + } if (this._productService.commit) { requestInit.headers['X-Client-Commit'] = this._productService.commit; }