Skip to content

Commit 6182a2d

Browse files
committed
RUM-9471: Add locale attributes
1 parent fbd5b1b commit 6182a2d

File tree

19 files changed

+300
-18
lines changed

19 files changed

+300
-18
lines changed

dd-sdk-android-core/api/apiSurface

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ data class com.datadog.android.api.context.AccountInfo
7171
data class com.datadog.android.api.context.DatadogContext
7272
constructor(com.datadog.android.DatadogSite, String, String, String, String, String, String, String, TimeInfo, ProcessInfo, NetworkInfo, DeviceInfo, UserInfo, AccountInfo?, com.datadog.android.privacy.TrackingConsent, String?, Map<String, Map<String, Any?>>)
7373
data class com.datadog.android.api.context.DeviceInfo
74-
constructor(String, String, String, DeviceType, String, String, String, String, String, Int?)
74+
constructor(String, String, String, DeviceType, String, String, String, String, String, Int?, LocaleInfo)
7575
enum com.datadog.android.api.context.DeviceType
7676
- MOBILE
7777
- TABLET
@@ -80,6 +80,8 @@ enum com.datadog.android.api.context.DeviceType
8080
- GAMING_CONSOLE
8181
- BOT
8282
- OTHER
83+
data class com.datadog.android.api.context.LocaleInfo
84+
constructor(List<String>, String, String)
8385
data class com.datadog.android.api.context.NetworkInfo
8486
constructor(Connectivity = Connectivity.NETWORK_NOT_CONNECTED, kotlin.String? = null, kotlin.Long? = null, kotlin.Long? = null, kotlin.Long? = null, kotlin.Long? = null, kotlin.String? = null)
8587
enum Connectivity

dd-sdk-android-core/api/dd-sdk-android-core.api

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,10 @@ public final class com/datadog/android/api/context/DatadogContext {
214214
}
215215

216216
public final class com/datadog/android/api/context/DeviceInfo {
217-
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)V
217+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/context/LocaleInfo;)V
218218
public final fun component1 ()Ljava/lang/String;
219219
public final fun component10 ()Ljava/lang/Integer;
220+
public final fun component11 ()Lcom/datadog/android/api/context/LocaleInfo;
220221
public final fun component2 ()Ljava/lang/String;
221222
public final fun component3 ()Ljava/lang/String;
222223
public final fun component4 ()Lcom/datadog/android/api/context/DeviceType;
@@ -225,15 +226,16 @@ public final class com/datadog/android/api/context/DeviceInfo {
225226
public final fun component7 ()Ljava/lang/String;
226227
public final fun component8 ()Ljava/lang/String;
227228
public final fun component9 ()Ljava/lang/String;
228-
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)Lcom/datadog/android/api/context/DeviceInfo;
229-
public static synthetic fun copy$default (Lcom/datadog/android/api/context/DeviceInfo;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;ILjava/lang/Object;)Lcom/datadog/android/api/context/DeviceInfo;
229+
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/context/LocaleInfo;)Lcom/datadog/android/api/context/DeviceInfo;
230+
public static synthetic fun copy$default (Lcom/datadog/android/api/context/DeviceInfo;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/api/context/DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lcom/datadog/android/api/context/LocaleInfo;ILjava/lang/Object;)Lcom/datadog/android/api/context/DeviceInfo;
230231
public fun equals (Ljava/lang/Object;)Z
231232
public final fun getArchitecture ()Ljava/lang/String;
232233
public final fun getDeviceBrand ()Ljava/lang/String;
233234
public final fun getDeviceBuildId ()Ljava/lang/String;
234235
public final fun getDeviceModel ()Ljava/lang/String;
235236
public final fun getDeviceName ()Ljava/lang/String;
236237
public final fun getDeviceType ()Lcom/datadog/android/api/context/DeviceType;
238+
public final fun getLocaleInfo ()Lcom/datadog/android/api/context/LocaleInfo;
237239
public final fun getNumberOfDisplays ()Ljava/lang/Integer;
238240
public final fun getOsMajorVersion ()Ljava/lang/String;
239241
public final fun getOsName ()Ljava/lang/String;
@@ -254,6 +256,21 @@ public final class com/datadog/android/api/context/DeviceType : java/lang/Enum {
254256
public static fun values ()[Lcom/datadog/android/api/context/DeviceType;
255257
}
256258

259+
public final class com/datadog/android/api/context/LocaleInfo {
260+
public fun <init> (Ljava/util/List;Ljava/lang/String;Ljava/lang/String;)V
261+
public final fun component1 ()Ljava/util/List;
262+
public final fun component2 ()Ljava/lang/String;
263+
public final fun component3 ()Ljava/lang/String;
264+
public final fun copy (Ljava/util/List;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/api/context/LocaleInfo;
265+
public static synthetic fun copy$default (Lcom/datadog/android/api/context/LocaleInfo;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/api/context/LocaleInfo;
266+
public fun equals (Ljava/lang/Object;)Z
267+
public final fun getCurrentLocale ()Ljava/lang/String;
268+
public final fun getLocales ()Ljava/util/List;
269+
public final fun getTimeZone ()Ljava/lang/String;
270+
public fun hashCode ()I
271+
public fun toString ()Ljava/lang/String;
272+
}
273+
257274
public final class com/datadog/android/api/context/NetworkInfo {
258275
public fun <init> ()V
259276
public fun <init> (Lcom/datadog/android/api/context/NetworkInfo$Connectivity;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/String;)V

dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/context/DeviceInfo.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package com.datadog.android.api.context
1919
* @property osVersion Full operating system version, e.g. 8.1.1.
2020
* @property architecture The CPU architecture of the device.
2121
* @property numberOfDisplays The number of displays on the device.
22+
* @property localeInfo locale information on the device such as timezone and region settings.
2223
*/
2324
data class DeviceInfo(
2425
val deviceName: String,
@@ -30,5 +31,6 @@ data class DeviceInfo(
3031
val osMajorVersion: String,
3132
val osVersion: String,
3233
val architecture: String,
33-
val numberOfDisplays: Int?
34+
val numberOfDisplays: Int?,
35+
val localeInfo: LocaleInfo
3436
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.api.context
8+
9+
/**
10+
* Provides information about locale.
11+
*
12+
* @property locales Ordered list of the user’s preferred system languages as IETF language tags.
13+
* @property currentLocale The user's current locale as a language tag (language + region), computed from their preferences and the app's supported languages, e.g. 'es-FR'.
14+
* @property timeZone The device’s current time zone identifier, e.g. 'Europe/Berlin'.
15+
*/
16+
data class LocaleInfo(
17+
val locales: List<String>,
18+
val currentLocale: String,
19+
val timeZone: String
20+
)

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/DatadogContextProvider.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package com.datadog.android.core.internal
88

99
import com.datadog.android.api.context.DatadogContext
1010
import com.datadog.android.api.context.DeviceInfo
11+
import com.datadog.android.api.context.LocaleInfo
1112
import com.datadog.android.api.context.ProcessInfo
1213
import com.datadog.android.api.context.TimeInfo
1314
import java.util.concurrent.TimeUnit
@@ -52,7 +53,14 @@ internal class DatadogContextProvider(val coreFeature: CoreFeature) : ContextPro
5253
osVersion = osVersion,
5354
osMajorVersion = osMajorVersion,
5455
architecture = architecture,
55-
numberOfDisplays = numberOfDisplays
56+
numberOfDisplays = numberOfDisplays,
57+
localeInfo = with(coreFeature.androidInfoProvider) {
58+
LocaleInfo(
59+
locales = locales,
60+
currentLocale = currentLocale,
61+
timeZone = timeZone
62+
)
63+
}
5664
)
5765
},
5866
userInfo = coreFeature.userInfoProvider.getUserInfo(),

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/NoOpContextProvider.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.datadog.android.DatadogSite
1010
import com.datadog.android.api.context.DatadogContext
1111
import com.datadog.android.api.context.DeviceInfo
1212
import com.datadog.android.api.context.DeviceType
13+
import com.datadog.android.api.context.LocaleInfo
1314
import com.datadog.android.api.context.NetworkInfo
1415
import com.datadog.android.api.context.ProcessInfo
1516
import com.datadog.android.api.context.TimeInfo
@@ -54,7 +55,12 @@ internal class NoOpContextProvider : ContextProvider {
5455
osMajorVersion = "",
5556
osVersion = "",
5657
architecture = "",
57-
numberOfDisplays = null
58+
numberOfDisplays = null,
59+
localeInfo = LocaleInfo(
60+
locales = emptyList(),
61+
currentLocale = "",
62+
timeZone = ""
63+
)
5864
),
5965
accountInfo = null,
6066
userInfo = UserInfo(null, null, null, null, emptyMap()),

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/AndroidInfoProvider.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,10 @@ internal interface AndroidInfoProvider {
2929
val architecture: String
3030

3131
val numberOfDisplays: Int?
32+
33+
val locales: List<String>
34+
35+
val currentLocale: String
36+
37+
val timeZone: String
3238
}

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/DefaultAndroidInfoProvider.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import android.telephony.TelephonyManager
1616
import android.view.Display
1717
import com.datadog.android.api.context.DeviceType
1818
import java.util.Locale
19+
import java.util.TimeZone
1920

2021
internal class DefaultAndroidInfoProvider(
2122
appContext: Context,
@@ -50,6 +51,46 @@ internal class DefaultAndroidInfoProvider(
5051
}
5152
}
5253

54+
override val locales: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
55+
val resources = appContext.resources
56+
val languageList = mutableListOf<String>()
57+
58+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
59+
val locales = resources.configuration.locales
60+
val localesSize = locales.size()
61+
62+
for (localeIndex in 0 until localesSize) {
63+
locales[localeIndex]?.toLanguageTag()?.let {
64+
languageList.add(it)
65+
}
66+
}
67+
} else {
68+
@Suppress("DEPRECATION")
69+
resources.configuration.locale?.toLanguageTag()?.let {
70+
languageList.add(it)
71+
}
72+
}
73+
74+
languageList
75+
}
76+
77+
override val currentLocale: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
78+
val resources = appContext.resources
79+
val currentLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
80+
resources.configuration.locales[0]?.toLanguageTag()
81+
} else {
82+
@Suppress("DEPRECATION")
83+
resources.configuration.locale?.toLanguageTag()
84+
}
85+
86+
// null shouldn't happen, but if it does this ensures that we return a valid languageTag
87+
currentLocale ?: Locale.getDefault().toLanguageTag()
88+
}
89+
90+
override val timeZone: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
91+
TimeZone.getDefault().id
92+
}
93+
5394
override val deviceBrand: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
5495
rawDeviceBrand.replaceFirstChar {
5596
if (it.isLowerCase()) it.titlecase(Locale.US) else it.toString()

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/system/NoOpAndroidInfoProvider.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ internal class NoOpAndroidInfoProvider : AndroidInfoProvider {
1919
override val osVersion: String = ""
2020
override val architecture: String = ""
2121
override val numberOfDisplays: Int? = null
22+
override val locales: List<String> = emptyList()
23+
override val currentLocale: String = ""
24+
override val timeZone: String = ""
2225
}

dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/DatadogContextProviderTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ internal class DatadogContextProviderTest {
148148
assertThat(context.deviceInfo.osName).isEqualTo(fakeAndroidInfo.osName)
149149
assertThat(context.deviceInfo.osVersion).isEqualTo(fakeAndroidInfo.osVersion)
150150
assertThat(context.deviceInfo.osMajorVersion).isEqualTo(fakeAndroidInfo.osMajorVersion)
151+
assertThat(context.deviceInfo.architecture).isEqualTo(fakeAndroidInfo.architecture)
152+
assertThat(context.deviceInfo.numberOfDisplays).isEqualTo(fakeAndroidInfo.numberOfDisplays)
153+
154+
// locale info
155+
assertThat(context.deviceInfo.localeInfo.locales).isEqualTo(fakeAndroidInfo.locales)
156+
assertThat(context.deviceInfo.localeInfo.currentLocale).isEqualTo(fakeAndroidInfo.currentLocale)
157+
assertThat(context.deviceInfo.localeInfo.timeZone).isEqualTo(fakeAndroidInfo.timeZone)
151158

152159
// user info
153160
assertThat(context.userInfo.id).isEqualTo(fakeUserInfo.id)

0 commit comments

Comments
 (0)