From 7dbff7345412b8be19dbabb0bd9279541c2788ec Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 21 Dec 2017 15:48:52 +0100 Subject: [PATCH] GDPR support: SentUsageStatistics.isAllowed flag is now part of ConsentOptions; bundled default consents.json --- .../com/intellij/ide/gdpr/ConsentOptions.java | 9 +++ .../src/com/intellij/idea/StartupUtil.java | 2 +- .../actions/SendStatisticsAction.java | 16 ++-- .../configurable/StatisticsConfigurable.java | 76 ------------------- .../StatisticsConfigurationComponent.form | 74 ------------------ .../StatisticsConfigurationComponent.java | 71 ----------------- .../UsageStatisticsPersistenceComponent.java | 17 +++-- .../StatisticsNotificationManager.java | 16 ++-- .../src/com/intellij/ui/AppUIUtil.java | 2 +- .../src/META-INF/PlatformExtensions.xml | 3 - .../platform-resources/src/PrivacyPolicy.html | 7 +- platform/platform-resources/src/consents.json | 9 +++ 12 files changed, 50 insertions(+), 252 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java create mode 100644 platform/platform-resources/src/consents.json diff --git a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java index f9a2e498a4c7..0f3636ac7d37 100644 --- a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java +++ b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java @@ -98,6 +98,15 @@ public final class ConsentOptions { return confirmedConsent == null? Permission.UNDEFINED : confirmedConsent.isAccepted()? Permission.YES : Permission.NO; } + public boolean setSendingUsageStatsAllowed(boolean allowed) { + final Consent defConsent = loadDefaultConsents().get(STATISTICS_OPTION_ID); + if (defConsent != null && !defConsent.isDeleted()) { + saveConfirmedConsents(Collections.singleton(new ConfirmedConsent(defConsent.getId(), defConsent.getVersion(), allowed, 0L))); + return true; + } + return false; + } + @Nullable public String getConfirmedConsentsString() { final Map defaults = loadDefaultConsents(); diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 51ee6a849f8f..91e55a82e0bf 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -130,7 +130,7 @@ public class StartupUtil { if (!Main.isHeadless()) { AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame()); AppUIUtil.registerBundledFonts(); - AppUIUtil.showEndUserAgreement(); + AppUIUtil.showUserAgreementAndConsentsIfNeeded(); } appStarter.start(newConfigFolder); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java index 3e49fe81134d..05a4ddf2ae85 100755 --- a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java @@ -15,11 +15,11 @@ */ package com.intellij.internal.statistic.actions; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; +import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.connect.StatisticsResult; import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; +import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; @@ -45,10 +45,14 @@ public class SendStatisticsAction extends AnAction { @Override public void run(@NotNull ProgressIndicator indicator) { UsageStatisticsPersistenceComponent statisticsPersistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); - statisticsPersistenceComponent.setAllowed(true); - ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); - statisticsPersistenceComponent.setAllowed(sendAllowed); + final boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); + try { + statisticsPersistenceComponent.setAllowed(true); + ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); + } + finally { + statisticsPersistenceComponent.setAllowed(sendAllowed); + } StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); final StatisticsResult result = service.send(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java deleted file mode 100644 index 3ec9f7cf6d97..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.options.SearchableConfigurable; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -public class StatisticsConfigurable implements SearchableConfigurable, Configurable.NoScroll { - - private boolean modifiedByDefault; - - public StatisticsConfigurable() { - this(false); - } - - public StatisticsConfigurable(boolean isModifiedByDefault) { - modifiedByDefault = isModifiedByDefault; - } - - - private StatisticsConfigurationComponent myConfig; - - @Nls - public String getDisplayName() { - return "Usage Statistics"; - } - - @Override - @Nullable - @NonNls - public String getHelpTopic() { - return "preferences.usage.statictics"; - } - - public JComponent createComponent() { - myConfig = new StatisticsConfigurationComponent(); - return myConfig.getJComponent(); - } - - public boolean isModified() { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - return myConfig.isAllowed() != persistenceComponent.isAllowed() || - myConfig.getPeriod() != persistenceComponent.getPeriod() || - modifiedByDefault; - } - - public void apply() throws ConfigurationException { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - - //persistenceComponent.setPeriod(myConfig.getPeriod()); - persistenceComponent.setAllowed(myConfig.isAllowed()); - persistenceComponent.setShowNotification(false); - modifiedByDefault = false; - } - - public void reset() { - myConfig.reset(); - } - - public void disposeUIResources() { - myConfig = null; - } - - @NotNull - @Override - public String getId() { - return "usage.statistics"; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form deleted file mode 100644 index fc64eadf51ec..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form +++ /dev/null @@ -1,74 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java deleted file mode 100644 index 3c87c7215cf6..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.StatisticsBundle; -import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.ui.RelativeFont; - -import javax.swing.*; -import java.util.Map; - -public class StatisticsConfigurationComponent { - - private JPanel myMainPanel; - private JLabel myTitle; - private JCheckBox myAllowToSendUsagesCheckBox; - private JLabel myLabel; - - public StatisticsConfigurationComponent() { - String product = ApplicationNamesInfo.getInstance().getFullProductName(); - String company = ApplicationInfo.getInstance().getCompanyName(); - myTitle.setText(StatisticsBundle.message("stats.title", product, company)); - myLabel.setText(StatisticsBundle.message("stats.config.details", company)); - RelativeFont.SMALL.install(myLabel); - - myAllowToSendUsagesCheckBox.setText(StatisticsBundle.message("stats.config.allow.send.stats.text", company)); - - // Let current statistics service override labels - StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); - if (service != null) { - Map overrides = service.getStatisticsConfigurationLabels(); - if (overrides != null) { - String s = overrides.get(StatisticsService.TITLE); - if (s != null) { - myTitle.setText(s); - } - s = overrides.get(StatisticsService.DETAILS); - if (s != null) { - myLabel.setText(s); - } - s = overrides.get(StatisticsService.ALLOW_CHECKBOX); - if (s != null) { - myAllowToSendUsagesCheckBox.setText(s); - } - } - } - - myTitle.setText(myTitle.getText().replace("%company%", company)); - myLabel.setText(myLabel.getText().replace("%company%", company)); - myAllowToSendUsagesCheckBox.setText(myAllowToSendUsagesCheckBox.getText().replace("%company%", company)); - } - - public JPanel getJComponent() { - return myMainPanel; - } - - public boolean isAllowed() { - return myAllowToSendUsagesCheckBox.isSelected(); - } - - public void reset() { - myAllowToSendUsagesCheckBox.setSelected(UsageStatisticsPersistenceComponent.getInstance().isAllowed()); - } - - public SendPeriod getPeriod() { - return SendPeriod.DAILY; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java index 113a24249b0a..451ab4946533 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java @@ -2,6 +2,7 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.beans.ConvertUsagesUtil; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -25,7 +26,6 @@ import java.util.Set; public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersistenceComponent implements NamedComponent, PersistentStateComponent { - @NonNls private boolean isAllowed = false; @NonNls private boolean isShowNotification = true; @NotNull private SendPeriod myPeriod = SendPeriod.DAILY; @@ -73,8 +73,11 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste setSentTime(0); } + // compatibility: if was previously allowed, transfer the setting to the new place final String isAllowedValue = element.getAttributeValue(IS_ALLOWED_ATTR); - setAllowed(!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)); + if (!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)) { + setAllowed(true); + } final String isShowNotificationValue = element.getAttributeValue(SHOW_NOTIFICATION_ATTR); setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) || Boolean.parseBoolean(isShowNotificationValue)); @@ -100,9 +103,9 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste element.setAttribute(LAST_TIME_ATTR, String.valueOf(lastTimeSent)); } - if (isAllowed()) { - element.setAttribute(IS_ALLOWED_ATTR, "true"); - } + //if (isAllowed()) { + // element.setAttribute(IS_ALLOWED_ATTR, "true"); + //} if (!isShowNotification()) { element.setAttribute(SHOW_NOTIFICATION_ATTR, "false"); } @@ -131,12 +134,12 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste } public void setAllowed(boolean allowed) { - isAllowed = allowed; + ConsentOptions.getInstance().setSendingUsageStatsAllowed(allowed); } @Override public boolean isAllowed() { - return isAllowed; + return ConsentOptions.getInstance().isSendingUsageStatsAllowed() == ConsentOptions.Permission.YES; } public void setShowNotification(boolean showNotification) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java index 327cbc773727..4293d84393c8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java @@ -1,19 +1,18 @@ package com.intellij.internal.statistic.updater; -import com.intellij.internal.statistic.configurable.StatisticsConfigurable; +import com.intellij.ide.gdpr.Consent; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.connect.StatisticsService; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.wm.IdeFrame; -import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.ui.AppUIUtil; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import javax.swing.event.HyperlinkEvent; +import java.util.Collection; public class StatisticsNotificationManager { @@ -56,9 +55,10 @@ public class StatisticsNotificationManager { notification.expire(); } else if ("settings".equals(description)) { - final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); - IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable(true)); + final Collection result = AppUIUtil.confirmConsentOptions(ConsentOptions.getInstance().getConsents().first); + if (result != null) { + ConsentOptions.getInstance().setConsents(result); + } notification.expire(); } } diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index c9d827d3c0be..0893de4ea8b1 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -253,7 +253,7 @@ public class AppUIUtil { return iconPath; } - public static void showEndUserAgreement() { + public static void showUserAgreementAndConsentsIfNeeded() { if (ApplicationInfoImpl.getShadowInstance().isVendorJetBrains()) { EndUserAgreement.Document agreement = EndUserAgreement.getLatestDocument(); if (!agreement.isAccepted()) { diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 64f5bdbaed2b..ae273649247b 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -415,9 +415,6 @@ - - diff --git a/platform/platform-resources/src/PrivacyPolicy.html b/platform/platform-resources/src/PrivacyPolicy.html index c3fc6051e6fc..f89b18f35323 100644 --- a/platform/platform-resources/src/PrivacyPolicy.html +++ b/platform/platform-resources/src/PrivacyPolicy.html @@ -1,4 +1,4 @@ - + @@ -12,7 +12,7 @@

This Policy may be amended from time to time. The respective latest version of the policy at the point of time of the purchase/registration of a JetBrains Software Product (whichever occurs later) shall apply. The data controller is JetBrains s.r.o., Praha 4, Na hřebenech - II 1718/10, PSČ 147 00, Česká republika + II 1718/10, PSČ 140 00, Česká republika

In this Privacy Policy, we describe the type of data, including personal data (collectively, “data”), @@ -297,9 +297,6 @@ Website works

  • For security purposes
  • -
  • Make sure you connect to the right service on our Website when we make any changes to the way the - Website works -
  • Accepting these cookies is a condition of using the Website, so if you prevent these cookies we can't diff --git a/platform/platform-resources/src/consents.json b/platform/platform-resources/src/consents.json new file mode 100644 index 000000000000..a44ef27787b9 --- /dev/null +++ b/platform/platform-resources/src/consents.json @@ -0,0 +1,9 @@ +[ + { + "consentId": "rsch.send.usage.stat", + "version": "1.0", + "text": "I consent to submit anonymous usage statistics to help JetBrains improve their products. I agree that the following information will be sent to JetBrains and processed in accordance with JetBrains Privacy Policy https://www.jetbrains.com/company/privacy.html\n * Information about which product features are used\n * General statistics (number of files, file types) of the solutions I am working on\n * General information about my hardware configuration (for example, amount of RAM, CPU speed and number of cores)\n * General information about my software configuration (for example, OS version)\nI can revoke my consent at any time in this Data Sharing Options dialog available at Help | Data Sharing Options", + "printableName": "Send anonymous usage statistics to JetBrains", + "accepted": "false" + } +] \ No newline at end of file