FUS: report file types defined in listed plugins

This commit is contained in:
Svetlana.Zemlyanskaya
2018-11-21 16:36:11 +01:00
parent 6f3ecc5da3
commit 8e95e3f951
5 changed files with 76 additions and 19 deletions
@@ -1,7 +1,11 @@
// Copyright 2000-2018 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.collectors.fus.fileTypes;
import com.intellij.internal.statistic.service.fus.collectors.FUSProjectUsageTrigger;
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsageTriggerCollector;
import com.intellij.internal.statistic.utils.StatisticsUtilKt;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public class FileTypeEditUsageTriggerCollector extends ProjectUsageTriggerCollector {
@@ -11,4 +15,10 @@ public class FileTypeEditUsageTriggerCollector extends ProjectUsageTriggerCollec
public String getGroupId() {
return "statistics.file.types.edit";
}
public static void trigger(@NotNull Project project, @NotNull FileType fileType) {
if (StatisticsUtilKt.getPluginType(fileType.getClass()).isSafeToReport()) {
FUSProjectUsageTrigger.getInstance(project).trigger(FileTypeEditUsageTriggerCollector.class, fileType.getName());
}
}
}
@@ -3,7 +3,6 @@ package com.intellij.internal.statistic.collectors.fus.fileTypes;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.intellij.internal.statistic.service.fus.collectors.FUSProjectUsageTrigger;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -17,6 +16,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.Pair;
@@ -38,7 +38,7 @@ public class FileTypeExtensionUsagesCollectorStartupActivity implements StartupA
myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerListener() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
FUSProjectUsageTrigger.getInstance(project).trigger(FileTypeOpenUsageTriggerCollector.class, file.getFileType().getName());
FileTypeOpenUsageTriggerCollector.trigger(project, file.getFileType());
}
@Override
@@ -66,9 +66,9 @@ public class FileTypeExtensionUsagesCollectorStartupActivity implements StartupA
if (editor == null || editor.getProject() != project) return;
VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
if (file != null) {
String fileType = file.getFileType().getName();
if (EDIT_USAGE_ONE_MINUTE_THROTTLING_CACHE.asMap().putIfAbsent(Pair.create(file.getPath(), fileType), Boolean.TRUE) == null)
FUSProjectUsageTrigger.getInstance(project).trigger(FileTypeEditUsageTriggerCollector.class, fileType);
final FileType fileType = file.getFileType();
if (EDIT_USAGE_ONE_MINUTE_THROTTLING_CACHE.asMap().putIfAbsent(Pair.create(file.getPath(), fileType.getName()), Boolean.TRUE) == null)
FileTypeEditUsageTriggerCollector.trigger(project, fileType);
}
}
@@ -1,7 +1,11 @@
// Copyright 2000-2018 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.collectors.fus.fileTypes;
import com.intellij.internal.statistic.service.fus.collectors.FUSProjectUsageTrigger;
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsageTriggerCollector;
import com.intellij.internal.statistic.utils.StatisticsUtilKt;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public class FileTypeOpenUsageTriggerCollector extends ProjectUsageTriggerCollector {
@@ -11,4 +15,10 @@ public class FileTypeOpenUsageTriggerCollector extends ProjectUsageTriggerCollec
public String getGroupId() {
return "statistics.file.types.open";
}
public static void trigger(@NotNull Project project, @NotNull FileType fileType) {
if (StatisticsUtilKt.getPluginType(fileType.getClass()).isSafeToReport()) {
FUSProjectUsageTrigger.getInstance(project).trigger(FileTypeOpenUsageTriggerCollector.class, fileType.getName());
}
}
}
@@ -3,6 +3,8 @@ package com.intellij.internal.statistic.collectors.fus.fileTypes;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector;
import com.intellij.internal.statistic.utils.PluginType;
import com.intellij.internal.statistic.utils.StatisticsUtilKt;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -46,16 +48,20 @@ public class FileTypeUsagesCollector extends ProjectUsagesCollector {
if (project.isDisposed()) {
return Collections.emptySet();
}
ApplicationManager.getApplication().runReadAction(() -> {
FileTypeIndex.processFiles(fileType, file -> {
//skip files from .idea directory otherwise 99% of projects would have XML and PLAIN_TEXT file types
if (!ProjectKt.getStateStore(project).isProjectFile(file)) {
usedFileTypes.add(fileType);
return false;
}
return true;
}, GlobalSearchScope.projectScope(project));
});
final PluginType type = StatisticsUtilKt.getPluginType(fileType.getClass());
if (type.isSafeToReport()) {
ApplicationManager.getApplication().runReadAction(() -> {
FileTypeIndex.processFiles(fileType, file -> {
//skip files from .idea directory otherwise 99% of projects would have XML and PLAIN_TEXT file types
if (!ProjectKt.getStateStore(project).isProjectFile(file)) {
usedFileTypes.add(fileType);
return false;
}
return true;
}, GlobalSearchScope.projectScope(project));
});
}
}
return ContainerUtil
.map2Set(usedFileTypes, (NotNullFunction<FileType, UsageDescriptor>)fileType -> new UsageDescriptor(fileType.getName(), 1));
@@ -1,10 +1,7 @@
// Copyright 2000-2018 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.utils
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.plugins.PluginManager
import com.intellij.ide.plugins.PluginManagerMain
import com.intellij.ide.plugins.RepositoryHelper
import com.intellij.ide.plugins.*
import com.intellij.internal.statistic.beans.UsageDescriptor
import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
import com.intellij.openapi.application.ApplicationManager
@@ -263,6 +260,40 @@ fun isSafeToReport(pluginId: String?): Boolean {
return pluginId != null && safeToReportPluginIds.contains(pluginId)
}
/**
* Returns if this code is coming from IntelliJ platform, a plugin created by JetBrains (bundled or not) or from official repository,
* so API from it may be reported
*/
fun getPluginType(clazz: Class<*>): PluginType {
val pluginId = PluginManagerCore.getPluginByClassName(clazz.name) ?: return PluginType.PLATFORM
val plugin = PluginManager.getPlugin(pluginId) ?: return PluginType.UNKNOWN
if (PluginManagerMain.isDevelopedByJetBrains(plugin)) {
return if (plugin.isBundled) PluginType.BUNDLED else PluginType.JB_PLUGIN
}
// only plugins installed from some repository (not bundled and not provided via classpath in development IDE instance -
// they are also considered bundled) would be reported
val listed = !plugin.isBundled && isSafeToReport(pluginId.idString)
return if (listed) PluginType.LISTED else PluginType.NOT_LISTED
}
enum class PluginType {
PLATFORM, BUNDLED, JB_PLUGIN, LISTED, NOT_LISTED, UNKNOWN;
fun isBundled() : Boolean {
return this == PLATFORM || this == BUNDLED
}
fun isJBPlugin() : Boolean {
return isBundled() || this == JB_PLUGIN
}
fun isSafeToReport() : Boolean {
return isJBPlugin() || this == LISTED;
}
}
private class DelayModificationTracker internal constructor(delay: Long, unit: TimeUnit) : ModificationTracker {
private val myStamp = System.currentTimeMillis()