diff --git a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts b/src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts similarity index 87% rename from src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts rename to src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts index b08ede73f6..25d7819ffc 100644 --- a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts +++ b/src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Registry } from 'vs/platform/registry/common/platform'; -import { BrowserTelemetryOptOut } from 'vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut'; +import { BrowserTelemetryOptOut } from 'sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; diff --git a/src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts b/src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts new file mode 100644 index 0000000000..e82e3bd392 --- /dev/null +++ b/src/sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts @@ -0,0 +1,93 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { URI } from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { onUnexpectedError } from 'vs/base/common/errors'; + +export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution { + + private static readonly TELEMETRY_OPT_OUT_SHOWN = 'workbench.telemetryOptOutShown'; + private privacyUrl: string | undefined; + + constructor( + @IStorageService private readonly storageService: IStorageService, + @IOpenerService private readonly openerService: IOpenerService, + @INotificationService private readonly notificationService: INotificationService, + @IHostService private readonly hostService: IHostService, + @ITelemetryService private readonly telemetryService: ITelemetryService, + @IProductService private readonly productService: IProductService, + @IEnvironmentService private readonly environmentService: IEnvironmentService + ) { + } + + protected async handleTelemetryOptOut(): Promise { + if (this.productService.telemetryOptOutUrl && + !this.storageService.get(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, StorageScope.APPLICATION) && + !this.environmentService.disableTelemetry) { + + const [count] = await Promise.all([this.getWindowCount()]); + + if (!this.hostService.hasFocus && count > 1) { + return; // return early if meanwhile another window opened (we only show the opt-out once) + } + + this.storageService.store(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.USER); + + this.privacyUrl = this.productService.privacyStatementUrl || this.productService.telemetryOptOutUrl; + + const telemetryOptOutUrl = this.productService.telemetryOptOutUrl; + if (telemetryOptOutUrl) { + this.showTelemetryOptOut(telemetryOptOutUrl); + } + } + } + + private showTelemetryOptOut(telemetryOptOutUrl: string): void { + const optOutNotice = localize('telemetryOptOut.optOutNotice', "Help improve Azure Data Studio by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt out]({1}).", this.privacyUrl, this.productService.telemetryOptOutUrl); + const optInNotice = localize('telemetryOptOut.optInNotice', "Help improve Azure Data Studio by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt in]({1}).", this.privacyUrl, this.productService.telemetryOptOutUrl); + + this.notificationService.prompt( + Severity.Info, + this.telemetryService.telemetryLevel !== TelemetryLevel.NONE ? optOutNotice : optInNotice, + [{ + label: localize('telemetryOptOut.readMore', "Read More"), + run: () => this.openerService.open(URI.parse(telemetryOptOutUrl)) + }], + { sticky: true } + ); + } + + protected abstract getWindowCount(): Promise; +} + +export class BrowserTelemetryOptOut extends AbstractTelemetryOptOut { + + constructor( + @IStorageService storageService: IStorageService, + @IOpenerService openerService: IOpenerService, + @INotificationService notificationService: INotificationService, + @IHostService hostService: IHostService, + @ITelemetryService telemetryService: ITelemetryService, + @IProductService productService: IProductService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + super(storageService, openerService, notificationService, hostService, telemetryService, productService, environmentService); + + this.handleTelemetryOptOut().catch(onUnexpectedError); + } + + protected async getWindowCount(): Promise { + return 1; + } +} diff --git a/src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts b/src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts similarity index 86% rename from src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts rename to src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts index a347377e40..72f326365f 100644 --- a/src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts +++ b/src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution.ts @@ -6,6 +6,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { NativeTelemetryOptOut } from 'vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut'; +import { NativeTelemetryOptOut } from 'sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut'; Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(NativeTelemetryOptOut, LifecyclePhase.Eventually); diff --git a/src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts b/src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts similarity index 62% rename from src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts rename to src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts index f2875a996b..a7a9643f7a 100644 --- a/src/vs/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts +++ b/src/sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.ts @@ -7,14 +7,10 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IProductService } from 'vs/platform/product/common/productService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; -import { AbstractTelemetryOptOut } from 'vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut'; +import { AbstractTelemetryOptOut } from 'sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { INativeHostService } from 'vs/platform/native/common/native'; export class NativeTelemetryOptOut extends AbstractTelemetryOptOut { @@ -25,20 +21,16 @@ export class NativeTelemetryOptOut extends AbstractTelemetryOptOut { @INotificationService notificationService: INotificationService, @IHostService hostService: IHostService, @ITelemetryService telemetryService: ITelemetryService, - @IExperimentService experimentService: IExperimentService, - @IConfigurationService configurationService: IConfigurationService, - @IExtensionGalleryService galleryService: IExtensionGalleryService, @IProductService productService: IProductService, @IEnvironmentService environmentService: IEnvironmentService, - @IJSONEditingService jsonEditingService: IJSONEditingService, @INativeHostService private readonly nativeHostService: INativeHostService ) { - super(storageService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService); + super(storageService, openerService, notificationService, hostService, telemetryService, productService, environmentService); this.handleTelemetryOptOut(); } protected getWindowCount(): Promise { - return this.nativeHostService ? this.nativeHostService.getWindowCount() : Promise.resolve(0); // {{SQL CARBON EDIT}} Tests run without UI context so electronService is undefined in that case + return this.nativeHostService ? this.nativeHostService.getWindowCount() : Promise.resolve(0); } } diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/common/media/dark/workspaceTrust.svg b/src/vs/workbench/contrib/welcome/gettingStarted/common/media/dark/workspaceTrust.svg deleted file mode 100644 index f1cf7fe505..0000000000 --- a/src/vs/workbench/contrib/welcome/gettingStarted/common/media/dark/workspaceTrust.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/common/media/light/workspaceTrust.svg b/src/vs/workbench/contrib/welcome/gettingStarted/common/media/light/workspaceTrust.svg deleted file mode 100644 index 486ed7dd30..0000000000 --- a/src/vs/workbench/contrib/welcome/gettingStarted/common/media/light/workspaceTrust.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts b/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts deleted file mode 100644 index 5c29eec5f3..0000000000 --- a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts +++ /dev/null @@ -1,188 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; -import { URI } from 'vs/base/common/uri'; -import { localize } from 'vs/nls'; -import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { language, locale } from 'vs/base/common/platform'; -import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { IProductService } from 'vs/platform/product/common/productService'; -import { IHostService } from 'vs/workbench/services/host/browser/host'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; - -export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution { - - private static readonly TELEMETRY_OPT_OUT_SHOWN = 'workbench.telemetryOptOutShown'; - private privacyUrl: string | undefined; - - constructor( - @IStorageService private readonly storageService: IStorageService, - @IOpenerService private readonly openerService: IOpenerService, - @INotificationService private readonly notificationService: INotificationService, - @IHostService private readonly hostService: IHostService, - @ITelemetryService private readonly telemetryService: ITelemetryService, - @IExperimentService private readonly experimentService: IExperimentService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, - @IProductService private readonly productService: IProductService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IJSONEditingService private readonly jsonEditingService: IJSONEditingService - ) { - } - - protected async handleTelemetryOptOut(): Promise { - if (this.productService.telemetryOptOutUrl && - !this.storageService.get(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, StorageScope.APPLICATION) && - !this.environmentService.disableTelemetry) { // {{SQL CARBON EDIT}} Adding check to disable opt out toast when this flag is set. - const experimentId = 'telemetryOptOut'; - - const [count, experimentState] = await Promise.all([this.getWindowCount(), this.experimentService.getExperimentById(experimentId)]); - - if (!this.hostService.hasFocus && count > 1) { - return; // return early if meanwhile another window opened (we only show the opt-out once) - } - - this.storageService.store(AbstractTelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.USER); - - this.privacyUrl = this.productService.privacyStatementUrl || this.productService.telemetryOptOutUrl; - - if (experimentState && experimentState.state === ExperimentState.Run && this.telemetryService.telemetryLevel !== TelemetryLevel.NONE) { - this.runExperiment(experimentId); - return; - } - - const telemetryOptOutUrl = this.productService.telemetryOptOutUrl; - if (telemetryOptOutUrl) { - this.showTelemetryOptOut(telemetryOptOutUrl); - } - } - } - - private showTelemetryOptOut(telemetryOptOutUrl: string): void { - const optOutNotice = localize('telemetryOptOut.optOutNotice', "Help improve Azure Data Studio by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt out]({1}).", this.privacyUrl, this.productService.telemetryOptOutUrl); - const optInNotice = localize('telemetryOptOut.optInNotice', "Help improve Azure Data Studio by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt in]({1}).", this.privacyUrl, this.productService.telemetryOptOutUrl); - - this.notificationService.prompt( - Severity.Info, - this.telemetryService.telemetryLevel !== TelemetryLevel.NONE ? optOutNotice : optInNotice, - [{ - label: localize('telemetryOptOut.readMore', "Read More"), - run: () => this.openerService.open(URI.parse(telemetryOptOutUrl)) - }], - { sticky: true } - ); - } - - protected abstract getWindowCount(): Promise; - - private runExperiment(experimentId: string) { - const promptMessageKey = 'telemetryOptOut.optOutOption'; - const yesLabelKey = 'telemetryOptOut.OptIn'; - const noLabelKey = 'telemetryOptOut.OptOut'; - - let promptMessage = localize('telemetryOptOut.optOutOption', "Please help Microsoft improve Visual Studio Code by allowing the collection of usage data. Read our [privacy statement]({0}) for more details.", this.privacyUrl); - let yesLabel = localize('telemetryOptOut.OptIn', "Yes, glad to help"); - let noLabel = localize('telemetryOptOut.OptOut', "No, thanks"); - - let queryPromise = Promise.resolve(undefined); - if (locale && locale !== language && locale !== 'en' && locale.indexOf('en-') === -1) { - queryPromise = this.galleryService.query({ text: `tag:lp-${locale}` }, CancellationToken.None).then(tagResult => { - if (!tagResult || !tagResult.total) { - return undefined; - } - const extensionToFetchTranslationsFrom = tagResult.firstPage.filter(e => e.publisher === 'MS-CEINTL' && e.name.indexOf('vscode-language-pack') === 0)[0] || tagResult.firstPage[0]; - if (!extensionToFetchTranslationsFrom.assets || !extensionToFetchTranslationsFrom.assets.coreTranslations.length) { - return undefined; - } - - return this.galleryService.getCoreTranslation(extensionToFetchTranslationsFrom, locale!) - .then(translation => { - const translationsFromPack: any = translation && translation.contents ? translation.contents['vs/workbench/contrib/welcome/telemetryOptOut/electron-browser/telemetryOptOut'] : {}; - if (!!translationsFromPack[promptMessageKey] && !!translationsFromPack[yesLabelKey] && !!translationsFromPack[noLabelKey]) { - promptMessage = translationsFromPack[promptMessageKey].replace('{0}', this.privacyUrl) + ' (Please help Microsoft improve Visual Studio Code by allowing the collection of usage data.)'; - yesLabel = translationsFromPack[yesLabelKey] + ' (Yes)'; - noLabel = translationsFromPack[noLabelKey] + ' (No)'; - } - return undefined; - }); - - }); - } - - const logTelemetry = (optout?: boolean) => { - type ExperimentsOptOutClassification = { - owner: 'karlb'; - comment: 'VS Code experiements opt out classification event'; - optout?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The optout value' }; - }; - - type ExperimentsOptOutEvent = { - optout?: boolean; - }; - this.telemetryService.publicLog2('experiments:optout', typeof optout === 'boolean' ? { optout } : {}); - }; - - queryPromise.then(() => { - this.notificationService.prompt( - Severity.Info, - promptMessage, - [ - { - label: yesLabel, - run: () => { - logTelemetry(false); - } - }, - { - label: noLabel, - run: async () => { - logTelemetry(true); - this.configurationService.updateValue('telemetry.enableTelemetry', false); - await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['enable-crash-reporter'], value: false }], true); - } - } - ], - { - sticky: true, - onCancel: logTelemetry - } - ); - this.experimentService.markAsCompleted(experimentId); - }); - } -} - -export class BrowserTelemetryOptOut extends AbstractTelemetryOptOut { - - constructor( - @IStorageService storageService: IStorageService, - @IOpenerService openerService: IOpenerService, - @INotificationService notificationService: INotificationService, - @IHostService hostService: IHostService, - @ITelemetryService telemetryService: ITelemetryService, - @IExperimentService experimentService: IExperimentService, - @IConfigurationService configurationService: IConfigurationService, - @IExtensionGalleryService galleryService: IExtensionGalleryService, - @IProductService productService: IProductService, - @IEnvironmentService environmentService: IEnvironmentService, - @IJSONEditingService jsonEditingService: IJSONEditingService - ) { - super(storageService, openerService, notificationService, hostService, telemetryService, experimentService, configurationService, galleryService, productService, environmentService, jsonEditingService); - - this.handleTelemetryOptOut(); - } - - protected async getWindowCount(): Promise { - return 1; - } -} diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index dc9a35dd51..fe5d14937d 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -168,6 +168,10 @@ import 'vs/workbench/contrib/mergeEditor/electron-sandbox/mergeEditor.contributi // Remote Tunnel import 'vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution'; +// {{SQL CARBON EDIT}} - SQL added contributions +// Telemetry Opt Out +import 'sql/workbench/contrib/welcome/telemetryOptOut/electron-sandbox/telemetryOptOut.contribution'; + //#endregion export { main } from 'vs/workbench/electron-sandbox/desktop.main'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 88dd690eac..fb47dc258d 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -213,12 +213,12 @@ export { //#endregion -//#region +//#region {{SQL CARBON EDIT}} - SQL added contributions // Getting Started import 'sql/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.contribution'; // Telemetry Opt Out -import 'vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution'; +import 'sql/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.contribution'; //#endregion