diff --git a/CHANGELOG.md b/CHANGELOG.md index 33a974ec6aa..edc61569ceb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ ### Internal - Add `ReturnScore` table +- Add `ReturnScore` sync resource +- Bump Sentry Android to v6.2.0 +- Bump AndroidX Benchmark to v1.5.0-alpha04 +- Bump AndroidX Paging to v3.4.2 +- Bump Play Services Auth to v21.5.1 +- Bump Kotlin to v2.3.20 +- Bump KSP to v2.3.6 +- Bump Sentry to v8.36.0 +- Bump dagger to v2.59.2 +- Bump Jackson Core to v2.21.1 +- Bump Compose BOM to v2026.03.00 ## 2026.03.02 diff --git a/app/src/androidTest/java/org/simple/clinic/di/TestAppComponent.kt b/app/src/androidTest/java/org/simple/clinic/di/TestAppComponent.kt index 3f384730af7..60fe0cf2505 100644 --- a/app/src/androidTest/java/org/simple/clinic/di/TestAppComponent.kt +++ b/app/src/androidTest/java/org/simple/clinic/di/TestAppComponent.kt @@ -40,6 +40,7 @@ import org.simple.clinic.patient.onlinelookup.api.LookupPatientOnlineApiIntegrat import org.simple.clinic.patientattribute.PatientAttributeRepositoryAndroidTest import org.simple.clinic.protocolv2.ProtocolRepositoryAndroidTest import org.simple.clinic.protocolv2.sync.ProtocolSyncAndroidTest +import org.simple.clinic.returnscore.ReturnScoreRepositoryAndroidTest import org.simple.clinic.rules.LocalAuthenticationRule import org.simple.clinic.rules.RegisterPatientRule import org.simple.clinic.rules.SaveDatabaseRule @@ -73,6 +74,7 @@ import org.simple.clinic.sync.ProtocolSyncIntegrationTest import org.simple.clinic.sync.QuestionnaireResponseSyncIntegrationTest import org.simple.clinic.sync.QuestionnaireSyncIntegrationTest import org.simple.clinic.sync.ReportsSyncIntegrationTest +import org.simple.clinic.sync.ReturnScoreSyncIntegrationTest import org.simple.clinic.sync.TeleconsultationSyncIntegrationTest import org.simple.clinic.teleconsultlog.teleconsultrecord.TeleconsultRecordRepositoryAndroidTest import org.simple.clinic.teleconsultlog.teleconsultrecord.TeleconsultRecordSyncIntegrationTest @@ -170,4 +172,6 @@ interface TestAppComponent { fun inject(target: PatientAttributeSyncIntegrationTest) fun inject(target: CVDRiskRepositoryAndroidTest) fun inject(target: CVDRiskSyncIntegrationTest) + fun inject(target: ReturnScoreRepositoryAndroidTest) + fun inject(target: ReturnScoreSyncIntegrationTest) } diff --git a/app/src/androidTest/java/org/simple/clinic/returnscore/ReturnScoreRepositoryAndroidTest.kt b/app/src/androidTest/java/org/simple/clinic/returnscore/ReturnScoreRepositoryAndroidTest.kt new file mode 100644 index 00000000000..6cc6ed62330 --- /dev/null +++ b/app/src/androidTest/java/org/simple/clinic/returnscore/ReturnScoreRepositoryAndroidTest.kt @@ -0,0 +1,54 @@ +package org.simple.clinic.returnscore + +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import org.simple.clinic.AppDatabase +import org.simple.clinic.TestClinicApp +import org.simple.clinic.TestData +import org.simple.clinic.rules.SaveDatabaseRule +import org.simple.clinic.util.Rules +import java.util.UUID +import javax.inject.Inject + +class ReturnScoreRepositoryAndroidTest { + + @Inject + lateinit var database: AppDatabase + + @Inject + lateinit var returnScoreRepository: ReturnScoreRepository + + @get:Rule + val rules: RuleChain = Rules + .global() + .around(SaveDatabaseRule()) + + @Before + fun setUp() { + TestClinicApp.appComponent().inject(this) + } + + @Test + fun saving_return_scores_should_work_correctly() { + // given + val returnScores = listOf( + TestData.returnScore( + uuid = UUID.fromString("ef5b7656-a6df-459c-a5b0-80d100721597"), + ), + TestData.returnScore( + uuid = UUID.fromString("ef5b7656-a6df-459c-a5b0-80d123021597"), + ) + ) + + // when + returnScoreRepository.save(returnScores) + + // then + val savedReturnScores = returnScoreRepository.returnScoresImmediate() + + assertThat(savedReturnScores).isEqualTo(returnScores) + } +} diff --git a/app/src/androidTest/java/org/simple/clinic/sync/ReturnScoreSyncIntegrationTest.kt b/app/src/androidTest/java/org/simple/clinic/sync/ReturnScoreSyncIntegrationTest.kt new file mode 100644 index 00000000000..289ca203746 --- /dev/null +++ b/app/src/androidTest/java/org/simple/clinic/sync/ReturnScoreSyncIntegrationTest.kt @@ -0,0 +1,92 @@ +package org.simple.clinic.sync + +import com.f2prateek.rx.preferences2.Preference +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import org.simple.clinic.AppDatabase +import org.simple.clinic.TestClinicApp +import org.simple.clinic.main.TypedPreference +import org.simple.clinic.returnscore.ReturnScoreRepository +import org.simple.clinic.returnscore.sync.ReturnScoreSync +import org.simple.clinic.returnscore.sync.ReturnScoreSyncApi +import org.simple.clinic.rules.SaveDatabaseRule +import org.simple.clinic.rules.ServerAuthenticationRule +import org.simple.clinic.util.Rules +import java.util.Optional +import javax.inject.Inject + +class ReturnScoreSyncIntegrationTest { + + @Inject + lateinit var appDatabase: AppDatabase + + @Inject + lateinit var repository: ReturnScoreRepository + + @Inject + @TypedPreference(TypedPreference.Type.LastReturnScorePullToken) + lateinit var lastPullToken: Preference> + + @Inject + lateinit var syncApi: ReturnScoreSyncApi + + @Inject + lateinit var syncInterval: SyncInterval + + @get:Rule + val ruleChain: RuleChain = Rules + .global() + .around(ServerAuthenticationRule()) + .around(SaveDatabaseRule()) + + private lateinit var sync: ReturnScoreSync + + private val batchSize = 1000 + private lateinit var config: SyncConfig + + @Before + fun setUp() { + TestClinicApp.appComponent().inject(this) + + resetLocalData() + + config = SyncConfig( + syncInterval = syncInterval, + pullBatchSize = batchSize, + pushBatchSize = batchSize, + name = "" + ) + + sync = ReturnScoreSync( + syncCoordinator = SyncCoordinator(), + api = syncApi, + repository = repository, + lastPullToken = lastPullToken, + config = config + ) + } + + private fun resetLocalData() { + clearReturnScoreDao() + lastPullToken.delete() + } + + private fun clearReturnScoreDao() { + appDatabase.returnScoreDao().clear() + } + + @Test + fun syncing_records_should_work_as_expected() { + // when + Truth.assertThat(repository.recordCount().blockingFirst()).isEqualTo(0) + sync.pull() + + // then + val pulledRecords = repository.returnScoresImmediate() + + Truth.assertThat(pulledRecords).isNotEmpty() + } +} diff --git a/app/src/main/java/org/simple/clinic/main/TypedPreference.kt b/app/src/main/java/org/simple/clinic/main/TypedPreference.kt index 33e6cb446de..5d84df00a38 100644 --- a/app/src/main/java/org/simple/clinic/main/TypedPreference.kt +++ b/app/src/main/java/org/simple/clinic/main/TypedPreference.kt @@ -25,5 +25,6 @@ annotation class TypedPreference(val value: Type) { DataProtectionConsent, LastPatientAttributePullToken, LastCVDRiskPullToken, + LastReturnScorePullToken } } diff --git a/app/src/main/java/org/simple/clinic/returnscore/ReturnScore.kt b/app/src/main/java/org/simple/clinic/returnscore/ReturnScore.kt index 711eb33fe08..aaafef4fdd2 100644 --- a/app/src/main/java/org/simple/clinic/returnscore/ReturnScore.kt +++ b/app/src/main/java/org/simple/clinic/returnscore/ReturnScore.kt @@ -10,6 +10,7 @@ import androidx.room.OnConflictStrategy import androidx.room.PrimaryKey import androidx.room.Query import io.reactivex.Flowable +import io.reactivex.Observable import kotlinx.parcelize.Parcelize import org.simple.clinic.storage.Timestamps import java.util.UUID @@ -41,6 +42,15 @@ data class ReturnScore( @Query("SELECT * FROM ReturnScore WHERE deletedAt IS NULL") fun getAll(): Flowable> + @Query("SELECT * FROM ReturnScore WHERE deletedAt IS NULL") + fun getAllImmediate(): List + + @Query("SELECT * FROM ReturnScore WHERE scoreType == :type AND deletedAt IS NULL LIMIT 1") + fun getByScoreType(type: ScoreType): Flowable> + + @Query("SELECT COUNT(uuid) FROM ReturnScore") + fun count(): Observable + @Query("DELETE FROM returnscore") fun clear(): Int diff --git a/app/src/main/java/org/simple/clinic/returnscore/ReturnScoreRepository.kt b/app/src/main/java/org/simple/clinic/returnscore/ReturnScoreRepository.kt new file mode 100644 index 00000000000..d55487a7072 --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/ReturnScoreRepository.kt @@ -0,0 +1,62 @@ +package org.simple.clinic.returnscore + +import io.reactivex.Observable +import org.simple.clinic.di.AppScope +import org.simple.clinic.patient.SyncStatus +import org.simple.clinic.returnscore.sync.ReturnScorePayload +import org.simple.clinic.sync.SynceableRepository +import java.util.UUID +import javax.inject.Inject + +@AppScope +class ReturnScoreRepository @Inject constructor( + private val dao: ReturnScore.RoomDao +) : SynceableRepository { + + override fun save(records: List) { + saveRecords(records) + } + + override fun setSyncStatus(from: SyncStatus, to: SyncStatus) { + // no-op + } + + override fun setSyncStatus(ids: List, to: SyncStatus) { + // no-op + } + + override fun mergeWithLocalData(payloads: List) { + val records = payloads + .map { it.toDatabaseModel() } + + saveRecords(records) + } + + override fun recordCount(): Observable { + return dao.count() + } + + override fun pendingSyncRecordCount(): Observable { + return Observable.just(0) + } + + override fun pendingSyncRecords(limit: Int, offset: Int): List { + return emptyList() + } + + private fun saveRecords(records: List) { + dao.save(records) + } + + fun returnScores(): Observable> { + return dao.getAll().toObservable() + } + + fun returnScoresImmediate(): List { + return dao.getAllImmediate() + } + + fun returnScoresByType(type: ScoreType): Observable> { + return dao.getByScoreType(type).toObservable() + } +} diff --git a/app/src/main/java/org/simple/clinic/returnscore/di/ReturnScoreModule.kt b/app/src/main/java/org/simple/clinic/returnscore/di/ReturnScoreModule.kt new file mode 100644 index 00000000000..058969c876b --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/di/ReturnScoreModule.kt @@ -0,0 +1,36 @@ +package org.simple.clinic.returnscore.di + +import com.f2prateek.rx.preferences2.Preference +import com.f2prateek.rx.preferences2.RxSharedPreferences +import dagger.Module +import dagger.Provides +import org.simple.clinic.AppDatabase +import org.simple.clinic.main.TypedPreference +import org.simple.clinic.returnscore.ReturnScore +import org.simple.clinic.returnscore.sync.ReturnScoreSyncApi +import org.simple.clinic.util.preference.StringPreferenceConverter +import org.simple.clinic.util.preference.getOptional +import retrofit2.Retrofit +import java.util.Optional +import javax.inject.Named + +@Module +open class ReturnScoreModule { + + @Provides + fun dao(appDatabase: AppDatabase): ReturnScore.RoomDao { + return appDatabase.returnScoreDao() + } + + @Provides + fun syncApi(@Named("for_deployment") retrofit: Retrofit): ReturnScoreSyncApi { + return retrofit.create(ReturnScoreSyncApi::class.java) + } + + @Provides + @TypedPreference(TypedPreference.Type.LastReturnScorePullToken) + fun lastPullToken(rxSharedPrefs: RxSharedPreferences): Preference> { + return rxSharedPrefs.getOptional("last_return_score_pull_token_v1", StringPreferenceConverter()) + } +} + diff --git a/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePayload.kt b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePayload.kt new file mode 100644 index 00000000000..7defaf53ea6 --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePayload.kt @@ -0,0 +1,46 @@ +package org.simple.clinic.returnscore.sync + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import org.simple.clinic.returnscore.ReturnScore +import org.simple.clinic.returnscore.ScoreType +import org.simple.clinic.storage.Timestamps +import java.time.Instant +import java.util.UUID + +@JsonClass(generateAdapter = true) +data class ReturnScorePayload( + @Json(name = "id") + val uuid: UUID, + + @Json(name = "patient_id") + val patientUuid: UUID, + + @Json(name = "score_type") + val scoreType: ScoreType, + + @Json(name = "score_value") + val scoreValue: Float, + + @Json(name = "created_at") + val createdAt: Instant, + + @Json(name = "updated_at") + val updatedAt: Instant, + + @Json(name = "deleted_at") + val deletedAt: Instant?, +) { + + fun toDatabaseModel() = ReturnScore( + uuid = uuid, + patientUuid = patientUuid, + scoreType = scoreType, + scoreValue = scoreValue, + timestamps = Timestamps( + createdAt = createdAt, + updatedAt = updatedAt, + deletedAt = deletedAt + ) + ) +} diff --git a/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePullResponse.kt b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePullResponse.kt new file mode 100644 index 00000000000..61d9e369028 --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScorePullResponse.kt @@ -0,0 +1,16 @@ +package org.simple.clinic.returnscore.sync + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import org.simple.clinic.sync.DataPullResponse + +@JsonClass(generateAdapter = true) +data class ReturnScorePullResponse( + + @Json(name = "patient_scores") + override val payloads: List, + + @Json(name = "process_token") + override val processToken: String + +) : DataPullResponse diff --git a/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSync.kt b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSync.kt new file mode 100644 index 00000000000..f4af766aac3 --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSync.kt @@ -0,0 +1,35 @@ +package org.simple.clinic.returnscore.sync + +import com.f2prateek.rx.preferences2.Preference +import org.simple.clinic.main.TypedPreference +import org.simple.clinic.returnscore.ReturnScoreRepository +import org.simple.clinic.sync.ModelSync +import org.simple.clinic.sync.SyncConfig +import org.simple.clinic.sync.SyncConfigType +import org.simple.clinic.sync.SyncCoordinator +import org.simple.clinic.util.read +import java.util.Optional +import javax.inject.Inject + +class ReturnScoreSync @Inject constructor( + private val syncCoordinator: SyncCoordinator, + private val api: ReturnScoreSyncApi, + private val repository: ReturnScoreRepository, + @TypedPreference(TypedPreference.Type.LastReturnScorePullToken) private val lastPullToken: Preference>, + @SyncConfigType(SyncConfigType.Type.Frequent) private val config: SyncConfig +) : ModelSync { + + override val name: String = "ReturnScore" + + override val requiresSyncApprovedUser = true + + override fun push() { + /* Nothing to do here */ + } + + override fun pull() { + val batchSize = config.pullBatchSize + + syncCoordinator.pull(repository, lastPullToken, batchSize) { api.pull(batchSize, it).execute().read()!! } + } +} diff --git a/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSyncApi.kt b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSyncApi.kt new file mode 100644 index 00000000000..9c59680b9f5 --- /dev/null +++ b/app/src/main/java/org/simple/clinic/returnscore/sync/ReturnScoreSyncApi.kt @@ -0,0 +1,17 @@ +package org.simple.clinic.returnscore.sync + +import retrofit2.Call +import retrofit2.http.GET +import retrofit2.http.Headers +import retrofit2.http.Query + +interface ReturnScoreSyncApi { + + @Headers(value = ["X-RESYNC-TOKEN: 1"]) + @GET("v4/patient_scores/sync") + fun pull( + @Query("limit") recordsToPull: Int, + @Query("process_token") lastPullToken: String? = null, + ): Call +} + diff --git a/app/src/main/java/org/simple/clinic/sync/SyncModule.kt b/app/src/main/java/org/simple/clinic/sync/SyncModule.kt index b8c2496ff51..28758398dea 100644 --- a/app/src/main/java/org/simple/clinic/sync/SyncModule.kt +++ b/app/src/main/java/org/simple/clinic/sync/SyncModule.kt @@ -48,6 +48,8 @@ import org.simple.clinic.questionnaireresponse.di.QuestionnaireResponseModule import org.simple.clinic.questionnaireresponse.sync.QuestionnaireResponseSync import org.simple.clinic.reports.ReportsModule import org.simple.clinic.reports.ReportsSync +import org.simple.clinic.returnscore.di.ReturnScoreModule +import org.simple.clinic.returnscore.sync.ReturnScoreSync import org.simple.clinic.summary.teleconsultation.sync.TeleconsultationSync import org.simple.clinic.teleconsultlog.teleconsultrecord.TeleconsultRecordRepository import org.simple.clinic.teleconsultlog.teleconsultrecord.TeleconsultRecordSync @@ -74,7 +76,8 @@ import javax.inject.Named QuestionnaireModule::class, QuestionnaireResponseModule::class, PatientAttributeModule::class, - CVDRiskModule::class + CVDRiskModule::class, + ReturnScoreModule::class, ]) class SyncModule { @@ -99,6 +102,7 @@ class SyncModule { questionnaireResponseSync: QuestionnaireResponseSync, patientAttributeSync: PatientAttributeSync, cvdRiskSync: CVDRiskSync, + returnScoreSync: ReturnScoreSync ): List { val optionalSyncs = if (features.isEnabled(Feature.CallResultSyncEnabled)) listOf(callResultSync) else emptyList() @@ -106,7 +110,7 @@ class SyncModule { questionnaireSync, questionnaireResponseSync, protocolSync, reportsSync, helpSync, patientSync, bloodPressureSync, medicalHistorySync, appointmentSync, prescriptionSync, bloodSugarSync, teleconsultationMedicalOfficersSync, - teleconsultRecordSync, drugSync, patientAttributeSync, cvdRiskSync + teleconsultRecordSync, drugSync, patientAttributeSync, cvdRiskSync, returnScoreSync ) + optionalSyncs } diff --git a/app/src/testFixtures/kotlin/org/simple/clinic/TestData.kt b/app/src/testFixtures/kotlin/org/simple/clinic/TestData.kt index 25f0e6275b3..50cc180c753 100644 --- a/app/src/testFixtures/kotlin/org/simple/clinic/TestData.kt +++ b/app/src/testFixtures/kotlin/org/simple/clinic/TestData.kt @@ -96,6 +96,9 @@ import org.simple.clinic.questionnaire.component.properties.InputFieldValidation import org.simple.clinic.questionnaire.component.properties.IntegerType import org.simple.clinic.questionnaire.component.properties.StringType import org.simple.clinic.questionnaireresponse.QuestionnaireResponse +import org.simple.clinic.returnscore.LikelyToReturnScoreType +import org.simple.clinic.returnscore.ReturnScore +import org.simple.clinic.returnscore.ScoreType import org.simple.clinic.scanid.IndiaNHIDDateOfBirth import org.simple.clinic.scanid.IndiaNHIDGender import org.simple.clinic.scanid.IndiaNHIDInfoPayload @@ -2004,4 +2007,22 @@ object TestData { ) ) } + + fun returnScore( + uuid: UUID = UUID.fromString("f9a42c9f-01fe-40c5-b625-64b3e9868d5e"), + scoreType: ScoreType = LikelyToReturnScoreType, + createdAt: Instant = Instant.now(), + updatedAt: Instant = Instant.now(), + deletedAt: Instant? = null, + ) = ReturnScore( + uuid = uuid, + patientUuid = UUID.fromString("7ac2d657-6868-441c-9c0c-5c4a5dba87d7"), + scoreType = scoreType, + scoreValue = 9f, + timestamps = Timestamps( + createdAt = createdAt, + updatedAt = updatedAt, + deletedAt = deletedAt + ) + ) } diff --git a/gradle.properties b/gradle.properties index eacd7a6dbb3..6c4b0e6a68a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -47,13 +47,9 @@ disableScreenshot=false allowRootedDevice=true maestroTests=false org.gradle.unsafe.configuration-cache=true - # AGP 9 compatibility flags (temporary) # Remove gradually before AGP 10 android.uniquePackageNames=false android.enableAppCompileTimeRClass=false android.r8.optimizedResourceShrinking=false -# remove this when sentry-android-gradle-plugin releases version 6.x.x -# https://github.com/getsentry/sentry-android-gradle-plugin/issues/1004 -android.newDsl=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ba78b72494f..4a7b4198074 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ agp = "9.0.1" androidx-cameraView = "1.5.3" androidx-camera = "1.5.3" -androidx-paging = "3.3.6" +androidx-paging = "3.4.2" androidx-room = "2.8.4" androidx-work = "2.11.1" androidx-security-crypto = "1.1.0" @@ -12,12 +12,12 @@ androidx-lifecycle = "2.10.0" androidx-activity = "1.12.4" chucker = "4.3.0" -dagger = "2.59.1" +dagger = "2.59.2" -kotlin = "2.3.10" +kotlin = "2.3.20" kotlinx-serialization = "1.10.0" -ksp = "2.3.5" +ksp = "2.3.6" ktlint = "0.36.0" @@ -39,7 +39,7 @@ coroutines = "1.10.2" compose-compiler = "1.5.13" -androidx-compose-bom = "2026.02.00" +androidx-compose-bom = "2026.03.00" composeThemeAdapter = "0.36.0" @@ -117,7 +117,7 @@ itemanimators = "com.mikepenz:itemanimators:1.1.0" itext7 = "com.itextpdf:itext7-core:7.2.5" -jackson-core = "com.fasterxml.jackson.core:jackson-core:2.21.0" +jackson-core = "com.fasterxml.jackson.core:jackson-core:2.21.1" jbcrypt = "org.mindrot:jbcrypt:0.4" @@ -162,7 +162,7 @@ okhttp-interceptor-logging = { module = "com.squareup.okhttp3:logging-intercepto openCsv = "com.opencsv:opencsv:5.12.0" play-app-update = "com.google.android.play:app-update-ktx:2.1.0" -play-services-auth = "com.google.android.gms:play-services-auth:21.5.0" +play-services-auth = "com.google.android.gms:play-services-auth:21.5.1" play-services-location = "com.google.android.gms:play-services-location:21.3.0" play-services-mlkit-barcode = "com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1" @@ -181,7 +181,7 @@ rx-java = "io.reactivex.rxjava2:rxjava:2.2.21" rx-kotlin = "io.reactivex.rxjava2:rxkotlin:2.4.0" rx-preferences = "com.f2prateek.rx.preferences2:rx-preferences:2.0.1" -sentry-android = "io.sentry:sentry-android:8.32.0" +sentry-android = "io.sentry:sentry-android:8.36.0" signaturepad = "com.github.gcacace:signature-pad:1.3.1" @@ -225,13 +225,13 @@ sqlCipher = { module = "net.zetetic:sqlcipher-android", version.ref = "sqlCipher android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } android-lint = { id = "com.android.lint", version.ref = "agp" } -androidx-benchmark = { id = "androidx.benchmark", version = "1.4.1" } +androidx-benchmark = { id = "androidx.benchmark", version = "1.5.0-alpha04" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } google-services = { id = "com.google.gms.google-services", version = "4.4.4" } -sentry = { id = "io.sentry.android.gradle", version = "6.0.0" } +sentry = { id = "io.sentry.android.gradle", version = "6.2.0" } [bundles] androidx-camera = ["androidx-camera-core", "androidx-camera-camera2", "androidx-camera-view", "androidx-camera-lifecycle"]