FUS: allow setting plugin info during validation stage

GitOrigin-RevId: 7bafe600f67cb38764c711bb1e6e62ed1ba76195
This commit is contained in:
Svetlana.Zemlyanskaya
2019-05-21 15:13:48 +03:00
committed by intellij-monorepo-bot
parent 1d30fad9a0
commit 3c8b8185d3
6 changed files with 45 additions and 33 deletions
@@ -4,7 +4,10 @@ package com.intellij.internal.statistic.collectors.fus;
import com.intellij.internal.statistic.eventLog.validator.ValidationResultType;
import com.intellij.internal.statistic.eventLog.validator.rules.EventContext;
import com.intellij.internal.statistic.eventLog.validator.rules.impl.CustomUtilsWhiteListRule;
import com.intellij.internal.statistic.utils.PluginInfo;
import com.intellij.internal.statistic.utils.PluginInfoDetectorKt;
import com.intellij.internal.statistic.utils.PluginType;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -17,8 +20,18 @@ public class ClassNameRuleValidator extends CustomUtilsWhiteListRule {
@NotNull
@Override
protected ValidationResultType doValidate(@NotNull String data, @NotNull EventContext context) {
if (data.equals("third.party")) return ValidationResultType.ACCEPTED;
final boolean isFromPluginRepository = PluginInfoDetectorKt.getPluginInfo(data).isSafeToReport();
return isFromPluginRepository ? ValidationResultType.ACCEPTED : ValidationResultType.REJECTED;
if (ValidationResultType.THIRD_PARTY.getDescription().equals(data)) return ValidationResultType.ACCEPTED;
final PluginInfo info = PluginInfoDetectorKt.getPluginInfo(data);
if (StringUtil.equals(context.eventId, data)) {
// set plugin info only if it's coming from event id otherwise behavior might be non-deterministic
context.setPluginInfo(info);
}
if (info.getType() == PluginType.UNKNOWN) {
// if we can't detect a plugin then probably it's not a class name
return ValidationResultType.REJECTED;
}
return info.isSafeToReport() ? ValidationResultType.ACCEPTED : ValidationResultType.THIRD_PARTY;
}
}
@@ -3,6 +3,7 @@ package com.intellij.internal.statistic.eventLog
import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
import com.intellij.internal.statistic.utils.PluginInfo
import com.intellij.internal.statistic.utils.addPluginInfoTo
import com.intellij.internal.statistic.utils.getPluginType
import com.intellij.internal.statistic.utils.getProjectId
import com.intellij.lang.Language
@@ -84,10 +85,7 @@ class FeatureUsageData {
}
fun addPluginInfo(info: PluginInfo): FeatureUsageData {
data["plugin_type"] = info.type.name
if (info.type.isSafeToReport() && info.id != null && StringUtil.isNotEmpty(info.id)) {
data["plugin"] = info.id
}
addPluginInfoTo(info, data)
return this
}
@@ -4,11 +4,9 @@ package com.intellij.internal.statistic.eventLog.fus
import com.intellij.internal.statistic.eventLog.FeatureUsageData
import com.intellij.internal.statistic.eventLog.FeatureUsageUiEvents
import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger
import com.intellij.internal.statistic.utils.getPluginInfo
import com.intellij.openapi.ui.DialogWrapper
private const val DIALOGS = "ui.dialogs"
private const val DIALOGS_DEFAULT = "third.party"
class FeatureUsageUiEventsImpl : FeatureUsageUiEvents {
private val SELECT_CONFIGURABLE_DATA = FeatureUsageData().addData("type", "select")
@@ -31,35 +29,18 @@ class FeatureUsageUiEventsImpl : FeatureUsageUiEvents {
override fun logShowDialog(name: String, context: Class<*>) {
if (FeatureUsageLogger.isEnabled()) {
val data = SHOW_DIALOG_DATA.copy()
val report = toReport(context, name, DIALOGS_DEFAULT, data)
FUCounterUsageLogger.getInstance().logEvent(DIALOGS, report, data)
FUCounterUsageLogger.getInstance().logEvent(DIALOGS, name, SHOW_DIALOG_DATA)
}
}
override fun logCloseDialog(name: String, exitCode: Int, context: Class<*>) {
if (FeatureUsageLogger.isEnabled()) {
val data = getDataForCloseDialog(exitCode).copy()
val report = toReport(context, name, DIALOGS_DEFAULT, data)
FUCounterUsageLogger.getInstance().logEvent(DIALOGS, report, data)
val data = when (exitCode) {
DialogWrapper.OK_EXIT_CODE -> CLOSE_OK_DIALOG_DATA
DialogWrapper.CANCEL_EXIT_CODE -> CLOSE_CANCEL_DIALOG_DATA
else -> CLOSE_CUSTOM_DIALOG_DATA
}
FUCounterUsageLogger.getInstance().logEvent(DIALOGS, name, data)
}
}
private fun getDataForCloseDialog(exitCode: Int): FeatureUsageData {
if (exitCode == DialogWrapper.OK_EXIT_CODE) {
return CLOSE_OK_DIALOG_DATA
}
else if (exitCode == DialogWrapper.CANCEL_EXIT_CODE) {
return CLOSE_CANCEL_DIALOG_DATA
}
else {
return CLOSE_CUSTOM_DIALOG_DATA
}
}
private fun toReport(context: Class<*>, name: String, defaultValue: String, data: FeatureUsageData): String {
val info = getPluginInfo(context)
data.addPluginInfo(info)
return if (info.isDevelopedByJetBrains()) name else defaultValue
}
}
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import static com.intellij.internal.statistic.eventLog.validator.ValidationResultType.*;
import static com.intellij.internal.statistic.utils.StatisticsUtilKt.addPluginInfoTo;
public class SensitiveDataValidator {
private static final Logger LOG = Logger.getInstance("com.intellij.internal.statistic.eventLog.validator.SensitiveDataValidator");
@@ -73,6 +74,10 @@ public class SensitiveDataValidator {
ValidationResultType resultType = validateEventData(context, whiteListRule, key, entryValue);
validatedData.put(key, resultType == ACCEPTED ? entryValue : resultType.getDescription());
}
if (context.pluginInfo != null && !(validatedData.containsKey("plugin") || validatedData.containsKey("plugin_type"))) {
addPluginInfoTo(context.pluginInfo, validatedData);
}
return validatedData;
}
@@ -2,6 +2,7 @@
package com.intellij.internal.statistic.eventLog.validator.rules;
import com.intellij.internal.statistic.eventLog.LogEventsKt;
import com.intellij.internal.statistic.utils.PluginInfo;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -12,13 +13,19 @@ import static com.intellij.internal.statistic.eventLog.LogEventsKt.copyEscaped;
public class EventContext {
public final String eventId;
public final Map<String, Object> eventData;
public PluginInfo pluginInfo;
private EventContext(@NotNull String eventId, @NotNull Map<String, Object> eventData) {
this.eventId = LogEventsKt.escape(eventId);
this.eventData = ContainerUtil.unmodifiableOrEmptyMap(copyEscaped(eventData));
this.pluginInfo = null;
}
public static EventContext create(@NotNull String eventId, @NotNull Map<String, Object> eventData) {
return new EventContext(eventId, eventData);
}
public void setPluginInfo(@NotNull PluginInfo info) {
this.pluginInfo = info;
}
}
@@ -16,6 +16,7 @@ import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.Getter
import com.intellij.openapi.util.ModificationTracker
import com.intellij.openapi.util.TimeoutCachedValue
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.containers.ObjectIntHashMap
import gnu.trove.THashSet
import java.io.IOException
@@ -30,6 +31,13 @@ fun createData(project: Project?, context: FUSUsageContext?): Map<String, Any> {
return newData(project, context)
}
fun addPluginInfoTo(info: PluginInfo, data : MutableMap<String, Any>) {
data["plugin_type"] = info.type.name
if (info.type.isSafeToReport() && info.id != null && StringUtil.isNotEmpty(info.id)) {
data["plugin"] = info.id
}
}
fun isDevelopedByJetBrains(pluginId: PluginId?): Boolean {
val plugin = PluginManager.getPlugin(pluginId)
return plugin == null || PluginManagerMain.isDevelopedByJetBrains(plugin.vendor)