From 9a675ed05bf4327e8d7b63de79e94312234f0e2b Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 5 Nov 2025 16:13:28 -0800 Subject: [PATCH 1/3] [analytics] initial `sendReport` API --- .../flutter/analytics/UnifiedAnalytics.java | 125 ++++++++++++++++-- 1 file changed, 112 insertions(+), 13 deletions(-) diff --git a/src/io/flutter/analytics/UnifiedAnalytics.java b/src/io/flutter/analytics/UnifiedAnalytics.java index 9775520589..ec5f4f3287 100644 --- a/src/io/flutter/analytics/UnifiedAnalytics.java +++ b/src/io/flutter/analytics/UnifiedAnalytics.java @@ -32,10 +32,9 @@ public class UnifiedAnalytics { private static final @NotNull Logger LOG = PluginLogger.createLogger(UnifiedAnalytics.class); @Nullable Boolean enabled = null; - final Project project; - final DtdUtils dtdUtils; - @NotNull final FlutterSdkUtil flutterSdkUtil; - + final @NotNull Project project; + final @NotNull DtdUtils dtdUtils; + final @NotNull FlutterSdkUtil flutterSdkUtil; public UnifiedAnalytics(@NotNull Project project) { this.project = project; @@ -71,6 +70,52 @@ public void manageConsent() { } } + /** + * Sends an analytics event to the unified analytics service. + * + *

This method constructs and sends an analytics event based on the provided + * {@link AnalyticsData}. It handles the communication with the Dart Tooling Daemon + * and processes the response. + * + * @param analyticsData The data object containing the details of the event to report. + * @return A {@link CompletableFuture} that completes with a {@link SendResult}. + * The {@code SendResult} will indicate whether the report was successfully + * sent and may contain a message with additional details on failure. + * If the analytics service is unavailable or an error occurs, the future + * will complete with a result where {@code success} is false. + */ + public @NotNull CompletableFuture sendReport(AnalyticsData analyticsData) { + try { + DartToolingDaemonService service = dtdUtils.readyDtdService(project).get(); + if (service == null) { + return SendResult.failed("DTD service is null"); + } + + JsonObject params = new JsonObject(); + params.addProperty("tool", getToolName()); + + // TODO (pq): convert analyticsData to params. + + // TODO (pq): hoist request constants into static fields + return makeUnifiedAnalyticsRequest("ideEvent", service, params).thenCompose(result -> { + if (result == null) { + return SendResult.failed("ideEvent result is null"); + } + + JsonPrimitive type = result.getAsJsonPrimitive("type"); + if (type == null) { + return SendResult.failed("ideEvent result type is null"); + } + + return SendResult.succeeded("Success".equals(type.getAsString())); + }); + } + catch (Exception e) { + LOG.info(e); + return SendResult.failed(e.getMessage()); + } + } + private @NotNull CompletableFuture makeUnifiedAnalyticsRequest(String requestName, @NotNull DartToolingDaemonService service, @NotNull JsonObject params) { @@ -168,15 +213,11 @@ public void actionPerformed(@NotNull AnActionEvent event) { private String getToolName() throws Exception { String ideValue = flutterSdkUtil.getFlutterHostEnvValue(); - if ("IntelliJ-IDEA".equals(ideValue)) { - return "intellij-plugins"; - } - else if ("Android-Studio".equals(ideValue)) { - return "android-studio-plugins"; - } - else { - throw new Exception("Tool name cannot be found for IDE type: " + ideValue); - } + return switch (flutterSdkUtil.getFlutterHostEnvValue()) { + case "IntelliJ-IDEA" -> "intellij-plugins"; + case "Android-Studio" -> "android-studio-plugins"; + default -> throw new Exception("Tool name cannot be found for IDE type: " + ideValue); + }; } private @NotNull CompletableFuture shouldShowMessage(@NotNull DartToolingDaemonService service, @NotNull JsonObject params) { @@ -206,3 +247,61 @@ else if ("Android-Studio".equals(ideValue)) { }); } } + +/** + * Represents the result of an analytics sending operation. + *

+ * This class encapsulates whether the operation was successful and includes an + * optional message, typically used for logging errors. + */ +class SendResult { + /** + * True if the analytics report was sent successfully, false otherwise. + */ + public final boolean success; + + /** + * An optional message providing more details about the result, particularly on failure. + */ + public final @Nullable String message; + + /** + * Constructs a new SendResult. + * + * @param success True if the operation was successful, false otherwise. + * @param message An optional descriptive message. + */ + SendResult(boolean success, @Nullable String message) { + this.success = success; + this.message = message; + } + + /** + * Wraps this result instance in a completed CompletableFuture. + * + * @return A CompletableFuture that is already completed with this SendResult instance. + */ + CompletableFuture toCompletedFuture() { + return CompletableFuture.completedFuture(this); + } + + /** + * Creates a CompletableFuture completed with a failed SendResult. + * + * @param message An optional error message describing the failure. + * @return A CompletableFuture completed with a new SendResult indicating failure. + */ + static CompletableFuture failed(@Nullable String message) { + return new SendResult(false, message).toCompletedFuture(); + } + + /** + * Creates a CompletableFuture completed with a successful SendResult. + * + * @param success The success status to record. + * @return A CompletableFuture completed with a new SendResult indicating success. + */ + static CompletableFuture succeeded(boolean success) { + return new SendResult(success, null).toCompletedFuture(); + } +} From 2f647bcf9e4d581a6f56b426c680da7f6a9654f2 Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 5 Nov 2025 16:22:49 -0800 Subject: [PATCH 2/3] doc trim --- .../flutter/analytics/UnifiedAnalytics.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/io/flutter/analytics/UnifiedAnalytics.java b/src/io/flutter/analytics/UnifiedAnalytics.java index ec5f4f3287..65e4e55b24 100644 --- a/src/io/flutter/analytics/UnifiedAnalytics.java +++ b/src/io/flutter/analytics/UnifiedAnalytics.java @@ -73,10 +73,6 @@ public void manageConsent() { /** * Sends an analytics event to the unified analytics service. * - *

This method constructs and sends an analytics event based on the provided - * {@link AnalyticsData}. It handles the communication with the Dart Tooling Daemon - * and processes the response. - * * @param analyticsData The data object containing the details of the event to report. * @return A {@link CompletableFuture} that completes with a {@link SendResult}. * The {@code SendResult} will indicate whether the report was successfully @@ -265,42 +261,19 @@ class SendResult { */ public final @Nullable String message; - /** - * Constructs a new SendResult. - * - * @param success True if the operation was successful, false otherwise. - * @param message An optional descriptive message. - */ SendResult(boolean success, @Nullable String message) { this.success = success; this.message = message; } - /** - * Wraps this result instance in a completed CompletableFuture. - * - * @return A CompletableFuture that is already completed with this SendResult instance. - */ CompletableFuture toCompletedFuture() { return CompletableFuture.completedFuture(this); } - /** - * Creates a CompletableFuture completed with a failed SendResult. - * - * @param message An optional error message describing the failure. - * @return A CompletableFuture completed with a new SendResult indicating failure. - */ static CompletableFuture failed(@Nullable String message) { return new SendResult(false, message).toCompletedFuture(); } - /** - * Creates a CompletableFuture completed with a successful SendResult. - * - * @param success The success status to record. - * @return A CompletableFuture completed with a new SendResult indicating success. - */ static CompletableFuture succeeded(boolean success) { return new SendResult(success, null).toCompletedFuture(); } From a8c6e8371ec33c187843530685d38a5144c81f19 Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 5 Nov 2025 16:23:53 -0800 Subject: [PATCH 3/3] tweak --- src/io/flutter/analytics/UnifiedAnalytics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/flutter/analytics/UnifiedAnalytics.java b/src/io/flutter/analytics/UnifiedAnalytics.java index 65e4e55b24..bb104cbc3d 100644 --- a/src/io/flutter/analytics/UnifiedAnalytics.java +++ b/src/io/flutter/analytics/UnifiedAnalytics.java @@ -71,7 +71,7 @@ public void manageConsent() { } /** - * Sends an analytics event to the unified analytics service. + * Sends analytics data to the unified analytics service. * * @param analyticsData The data object containing the details of the event to report. * @return A {@link CompletableFuture} that completes with a {@link SendResult}.