Analytics rewrite: generic provider SPI with GDPR consent and multiple backends#5266
Analytics rewrite: generic provider SPI with GDPR consent and multiple backends#5266shai-almog wants to merge 5 commits into
Conversation
…e backends Replace the deprecated Google Analytics v1 AnalyticsService with a generic provider SPI. Apps register one or more AnalyticsProvider implementations with the Analytics facade, which fans screen / event / user-property / crash calls out to all providers after a configurable (opt-in by default) consent gate. Providers: CodenameOneAnalyticsProvider (first-party, batched to the cloud), GoogleAnalyticsProvider (GA4), MatomoAnalyticsProvider (privacy-first, non Google), FirebaseAnalyticsProvider (Android + iOS native peers), and LoggingAnalyticsProvider (simulator / tests). The old AnalyticsService is retained, deprecated, and now delegates to the new API. Adds GDPR features (granular consent persisted across restarts, pseudonymous user-resettable client id), Firebase build-hint dependency injection in the Android (android.firebaseAnalytics) and iOS (ios.firebaseAnalytics) builders, a new developer-guide Analytics chapter, and 25 unit tests. The iOS native peer was verified with a full local arm64 xcodebuild (BUILD SUCCEEDED). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
|
Compared 129 screenshots: 129 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 122 screenshots: 122 matched. |
|
Compared 129 screenshots: 129 matched. Benchmark Results
Detailed Performance Metrics
|
Cloudflare Preview
|
|
Compared 210 screenshots: 210 matched. |
iOS Metal screenshot updatesCompared 129 screenshots: 55 matched, 74 missing actuals.
Benchmark Results
Build and Run Timing
|
|
Compared 125 screenshots: 125 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
The CN1 core (CodenameOne/src) compiles against the CLDC11 bootclasspath, whose StringBuilder has no substring(int,int). Convert to String first in GoogleAnalyticsProvider.sanitizeName so the core/CLDC11 build compiles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The deprecated AnalyticsService now delegates to Analytics, leaving domain / timeout / readTimeout written but never read -- SpotBugs failed the JDK 8 gate on URF_UNREAD_FIELD. Remove the fields; the setters become documented no-ops and the init domain parameter is retained for source compatibility only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make Analytics final (ClassWithOnlyPrivateConstructorsShouldBeFinal) and drop the redundant public modifiers on NativeFirebaseAnalytics interface methods (UnnecessaryModifier). Verified against the full forbidden PMD rule set via mvn verify -- zero forbidden violations across the analytics sources. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
CI LanguageTool (rendered-HTML gate, not runnable locally) flagged British spellings 'behavioural'/'anonymisation' and the proper noun 'Piwik'. Switch to US spelling (behavioral/anonymization, plus honor) and accept-list Piwik. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f4a7d53 to
2422a15
Compare
Summary
Replaces the deprecated Google Analytics v1
AnalyticsServicewith a generic provider SPI. Apps register one or moreAnalyticsProviderimplementations with theAnalyticsfacade, which fansscreen/event/setUserProperty/crashcalls out to all providers — but only after a configurable, opt-in-by-default consent gate.Client (
com.codename1.analytics)Analyticsfacade +AnalyticsProviderSPI (AbstractAnalyticsProviderbase),AnalyticsEvent,AnalyticsConsent,ConsentMode,AnalyticsContext,AnalyticsCrashReport,AnalyticsCapability.resetClientId()); no hardware identifiers.CodenameOneAnalyticsProvider(first-party, batched to the cloud),GoogleAnalyticsProvider(GA4 Measurement Protocol),MatomoAnalyticsProvider(privacy-first, non-Google),FirebaseAnalyticsProvider,LoggingAnalyticsProvider.AnalyticsServiceis retained, deprecated, and delegates to the new API (itsinitswitches the facade to opt-out to preserve historical behaviour).UIBuilderanalytics hook unchanged.Firebase native + builders
NativeFirebaseAnalyticsImpl) via reflection (mirrors the port's FCM pattern); iOS peer as an Objective-C class (com_codename1_analytics_NativeFirebaseAnalyticsImpl) using dynamic dispatch onFIRAnalytics.AndroidGradleBuilder/IPhoneBuilderinject the Firebase Gradle dep /Firebase/Analyticspod, gated on theandroid.firebaseAnalytics/ios.firebaseAnalyticsbuild hints (mirrors the existing FCM/AdMob handling).Docs + tests
docs/developer-guide/Analytics.asciidocchapter (old section replaced with a pointer); passes asciidoctor + Vale + paragraph-cap locally.maven/core-unittests(consent gating, all providers, client id, capabilities, deprecated facade) — all green against a from-source core build.Verification
mvn -o -pl core-unittests -DunitTests=true -Plocal-dev-javase test -Dtest='*Analytics*'→ 25/25 pass.xcodebuild -sdk iphoneos -arch arm64of a sample app → BUILD SUCCEEDED, peer object compiled and linked.🤖 Generated with Claude Code