diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 1d39bab1d17e4fa143c36ee9f6025fd99e4f8a53..344854f2adfcb3ee4a681322626e8ac2c7de7ff5 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -10,7 +10,7 @@ plugins {
val versionMajor = 3
val versionMinor = 2
val versionPatch = 10
-val releasePatch = "2"
+val releasePatch = "3"
val versionName = "${versionMajor}.${versionMinor}.${versionPatch}-${releasePatch}"
diff --git a/lib/src/main/java/com/aurora/gplayapi/data/models/ContentRating.kt b/lib/src/main/java/com/aurora/gplayapi/data/models/ContentRating.kt
index 1cb61e56f56308c67a12e19e7eabe5253657de93..023a332ab2add622391f08c44d5a1fad6d92d1aa 100644
--- a/lib/src/main/java/com/aurora/gplayapi/data/models/ContentRating.kt
+++ b/lib/src/main/java/com/aurora/gplayapi/data/models/ContentRating.kt
@@ -5,6 +5,7 @@ import kotlinx.parcelize.Parcelize
@Parcelize
data class ContentRating(
+ val id: String = String(),
val title: String = String(),
val description: String = String(),
val recommendation: String = String(),
diff --git a/lib/src/main/java/com/aurora/gplayapi/helpers/ContentRatingHelper.kt b/lib/src/main/java/com/aurora/gplayapi/helpers/ContentRatingHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..135f1f5501e52384e1bbf52fbf954f861e611079
--- /dev/null
+++ b/lib/src/main/java/com/aurora/gplayapi/helpers/ContentRatingHelper.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 MURENA SAS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.aurora.gplayapi.helpers
+
+import com.aurora.gplayapi.DetailsResponse
+import com.aurora.gplayapi.GooglePlayApi
+import com.aurora.gplayapi.data.builders.AppBuilder
+import com.aurora.gplayapi.data.models.AuthData
+import com.aurora.gplayapi.data.models.ContentRating
+import com.aurora.gplayapi.data.providers.HeaderProvider.getDefaultHeaders
+import com.aurora.gplayapi.exceptions.ApiException
+import com.aurora.gplayapi.network.IHttpClient
+import java.util.Locale
+
+class ContentRatingHelper(authData: AuthData) : BaseHelper(authData) {
+
+ companion object {
+ private const val HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language"
+ private const val HTTP_QUERY_PARAM_DOC = "doc"
+ }
+
+ override fun using(httpClient: IHttpClient) = apply {
+ this.httpClient = httpClient
+ }
+
+ fun updateContentRatingWithId(
+ appPackage: String,
+ currentContentRating: ContentRating,
+ ): ContentRating {
+ // If the device's language is English, the default rating will be in English.
+ // So, its title can already be treated as an identifier for the rating.
+ if (Locale.getDefault().language == Locale.ENGLISH.language) {
+ return currentContentRating.copy(id = currentContentRating.title.lowercase())
+ }
+
+ return try {
+ val englishLocaleContentRating = fetchContentRating(appPackage, Locale.US)
+
+ // For rating in other languages, we set the English title as its ID
+ currentContentRating.copy(id = englishLocaleContentRating.title.lowercase())
+ } catch (appNotFoundException: ApiException.AppNotFound) {
+ currentContentRating
+ }
+ }
+
+ private fun fetchContentRating(
+ appPackage: String, locale: Locale = Locale.getDefault()
+ ): ContentRating {
+ val response = getAppDetails(packageName = appPackage, locale = locale)
+ return AppBuilder.build(response).contentRating
+ }
+
+ private fun getAppDetails(
+ packageName: String, locale: Locale = Locale.getDefault()
+ ): DetailsResponse {
+ val headers = buildHeaders(locale)
+ val params = mapOf(HTTP_QUERY_PARAM_DOC to packageName)
+ val playResponse = httpClient.get(GooglePlayApi.URL_DETAILS, headers, params)
+
+ return if (playResponse.isSuccessful) {
+ getDetailsResponseFromBytes(playResponse.responseBytes)
+ } else {
+ throw ApiException.AppNotFound(playResponse.errorString)
+ }
+ }
+
+ private fun buildHeaders(locale: Locale): Map {
+ return getDefaultHeaders(authData).apply {
+ this[HTTP_HEADER_ACCEPT_LANGUAGE] = locale.toLanguageTag()
+ }
+ }
+}
diff --git a/sampleapp/src/main/java/com/aurora/sampleapp/MainActivityViewModel.kt b/sampleapp/src/main/java/com/aurora/sampleapp/MainActivityViewModel.kt
index a47788bf534f2679187df2f93637ec1c9c627e43..aa990a55fc74dbffea9e73b52f518066f02b3ff9 100644
--- a/sampleapp/src/main/java/com/aurora/sampleapp/MainActivityViewModel.kt
+++ b/sampleapp/src/main/java/com/aurora/sampleapp/MainActivityViewModel.kt
@@ -3,14 +3,13 @@ package com.aurora.sampleapp
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.aurora.gplayapi.DeviceManager
import com.aurora.gplayapi.data.models.AuthData
import com.aurora.gplayapi.helpers.AuthHelper
-import java.util.Properties
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
+import java.util.Properties
class MainActivityViewModel : ViewModel() {
@@ -20,7 +19,7 @@ class MainActivityViewModel : ViewModel() {
fun buildAuthData(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
val properties = Properties()
- context.resources.openRawResource(com.aurora.gplayapi.R.raw.gplayapi_px_7a).use {
+ context.resources.openRawResource(foundation.e.gplayapi.R.raw.gplayapi_px_7a).use {
properties.load(it)
}