Skip to content

Commit c484860

Browse files
lincmbapldLZRSf-odhiambo
authored
Genai speech to form (#3666)
* Initial commit * Add dependencies * Transcribe an audio file to text using Google Cloud Speech-to-Text API * Gemini client * TextToForm code * remove validation * SpeechToForm class * add genai lib, mock gemini class with it * use suspend, rename to model, update template * Add unit tests * Add lisences, clean up * fix tests * expand docs * Allow for GEMINI_API_KEY to be passed as project property * Update SpeechToForm to use GeminiModel in instantiating TextToForm Update GeminiModel to return model * Clean up temp file after test * Add option to run tests bu hitting the actual API * Update method name to avoid conflict * pull out qr validation * QR generation retry logic incase of errors. Refactor some functions * Address changes * Add test audio file * move to new package structure and abstract models * match tests to new abstractions * turn class into interface, do not override autogen getter * retry if not able to extract response, always return a qr * refactor some constants * Add sample transcript * rename packages and add outline of summarize class * add scaffold for live speech to text * Refine model layer abstraction. Make it easy to change models. * Refactor dispatcher. * Convert Speech to text to an object. Use proper logging. Remove redundant qR checks * refactor TextToForm to an object. Utilize refactored models. Handle different responses * Update tests * fix summarize and remove wildcard * spotless * Resolved issues making build fail: - Excluded conflicting dependencies (com.google.guava:guava and org.threeten:threetenbp) from the google-cloud-speech library. - Upgraded google-cloud-speech to version 4.50.0 to address compatibility issues. * Additional sample test files * Use real files TextToForm tests * Add grpc-okhttp dependency needed by google cloud speech * Switch transcription to only transcribe wav files as recommended. * Improve SpeechToTextTest to only mock api calls but use real files * Add sample conversation.wav file * Handle edge case in retryLogic where QR, QRJson of generatedText could be blank Add more TextToFormTest tests * Gnerate Summary initial work and tests * Resolve tests failure caused by refactoring QuestionnaireResponseValidator * Add SpeechToext fragment views * add starter gemma model * Update questionnaire form on new QuestionnaireResponse * Refactor showing progress dialog in Questionnaire activity * Show record button * Toggle record button and show speech-to-text 'window' * Exclude protobuf-javalite to fix duplicated classes error Since full version protobuf-java is required for com.google.cloud:google-cloud-speech * Add record-audio permission before lauching speech to text * Simulate stop recording processing progress view * add tests, fix style * set type and create constants * Integrate to TextToForm api with Gemini * Show edit button to exit speech-to-text without updating form * Integrate speech-to-text to call cloud speech-to-text api * Fix errors in tests * Fix failing tests for QuestionnaireViewModel * Latest working changes - add build variant * Run spotless * Add enableSpeechToText to questionnaire config * Edit GemmaModel class to allow test * refactor hasDebygSuffix and allow more paths * check buffer min and use generic mic * newer model, fix prompt for multiselects * line breaks * move hasDebugSuffix tests * use a list and remove need for test * extend timeout, check adb * add ram size * add missing mocks and ids * add test for service points map * test unmocked debug variant * add note for gradle change * increase heap * disable avd force * remove memory changes * shard quest tests * fix time stripping code * add info * add shard suffix to test report * remove clean * update regex and examples * add worker cleanup * add unmock * more agressive test cleanup * remove verbose * add roll up step * increase heap size * more shards less heap --------- Co-authored-by: pld <peter@ona.io> Co-authored-by: L≡ZRS <12814349+LZRS@users.noreply.github.com> Co-authored-by: Francis Odhiambo <4540684+f-odhiambo@users.noreply.github.com>
1 parent d1454d4 commit c484860

File tree

52 files changed

+5298
-346
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+5298
-346
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ jobs:
2525
runs-on: ubuntu-latest
2626
strategy:
2727
matrix:
28-
api-level: [34]
29-
28+
api-level: [34]
3029
steps:
3130
- name: Checkout 🛎️
3231
uses: actions/checkout@v4
32+
with:
33+
fetch-depth: 2
3334

3435
- name: Set up JDK 17
3536
uses: actions/setup-java@v4
@@ -114,8 +115,7 @@ jobs:
114115
runs-on: ubuntu-latest
115116
strategy:
116117
matrix:
117-
api-level: [34]
118-
118+
api-level: [34]
119119
steps:
120120
- name: Checkout 🛎️
121121
uses: actions/checkout@v4
@@ -199,11 +199,13 @@ jobs:
199199
run: bash <(curl -s https://codecov.io/bash) -F geowidget -f "geowidget/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"
200200

201201
quest-tests:
202+
timeout-minutes: 90 # Extend timeout to 90 minutes
202203
runs-on: ubuntu-latest
203204
strategy:
204205
matrix:
206+
shard: [0, 1, 2, 3, 4, 5] # Split into 6 shards
207+
num-shards: [6] # Total number of shards
205208
api-level: [34]
206-
207209
steps:
208210
- name: Checkout 🛎️
209211
uses: actions/checkout@v4
@@ -258,7 +260,7 @@ jobs:
258260
working-directory: android
259261
api-level: ${{ matrix.api-level }}
260262
arch: x86_64
261-
force-avd-creation: true
263+
force-avd-creation: false
262264
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
263265
disable-animations: false
264266
script: echo "Generated AVD snapshot for caching."
@@ -269,45 +271,33 @@ jobs:
269271
working-directory: android
270272
api-level: ${{ matrix.api-level }}
271273
arch: x86_64
272-
force-avd-creation: true
273-
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
274-
disable-animations: true
275-
script: ./gradlew clean -PlocalPropertiesFile=local.properties :quest:fhircoreJacocoReport --stacktrace -Pandroid.testInstrumentationRunnerArguments.notPackage=org.smartregister.fhircore.quest.performance
276-
277-
- name: Run Quest module unit and instrumentation tests and generate aggregated coverage report (Disabled)
278-
if: false
279-
uses: reactivecircus/android-emulator-runner@v2
280-
with:
281-
working-directory: android
282-
api-level: ${{ matrix.api-level }}
283-
arch: x86_64
284-
force-avd-creation: true
274+
force-avd-creation: false
275+
heap-size: 256M
285276
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
286277
disable-animations: true
287-
run: |
288-
set -e
289-
./gradlew -PlocalPropertiesFile=local.properties :quest:clean
290-
./gradlew -PlocalPropertiesFile=local.properties :quest:assembleOpensrpDebugAndroidTest --stacktrace
291-
/Users/martin/Library/Android/sdk/platform-tools/adb install quest/build/outputs/apk/androidTest/opensrp/debug/quest-opensrp-debug-androidTest.apk
292-
./gradlew -PlocalPropertiesFile=local.properties :quest:assembleOpensrpDebug --stacktrace
293-
/Users/martin/Library/Android/sdk/platform-tools/adb install quest/build/outputs/apk/opensrp/debug/quest-opensrp-debug.apk
294-
/Users/martin/Library/Android/sdk/platform-tools/adb shell am instrument -w \
295-
--no-window-animation \
296-
-e coverage "true" \
297-
-e debug false \
298-
org.smartregister.opensrp.test/org.smartregister.fhircore.quest.QuestTestRunner
299-
/Users/martin/Library/Android/sdk/platform-tools/adb shell run-as org.smartregister.opensrp \
300-
cat "/data/user/0/org.smartregister.opensrp/files/coverage.ec" > quest/coverage.ec
301-
./gradlew -PlocalPropertiesFile=local.properties :quest:fhircoreJacocoReport --stacktrace
278+
script: >-
279+
./gradlew -PlocalPropertiesFile=local.properties :quest:fhircoreJacocoReport
280+
-Pandroid.testInstrumentationRunnerArguments.notPackage=org.smartregister.fhircore.quest.performance
281+
-Pandroid.testInstrumentationRunnerArguments.numShards=${{ matrix.num-shards }}
282+
-Pandroid.testInstrumentationRunnerArguments.shardIndex=${{ matrix.shard }}
302283
303284
- name: Upload Test reports
304285
if: ${{ !cancelled() }}
305286
uses: actions/upload-artifact@v4
306287
with:
307-
name: quest-test-reports
288+
name: quest-test-report-${{ matrix.shard }}
308289
path: android/quest/build/reports
309290

310291
- name: Upload Quest module test coverage report to Codecov
311292
if: matrix.api-level == 34 # Only upload coverage on API level 34
312293
working-directory: android
313294
run: bash <(curl -s https://codecov.io/bash) -F quest -f "quest/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"
295+
296+
quest-success:
297+
name: Quest Tests Success
298+
needs: quest-tests
299+
runs-on: ubuntu-latest
300+
if: ${{ !cancelled() }}
301+
steps:
302+
- name: Quest Tests Passed
303+
run: echo "All Quest tests passed!"

android/buildSrc/src/main/kotlin/project-properties.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ val requiredFhirProperties =
2727
"OAUTH_SCOPE",
2828
"MAPBOX_SDK_TOKEN",
2929
"SENTRY_DSN",
30-
"OPENSRP_APP_ID"
30+
"OPENSRP_APP_ID",
31+
"GEMINI_API_KEY",
32+
"SPEECH_TO_TEXT_API_KEY",
3133
)
3234

3335
val localProperties = readProperties((project.properties["localPropertiesFile"] ?: "${rootProject.projectDir}/local.properties").toString())

android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/QuestionnaireConfig.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ data class QuestionnaireConfig(
6868
val linkIds: List<LinkIdConfig>? = null,
6969
val showSubmitAnywayButton: String = "false",
7070
val showSubmissionConfirmationDialog: String = "false",
71+
val enableSpeechToText: Boolean = false,
7172
) : java.io.Serializable, Parcelable {
7273

7374
fun interpolate(computedValuesMap: Map<String, Any>) =

android/engine/src/main/java/org/smartregister/fhircore/engine/util/SharedPreferencesHelper.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import dagger.hilt.android.qualifiers.ApplicationContext
2424
import javax.inject.Inject
2525
import javax.inject.Singleton
2626
import kotlinx.serialization.SerializationException
27+
import org.jetbrains.annotations.VisibleForTesting
28+
import org.smartregister.fhircore.engine.BuildConfig
29+
import org.smartregister.fhircore.engine.configuration.ConfigurationRegistry.Companion.DEBUG_SUFFIX
2730
import org.smartregister.fhircore.engine.util.extension.decodeJson
2831
import org.smartregister.fhircore.engine.util.extension.encodeJson
2932
import timber.log.Timber
@@ -108,6 +111,12 @@ constructor(@ApplicationContext val context: Context, val gson: Gson) {
108111

109112
fun retrieveApplicationId() = read(SharedPreferenceKey.APP_ID.name, null)
110113

114+
fun hasDebugSuffix(): Boolean =
115+
retrieveApplicationId()?.trim()?.endsWith(DEBUG_SUFFIX, ignoreCase = true) == true &&
116+
isDebugVariant()
117+
118+
@VisibleForTesting fun isDebugVariant() = BuildConfig.DEBUG
119+
111120
companion object {
112121
const val PREFS_NAME = "params"
113122
const val PREFS_SYNC_PROGRESS_TOTAL = "sync_progress_total"

android/engine/src/test/java/org/smartregister/fhircore/engine/util/SharedPreferencesHelperTest.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import androidx.test.core.app.ApplicationProvider
2222
import com.google.gson.Gson
2323
import dagger.hilt.android.testing.HiltAndroidRule
2424
import dagger.hilt.android.testing.HiltAndroidTest
25+
import io.mockk.coEvery
26+
import io.mockk.spyk
2527
import javax.inject.Inject
2628
import org.junit.Assert
2729
import org.junit.Before
@@ -122,4 +124,38 @@ internal class SharedPreferencesHelperTest : RobolectricTest() {
122124

123125
Assert.assertEquals("test.demo", retrievedAppId)
124126
}
127+
128+
@Test
129+
fun testHasDebugSuffix_withSuffix_shouldReturn_true() {
130+
setDebugInvariantTrue()
131+
sharedPreferencesHelper.write(SharedPreferenceKey.APP_ID.name, "app/debug")
132+
Assert.assertTrue(sharedPreferencesHelper.hasDebugSuffix())
133+
}
134+
135+
@Test
136+
fun testHasDebugSuffix_noSuffix_shouldReturn_false() {
137+
setDebugInvariantTrue()
138+
sharedPreferencesHelper.write(SharedPreferenceKey.APP_ID.name, "app")
139+
Assert.assertFalse(sharedPreferencesHelper.hasDebugSuffix())
140+
}
141+
142+
@Test
143+
fun testHasDebugSuffix_emptyAppId_shouldReturn_null() {
144+
setDebugInvariantTrue()
145+
sharedPreferencesHelper.write(SharedPreferenceKey.APP_ID.name, null)
146+
Assert.assertFalse(sharedPreferencesHelper.hasDebugSuffix())
147+
}
148+
149+
@Test
150+
fun testIsDebugVariant_shouldReturnTrue() {
151+
Assert.assertTrue(sharedPreferencesHelper.isDebugVariant())
152+
}
153+
154+
private fun setDebugInvariantTrue() {
155+
sharedPreferencesHelper =
156+
spyk(
157+
SharedPreferencesHelper(application, gson),
158+
)
159+
coEvery { sharedPreferencesHelper.isDebugVariant() } returns true
160+
}
125161
}

android/geowidget/src/main/java/org/smartregister/fhircore/geowidget/screens/GeoWidgetViewModel.kt

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,47 @@ class GeoWidgetViewModel : ViewModel() {
2626

2727
val mapFeatures = ArrayDeque<Feature>()
2828

29+
private val servicePointTypes =
30+
listOf(
31+
ServicePointType.EPP,
32+
ServicePointType.CEG,
33+
ServicePointType.CHRD1,
34+
ServicePointType.CHRD2,
35+
ServicePointType.DRSP,
36+
ServicePointType.MSP,
37+
ServicePointType.SDSP,
38+
ServicePointType.CSB1,
39+
ServicePointType.CSB2,
40+
ServicePointType.CHRR,
41+
ServicePointType.WAREHOUSE,
42+
ServicePointType.WATER_POINT,
43+
ServicePointType.PRESCO,
44+
ServicePointType.MEAH,
45+
ServicePointType.DREAH,
46+
ServicePointType.MPPSPF,
47+
ServicePointType.DRPPSPF,
48+
ServicePointType.NGO_PARTNER,
49+
ServicePointType.SITE_COMMUNAUTAIRE,
50+
ServicePointType.DRJS,
51+
ServicePointType.INSTAT,
52+
ServicePointType.BSD,
53+
ServicePointType.MEN,
54+
ServicePointType.DREN,
55+
ServicePointType.DISTRICT_PPSPF,
56+
ServicePointType.MAIRIE,
57+
ServicePointType.ECOLE_COMMUNAUTAIRE,
58+
ServicePointType.ECOLE_PRIVÉ,
59+
ServicePointType.ECOLE_PUBLIQUE,
60+
ServicePointType.CENTRE_DE_SANTE,
61+
ServicePointType.CENTRE_DE_TRAITEMENT_DU_CHOLERA,
62+
ServicePointType.HOPITAL_COMMUNAL,
63+
ServicePointType.HOPITAL,
64+
ServicePointType.BUREAU_DES_PARTENAIRES,
65+
ServicePointType.LYCÉE,
66+
ServicePointType.DIRECTION_COMMUNALE_DE_L_ENSEIGNEMENT,
67+
ServicePointType.ECOLE_PRIVE,
68+
)
69+
2970
fun updateMapFeatures(geoJsonFeatures: List<GeoJsonFeature>) {
3071
if (mapFeatures.size <= MAP_FEATURES_LIMIT) {
3172
mapFeatures.addAll(geoJsonFeatures.map { it.toFeature() })
@@ -34,50 +75,8 @@ class GeoWidgetViewModel : ViewModel() {
3475

3576
fun clearMapFeatures() = mapFeatures.clear()
3677

37-
// Todo Refactor this to work different and better
3878
fun getServicePointKeyToType(): Map<String, ServicePointType> {
39-
val map: MutableMap<String, ServicePointType> = HashMap()
40-
map[ServicePointType.EPP.name.lowercase()] = ServicePointType.EPP
41-
map[ServicePointType.CEG.name.lowercase()] = ServicePointType.CEG
42-
map[ServicePointType.CHRD1.name.lowercase()] = ServicePointType.CHRD1
43-
map[ServicePointType.CHRD2.name.lowercase()] = ServicePointType.CHRD2
44-
map[ServicePointType.DRSP.name.lowercase()] = ServicePointType.DRSP
45-
map[ServicePointType.MSP.name.lowercase()] = ServicePointType.MSP
46-
map[ServicePointType.SDSP.name.lowercase()] = ServicePointType.SDSP
47-
map[ServicePointType.CSB1.name.lowercase()] = ServicePointType.CSB1
48-
map[ServicePointType.CSB2.name.lowercase()] = ServicePointType.CSB2
49-
map[ServicePointType.CHRR.name.lowercase()] = ServicePointType.CHRR
50-
map[ServicePointType.WAREHOUSE.name.lowercase()] = ServicePointType.WAREHOUSE
51-
map[ServicePointType.WATER_POINT.name.lowercase()] = ServicePointType.WATER_POINT
52-
map[ServicePointType.PRESCO.name.lowercase()] = ServicePointType.PRESCO
53-
map[ServicePointType.MEAH.name.lowercase()] = ServicePointType.MEAH
54-
map[ServicePointType.DREAH.name.lowercase()] = ServicePointType.DREAH
55-
map[ServicePointType.MPPSPF.name.lowercase()] = ServicePointType.MPPSPF
56-
map[ServicePointType.DRPPSPF.name.lowercase()] = ServicePointType.DRPPSPF
57-
map[ServicePointType.NGO_PARTNER.name.lowercase()] = ServicePointType.NGO_PARTNER
58-
map[ServicePointType.SITE_COMMUNAUTAIRE.name.lowercase()] = ServicePointType.SITE_COMMUNAUTAIRE
59-
map[ServicePointType.DRJS.name.lowercase()] = ServicePointType.DRJS
60-
map[ServicePointType.INSTAT.name.lowercase()] = ServicePointType.INSTAT
61-
map[ServicePointType.BSD.name.lowercase()] = ServicePointType.BSD
62-
map[ServicePointType.MEN.name.lowercase()] = ServicePointType.MEN
63-
map[ServicePointType.DREN.name.lowercase()] = ServicePointType.DREN
64-
map[ServicePointType.DISTRICT_PPSPF.name.lowercase()] = ServicePointType.DISTRICT_PPSPF
65-
map[ServicePointType.MAIRIE.name.lowercase()] = ServicePointType.MAIRIE
66-
map[ServicePointType.ECOLE_COMMUNAUTAIRE.name.lowercase()] =
67-
ServicePointType.ECOLE_COMMUNAUTAIRE
68-
map[ServicePointType.ECOLE_PRIVÉ.name.lowercase()] = ServicePointType.ECOLE_PRIVÉ
69-
map[ServicePointType.ECOLE_PUBLIQUE.name.lowercase()] = ServicePointType.ECOLE_PUBLIQUE
70-
map[ServicePointType.CENTRE_DE_SANTE.name.lowercase()] = ServicePointType.CENTRE_DE_SANTE
71-
map[ServicePointType.CENTRE_DE_TRAITEMENT_DU_CHOLERA.name.lowercase()] =
72-
ServicePointType.CENTRE_DE_TRAITEMENT_DU_CHOLERA
73-
map[ServicePointType.HOPITAL_COMMUNAL.name.lowercase()] = ServicePointType.HOPITAL_COMMUNAL
74-
map[ServicePointType.HOPITAL.name.lowercase()] = ServicePointType.HOPITAL
75-
map[ServicePointType.BUREAU_DES_PARTENAIRES.name.lowercase()] =
76-
ServicePointType.BUREAU_DES_PARTENAIRES
77-
map[ServicePointType.LYCÉE.name.lowercase()] = ServicePointType.LYCÉE
78-
map[ServicePointType.DIRECTION_COMMUNALE_DE_L_ENSEIGNEMENT.name.lowercase()] =
79-
ServicePointType.DIRECTION_COMMUNALE_DE_L_ENSEIGNEMENT
80-
map[ServicePointType.ECOLE_PRIVE.name.lowercase()] = ServicePointType.ECOLE_PRIVE
81-
return map
79+
// Use the class-level list to create the map
80+
return servicePointTypes.associateBy { it.name.lowercase() }
8281
}
8382
}

android/geowidget/src/test/java/org/smartregister/fhircore/geowidget/screens/GeoWidgetViewModelTest.kt

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -113,39 +113,12 @@ class GeoWidgetViewModelTest {
113113

114114
@Test
115115
fun testThatMapOfServicePointTypeReturnsEnumValuesBasedOnTheirLowercaseNames() {
116-
val result = geoWidgetViewModel.getServicePointKeyToType()
117-
val expectedMap =
118-
mapOf(
119-
"epp" to ServicePointType.EPP,
120-
"ceg" to ServicePointType.CEG,
121-
"chrd1" to ServicePointType.CHRD1,
122-
"chrd2" to ServicePointType.CHRD2,
123-
"drsp" to ServicePointType.DRSP,
124-
"msp" to ServicePointType.MSP,
125-
"sdsp" to ServicePointType.SDSP,
126-
"csb1" to ServicePointType.CSB1,
127-
"csb2" to ServicePointType.CSB2,
128-
"chrr" to ServicePointType.CHRR,
129-
"warehouse" to ServicePointType.WAREHOUSE,
130-
"water_point" to ServicePointType.WATER_POINT,
131-
"presco" to ServicePointType.PRESCO,
132-
"meah" to ServicePointType.MEAH,
133-
"dreah" to ServicePointType.DREAH,
134-
"mppspf" to ServicePointType.MPPSPF,
135-
"drppspf" to ServicePointType.DRPPSPF,
136-
"ngo_partner" to ServicePointType.NGO_PARTNER,
137-
"site_communautaire" to ServicePointType.SITE_COMMUNAUTAIRE,
138-
"drjs" to ServicePointType.DRJS,
139-
"instat" to ServicePointType.INSTAT,
140-
"bsd" to ServicePointType.BSD,
141-
"men" to ServicePointType.MEN,
142-
"dren" to ServicePointType.DREN,
143-
"district_ppspf" to ServicePointType.DISTRICT_PPSPF,
144-
"mairie" to ServicePointType.MAIRIE,
145-
"ecole_communautaire" to ServicePointType.ECOLE_COMMUNAUTAIRE,
146-
"ecole_privé" to ServicePointType.ECOLE_PRIVÉ,
147-
"lycée" to ServicePointType.LYCÉE,
148-
)
149-
Assert.assertEquals(expectedMap, result)
116+
val servicePointTypeMap = geoWidgetViewModel.getServicePointKeyToType()
117+
118+
ServicePointType.entries.forEach { servicePointType ->
119+
val expectedValue = servicePointType.name.lowercase()
120+
val actualValue = servicePointTypeMap[expectedValue]
121+
Assert.assertEquals(servicePointType, actualValue)
122+
}
150123
}
151124
}

android/gradle.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ android.useAndroidX=true
2020
android.enableJetifier=true
2121
android.defaults.buildfeatures.buildconfig=true
2222
android.suppressUnsupportedCompileSdk=34
23+
android.testInstrumentationRunnerArguments.useTestStorageService=true
2324
android.jetifier.ignorelist=jackson-core
2425
#org.gradle.daemon.max-idle-time=10800000 // 3 hours in milliseconds
2526

2627
org.gradle.warning.mode=all
27-
org.gradle.configuration-cache=true
28+
# set configuration-cache to false in order to avoid macrobenchmark failure
29+
org.gradle.configuration-cache=false
2830
org.gradle.caching=false
2931
org.gradle.parallel=true
3032
org.gradle.configureondemand=true

0 commit comments

Comments
 (0)