Skip to content

Commit d17f1bc

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/#51-duration-tracking
# Conflicts: # lib/build.gradle.kts # lib/src/test/java/com/telemetrydeck/sdk/TelemetryDeckTests.kt
2 parents eeebeda + 99bb2c7 commit d17f1bc

File tree

16 files changed

+317
-65
lines changed

16 files changed

+317
-65
lines changed

.github/workflows/publish.yml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
name: Publish to Maven Central
2-
3-
on:
4-
push:
5-
tags:
6-
- "[0-9]+.[0-9]+.[0-9]+*"
7-
8-
jobs:
9-
publish:
10-
name: Publish to Sonatype
11-
runs-on: ubuntu-latest
12-
steps:
13-
- name: Checkout
14-
uses: actions/checkout@v4
15-
16-
- name: Configure JDK
17-
uses: actions/setup-java@v4
18-
with:
19-
distribution: 'temurin'
20-
java-version: '17'
21-
22-
- name: Setup Gradle
23-
uses: gradle/actions/setup-gradle@v4
24-
25-
- name: Upload Artifacts
26-
# gradle.properties must be set with SONATYPE_HOST=CENTRAL_PORTAL and RELEASE_SIGNING_ENABLED=true
27-
run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache
28-
env:
29-
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralUsername }}
30-
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
31-
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
32-
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyId }}
33-
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyPassword }}
1+
#name: Publish to Maven Central
2+
#
3+
#on:
4+
# push:
5+
# tags:
6+
# - "[0-9]+.[0-9]+.[0-9]+*"
7+
#
8+
#jobs:
9+
# publish:
10+
# name: Publish to Sonatype
11+
# runs-on: ubuntu-latest
12+
# steps:
13+
# - name: Checkout
14+
# uses: actions/checkout@v4
15+
#
16+
# - name: Configure JDK
17+
# uses: actions/setup-java@v4
18+
# with:
19+
# distribution: 'temurin'
20+
# java-version: '17'
21+
#
22+
# - name: Setup Gradle
23+
# uses: gradle/actions/setup-gradle@v4
24+
#
25+
# - name: Upload Artifacts
26+
# # gradle.properties must be set with SONATYPE_HOST=CENTRAL_PORTAL and RELEASE_SIGNING_ENABLED=true
27+
# run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache
28+
# env:
29+
# ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralUsername }}
30+
# ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
31+
# ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
32+
# ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyId }}
33+
# ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyPassword }}

README.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The Kotlin SDK for TelemetryDeck is available from Maven Central and can be used
1010

1111
```groovy
1212
dependencies {
13-
implementation 'com.telemetrydeck:kotlin-sdk:4.0.2'
13+
implementation 'com.telemetrydeck:kotlin-sdk:4.0.5'
1414
}
1515
```
1616

@@ -148,9 +148,41 @@ By default, Kotlin SDK for TelemetryDeck will include the following environment
148148

149149
See [Custom Telemetry](#custom-telemetry) on how to implement your own parameter enrichment.
150150

151+
## Default Parameters
152+
153+
If there are parameters you would like to include with every outgoing signal, you can use `DefaultParameterProvider` instead of passing them with every call.
154+
155+
```kotlin
156+
// create an instance of [DefaultParameterProvider] and pass the key value you wish to be appended to every signal
157+
val provider = DefaultParameterProvider(mapOf("key" to "value"))
158+
159+
// add the provider when configuring an instance of TelemetryDeck
160+
161+
val builder = TelemetryDeck.Builder()
162+
.appID("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
163+
.addProvider(provider)
164+
```
165+
166+
## Default prefix
167+
168+
If you find yourself prepending the same prefix for to your custom signals or parameters,
169+
you can optionally configure `TelemetryDeck` to do this for you by activating our `DefaultPrefixProvider`:
170+
171+
172+
```kotlin
173+
// create an instance of [DefaultPrefixProvider] with a signal or parameter prefix
174+
val provider = DefaultPrefixProvider("MyApp.", "MyApp.Params.")
175+
176+
// add the provider when configuring an instance of TelemetryDeck
177+
178+
val builder = TelemetryDeck.Builder()
179+
.appID("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
180+
.addProvider(provider)
181+
```
182+
151183
## Custom Telemetry
152184

153-
Another way to send signals is to register a custom `TelemetryDeckProvider`.
185+
Another way to send signals is to implement a custom `TelemetryDeckProvider`.
154186
A provider uses the TelemetryDeck client in order to queue or send signals based on environment or other triggers.
155187

156188

@@ -216,6 +248,8 @@ You can also completely disable or override the default providers with your own.
216248
- `EnvironmentParameterProvider` - Adds environment and device information to outgoing Signals. This provider overrides the `enrich` method in order to append additional metadata for all signals before sending them.
217249
- `PlatformContextProvider` - Adds environment and device information which may change over time like the current timezone and screen metrics.
218250

251+
For a complete list, check the `com.telemetrydeck.sdk.providers` package.
252+
219253
```kotlin
220254
// Append a custom provider
221255
val builder = TelemetryDeck.Builder()
@@ -303,7 +337,6 @@ After:
303337

304338
### Custom Telemetry
305339

306-
307340
Your custom providers must replace `TelemetryProvider` with `TelemetryDeckProvider`.
308341

309342
To adopt the new interface:

build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ plugins {
22
alias(libs.plugins.androidLibrary) apply false
33
alias(libs.plugins.kotlin.android) apply false
44
alias(libs.plugins.kotlin.serialization) apply false
5-
alias(libs.plugins.kotlin.compose) apply false
65
alias(libs.plugins.vanniktech.publish) apply false
76
}

gradle/libs.versions.toml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
[versions]
2-
agp = "8.7.3"
2+
agp = "8.8.0"
33
kotlin = "2.0.20"
4-
coreKtx = "1.13.1"
4+
coreKtx = "1.15.0"
55
junit = "4.13.2"
66
junitVersion = "1.2.1"
77
espressoCore = "3.6.1"
88
lifecycleRuntimeKtx = "2.8.7"
9-
activityCompose = "1.9.3"
10-
composeBom = "2024.10.00"
9+
activityCompose = "1.10.0"
10+
composeBom = "2024.04.01"
1111
ktor = "3.0.2"
1212
kotlinx = "1.7.3"
13-
coroutines = "1.9.0"
13+
coroutines = "1.10.1"
1414
vanniktech-publish = "0.30.0"
1515
appcompat = "1.7.0"
1616
mockk = "1.13.13"
@@ -50,5 +50,4 @@ androidx-jUnitTestRules = { module = "androidx.test:rules", version.ref = "andro
5050
androidLibrary = { id = "com.android.library", version.ref = "agp" }
5151
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
5252
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
53-
vanniktech-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech-publish" }
54-
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
53+
vanniktech-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech-publish" }

lib/build.gradle.kts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ plugins {
55
alias(libs.plugins.androidLibrary)
66
alias(libs.plugins.kotlin.android)
77
alias(libs.plugins.kotlin.serialization)
8-
alias(libs.plugins.kotlin.compose)
98
alias(libs.plugins.vanniktech.publish)
109
}
1110

@@ -44,7 +43,7 @@ android {
4443
jvmTarget = "11"
4544
}
4645
buildFeatures {
47-
compose = true
46+
compose = false
4847
buildConfig = true
4948
}
5049

@@ -68,10 +67,6 @@ dependencies {
6867
implementation(libs.androidx.core.ktx)
6968
implementation(libs.androidx.lifecycle.runtime.ktx)
7069
implementation(libs.androidx.lifecycle.process)
71-
// explicit dependency on compose seems to be required to use the compose compiler
72-
// this is not used by the library atm
73-
implementation(libs.androidx.activity.compose)
74-
implementation(platform(libs.androidx.compose.bom))
7570
implementation(libs.androidx.appcompat)
7671
implementation(libs.ktor.client.core)
7772
implementation(libs.kotlinx.coroutines.core)
@@ -86,14 +81,16 @@ dependencies {
8681

8782
testImplementation(libs.junit)
8883
testImplementation(libs.androidx.arch.core)
89-
84+
// As of Kotlin 2.0, the Compose Compiler and runtime are required in the classpath https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compiler.html
85+
testImplementation(libs.androidx.activity.compose)
86+
testImplementation(platform(libs.androidx.compose.bom))
9087
androidTestImplementation(libs.androidx.junit)
9188
androidTestImplementation(libs.androidx.espresso.core)
9289
androidTestImplementation(platform(libs.androidx.compose.bom))
9390
androidTestImplementation(libs.androidx.ui.test.junit4)
9491
androidTestImplementation(libs.androidx.jUnitTestRules)
95-
debugImplementation(libs.androidx.ui.tooling)
96-
debugImplementation(libs.androidx.ui.test.manifest)
92+
androidTestImplementation(libs.androidx.ui.tooling)
93+
androidTestImplementation(libs.androidx.ui.test.manifest)
9794

9895
testImplementation(libs.mockk)
9996
testImplementation(libs.mockk.android)
@@ -102,7 +99,7 @@ dependencies {
10299
}
103100

104101
mavenPublishing {
105-
coordinates("com.telemetrydeck", "kotlin-sdk", "4.0.2")
102+
coordinates("com.telemetrydeck", "kotlin-sdk", "4.0.5")
106103

107104
pom {
108105
name = "TelemetryDeck SDK"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.telemetrydeck.sdk
2+
3+
data class SignalTransform(val signalType: String, val clientUser: String?, val additionalPayload: Map<String, String>, val floatValue: Double?)

lib/src/main/java/com/telemetrydeck/sdk/TelemetryDeck.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,27 @@ class TelemetryDeck(
178178
enrichedPayload = provider.enrich(signalType, clientUser, enrichedPayload)
179179
}
180180

181-
val userValue = identityProvider.calculateIdentity(clientUser, configuration.defaultUser)
181+
var signalTransform = SignalTransform(signalType, clientUser, enrichedPayload, floatValue)
182+
for (provider in this.providers) {
183+
signalTransform = provider.transform(signalTransform)
184+
}
185+
return signalFromTransform(signalTransform)
186+
}
187+
188+
private fun signalFromTransform(signalTransform: SignalTransform): Signal {
189+
val userValue = identityProvider.calculateIdentity(signalTransform.clientUser, configuration.defaultUser)
182190

183191
val userValueWithSalt = userValue + (configuration.salt ?: "")
184192
val hashedUser = hashString(userValueWithSalt)
185193

186-
val payload = SignalPayload(additionalPayload = enrichedPayload)
194+
val payload = SignalPayload(additionalPayload = signalTransform.additionalPayload)
187195
val signal = Signal(
188196
appID = configuration.telemetryAppID,
189-
type = signalType,
197+
type = signalTransform.signalType,
190198
clientUser = hashedUser,
191199
payload = payload.asMultiValueDimension,
192200
isTestMode = configuration.testMode.toString().lowercase(),
193-
floatValue = floatValue
201+
floatValue = signalTransform.floatValue
194202
)
195203
signal.sessionID = this.configuration.sessionID.toString()
196204
logger?.debug("Created a signal ${signal.type}, session ${signal.sessionID}, test ${signal.isTestMode}")

lib/src/main/java/com/telemetrydeck/sdk/TelemetryDeckProvider.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface TelemetryDeckProvider {
2121
* A provider can override this method in order to append or remove telemetry metadata from Signals
2222
* before they are enqueued for broadcast.
2323
*
24-
* TelemetryManager calls this method all providers in order of registration.
24+
* TelemetryManager calls this method on all providers in order of registration.
2525
*/
2626
fun enrich(
2727
signalType: String,
@@ -30,4 +30,17 @@ interface TelemetryDeckProvider {
3030
): Map<String, String> {
3131
return additionalPayload
3232
}
33-
}
33+
34+
/**
35+
* A provider can override this method in order apply a transformation on any part of the signal, including the signal name.
36+
* [TelemetryDeck] calls this method on all providers in order of registration.
37+
*
38+
* This method is always called **after** [enrich].
39+
*/
40+
fun transform(
41+
signalTransform: SignalTransform
42+
): SignalTransform {
43+
return signalTransform
44+
}
45+
}
46+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.telemetrydeck.sdk.providers
2+
3+
import android.app.Application
4+
import com.telemetrydeck.sdk.TelemetryDeckProvider
5+
import com.telemetrydeck.sdk.TelemetryDeckSignalProcessor
6+
7+
8+
/**
9+
* [DefaultParameterProvider] is a [TelemetryDeckProvider] that adds default parameters
10+
* to every telemetry signal. It ensures that signals are enriched with predefined data,
11+
* unless the signal already contains a value for the same key.
12+
*
13+
* @property defaultParameters A map of key-value pairs representing the default parameters
14+
* that will be added to each telemetry signal.
15+
*/
16+
class DefaultParameterProvider(val defaultParameters: Map<String, String>): TelemetryDeckProvider {
17+
override fun register(ctx: Application?, client: TelemetryDeckSignalProcessor) {
18+
// nothing to do
19+
}
20+
21+
override fun stop() {
22+
// nothing to do
23+
}
24+
25+
override fun enrich(
26+
signalType: String,
27+
clientUser: String?,
28+
additionalPayload: Map<String, String>
29+
): Map<String, String> {
30+
val signalPayload = additionalPayload.toMutableMap()
31+
for (item in defaultParameters) {
32+
if (!signalPayload.containsKey(item.key)) {
33+
signalPayload[item.key] = item.value
34+
}
35+
}
36+
return signalPayload
37+
}
38+
}

0 commit comments

Comments
 (0)