Skip to content

Commit c82ee0e

Browse files
committed
feat: analytics interface in :common
1 parent 75247c1 commit c82ee0e

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

  • common/src/main/java/com/ichi2/anki/common/analytics
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2026 Ashish Yadav <mailtoashish693@gmail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 3 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
package com.ichi2.anki.common.analytics
17+
18+
import androidx.annotation.VisibleForTesting
19+
20+
/**
21+
* Interface for analytics tracking.
22+
*
23+
* Implemented in the app module (e.g. by `AnkiDroidUsageAnalytics`).
24+
* Feature modules should use [Analytics] object to send events.
25+
*/
26+
interface UsageAnalytics {
27+
/**
28+
* Send a detailed arbitrary analytics event, with noun/verb pairs and extra data if needed.
29+
*
30+
* @param category the category of event, make your own but use a constant so reporting is good
31+
* @param action the action the user performed
32+
* @param value a value for the event
33+
* @param label a label for the event
34+
*/
35+
fun sendAnalyticsEvent(
36+
category: String,
37+
action: String,
38+
value: Int? = null,
39+
label: String? = null,
40+
)
41+
42+
/**
43+
* Submit a screen for aggregation / analysis.
44+
* Intended for use to determine if / how features are being used.
45+
*
46+
* @param screen the result of [Class.getSimpleName] will be used as the screen tag
47+
*/
48+
fun sendAnalyticsScreenView(screen: Any) {
49+
sendAnalyticsScreenView(screen.javaClass.simpleName)
50+
}
51+
52+
/**
53+
* Submit a screen display with a synthetic name for aggregation / analysis.
54+
* Intended for use if your class handles multiple screens you want to track separately.
55+
*
56+
* @param screenName the name to show in analysis reports
57+
*/
58+
fun sendAnalyticsScreenView(screenName: String)
59+
}
60+
61+
/**
62+
* Global accessor for analytics. Delegates to the [UsageAnalytics] implementation
63+
* set during app initialization.
64+
*
65+
* Usage:
66+
* ```
67+
* Analytics.sendAnalyticsEvent("Widget", "enabled")
68+
* Analytics.sendAnalyticsScreenView("DeckPicker")
69+
* ```
70+
*/
71+
object Analytics {
72+
lateinit var instance: UsageAnalytics
73+
private set
74+
75+
fun setAnalytics(analytics: UsageAnalytics) {
76+
instance = analytics
77+
}
78+
79+
@VisibleForTesting
80+
fun getAnalytics(): UsageAnalytics = instance
81+
82+
fun sendAnalyticsEvent(
83+
category: String,
84+
action: String,
85+
value: Int? = null,
86+
label: String? = null,
87+
) = instance.sendAnalyticsEvent(category, action, value, label)
88+
89+
fun sendAnalyticsScreenView(screen: Any) = instance.sendAnalyticsScreenView(screen)
90+
91+
fun sendAnalyticsScreenView(screenName: String) = instance.sendAnalyticsScreenView(screenName)
92+
}

0 commit comments

Comments
 (0)