diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index b858a27d7..c67d3b3d8 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -43,9 +43,6 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - validate-wrappers: true - gradle-home-cache-cleanup: true - name: Setup Android SDK uses: android-actions/setup-android@v3 diff --git a/.github/workflows/NightlyBaselineProfiles.yaml b/.github/workflows/NightlyBaselineProfiles.yaml index b72e4ad19..288842ac7 100644 --- a/.github/workflows/NightlyBaselineProfiles.yaml +++ b/.github/workflows/NightlyBaselineProfiles.yaml @@ -18,8 +18,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + ls /dev/kvm - name: Copy CI gradle.properties run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties @@ -30,6 +34,18 @@ jobs: distribution: 'zulu' java-version: 17 + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Accept licenses + run: yes | sdkmanager --licenses || true + + - name: Check build-logic + run: ./gradlew check -p build-logic + - name: Setup GMD run: ./gradlew :benchmarks:pixel6Api33Setup --info diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 73ab89bfa..71ee060e1 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -33,9 +33,6 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - validate-wrappers: true - gradle-home-cache-cleanup: true - name: Setup Android SDK uses: android-actions/setup-android@v3 diff --git a/.google/BUILDME b/.google/BUILDME index 5295ed188..d6b23eab3 100644 --- a/.google/BUILDME +++ b/.google/BUILDME @@ -1,2 +1,2 @@ # This file can be used to trigger an internal build by changing the number below -3 +2 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 412429810..07676ce59 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -48,7 +48,7 @@ android { release { isMinifyEnabled = true applicationIdSuffix = NiaBuildType.RELEASE.applicationIdSuffix - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) // To publish on the Play store a private signing key is required, but to allow anyone // who clones the code to sign and run the release variant, use the debug signing key. diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro deleted file mode 100644 index 5f4922bce..000000000 --- a/app/proguard-rules.pro +++ /dev/null @@ -1,9 +0,0 @@ -# Fix for Retrofit issue https://github.com/square/retrofit/issues/3751 -# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items). --keep,allowobfuscation,allowshrinking interface retrofit2.Call --keep,allowobfuscation,allowshrinking class retrofit2.Response - -# With R8 full mode generic signatures are stripped for classes that are not -# kept. Suspend functions are wrapped in continuations where the type argument -# is used. --keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index e2557b2d5..0fab38e17 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -77,7 +77,7 @@ class MainActivity : ComponentActivity(), ApplicationComponentProvider { @Inject lateinit var userNewsResourceRepository: UserNewsResourceRepository - val viewModel: MainActivityViewModel by viewModels() + private val viewModel: MainActivityViewModel by viewModels() override val component by lazy(LazyThreadSafetyMode.NONE) { ApplicationComponent::class.create(applicationContext) diff --git a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt index fbff1abbf..e0223f5f9 100644 --- a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt +++ b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt @@ -61,20 +61,18 @@ class BookmarksViewModelTest { @Test fun oneBookmark_showsInFeed() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.feedUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedUiState.collect() } newsRepository.sendNewsResources(newsResourcesTestData) userDataRepository.setNewsResourceBookmarked(newsResourcesTestData[0].id, true) val item = viewModel.feedUiState.value assertIs(item) assertEquals(item.feed.size, 1) - - collectJob.cancel() } @Test fun oneBookmark_whenRemoving_removesFromFeed() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.feedUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedUiState.collect() } // Set the news resources to be used by this test newsRepository.sendNewsResources(newsResourcesTestData) // Start with the resource saved @@ -85,7 +83,5 @@ class BookmarksViewModelTest { val item = viewModel.feedUiState.value assertIs(item) assertEquals(item.feed.size, 0) - - collectJob.cancel() } } diff --git a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index eece140ac..812544c0c 100644 --- a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -98,9 +98,8 @@ class ForYouViewModelTest { @Test fun stateIsLoadingWhenFollowedTopicsAreLoading() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) @@ -109,31 +108,24 @@ class ForYouViewModelTest { viewModel.onboardingUiState.value, ) assertEquals(NewsFeedUiState.Loading, viewModel.feedState.value) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun stateIsLoadingWhenAppIsSyncingWithNoInterests() = runTest { syncManager.setSyncing(true) - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.isSyncing.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.isSyncing.collect() } assertEquals( true, viewModel.isSyncing.value, ) - - collectJob.cancel() } @Test fun onboardingStateIsLoadingWhenTopicsAreLoading() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } userDataRepository.setFollowedTopicIds(emptySet()) @@ -142,16 +134,12 @@ class ForYouViewModelTest { viewModel.onboardingUiState.value, ) assertEquals(NewsFeedUiState.Success(emptyList()), viewModel.feedState.value) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun onboardingIsShownWhenNewsResourcesAreLoading() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) userDataRepository.setFollowedTopicIds(emptySet()) @@ -202,16 +190,12 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun onboardingIsShownAfterLoadingEmptyFollowedTopics() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) userDataRepository.setFollowedTopicIds(emptySet()) @@ -263,16 +247,12 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun onboardingIsNotShownAfterUserDismissesOnboarding() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) @@ -299,16 +279,12 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun topicSelectionUpdatesAfterSelectingTopic() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) userDataRepository.setFollowedTopicIds(emptySet()) @@ -352,16 +328,12 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun topicSelectionUpdatesAfterUnselectingTopic() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) userDataRepository.setFollowedTopicIds(emptySet()) @@ -416,16 +388,12 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun newsResourceSelectionUpdatesAfterLoadingFollowedTopics() = runTest { - val collectJob1 = - launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } - val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } val followedTopicIds = setOf("1") val userData = emptyUserData.copy( @@ -460,15 +428,11 @@ class ForYouViewModelTest { ), viewModel.feedState.value, ) - - collectJob1.cancel() - collectJob2.cancel() } @Test fun deepLinkedNewsResourceIsFetchedAndResetAfterViewing() = runTest { - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.deepLinkedNewsResource.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.deepLinkedNewsResource.collect() } newsRepository.sendNewsResources(sampleNewsResources) userDataRepository.setUserData(emptyUserData) @@ -503,8 +467,6 @@ class ForYouViewModelTest { ), ), ) - - collectJob.cancel() } @Test diff --git a/feature/interests/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt b/feature/interests/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt index 987a5bc01..cdf21f325 100644 --- a/feature/interests/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt +++ b/feature/interests/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt @@ -80,17 +80,15 @@ class InterestsViewModelTest { @Test fun uiState_whenFollowedTopicsAreLoading_thenShowLoading() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } userDataRepository.setFollowedTopicIds(emptySet()) assertEquals(InterestsUiState.Loading, viewModel.uiState.value) - - collectJob.cancel() } @Test fun uiState_whenFollowingNewTopic_thenShowUpdatedTopics() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } val toggleTopicId = testOutputTopics[1].topic.id topicsRepository.sendTopics(testInputTopics.map { it.topic }) @@ -114,13 +112,11 @@ class InterestsViewModelTest { ), viewModel.uiState.value, ) - - collectJob.cancel() } @Test fun uiState_whenUnfollowingTopics_thenShowUpdatedTopics() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.uiState.collect() } val toggleTopicId = testOutputTopics[1].topic.id @@ -147,8 +143,6 @@ class InterestsViewModelTest { ), viewModel.uiState.value, ) - - collectJob.cancel() } } diff --git a/feature/search/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt index c832401de..a62965b52 100644 --- a/feature/search/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt +++ b/feature/search/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt @@ -85,20 +85,16 @@ class SearchViewModelTest { fun stateIsEmptyQuery_withEmptySearchQuery() = runTest { searchContentsRepository.addNewsResources(newsResourcesTestData) searchContentsRepository.addTopics(topicsTestData) - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } viewModel.onSearchQueryChanged("") assertEquals(EmptyQuery, viewModel.searchResultUiState.value) - - collectJob.cancel() } @Test fun emptyResultIsReturned_withNotMatchingQuery() = runTest { - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } viewModel.onSearchQueryChanged("XXX") searchContentsRepository.addNewsResources(newsResourcesTestData) @@ -106,32 +102,24 @@ class SearchViewModelTest { val result = viewModel.searchResultUiState.value assertIs(result) - - collectJob.cancel() } @Test fun recentSearches_verifyUiStateIsSuccess() = runTest { - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() } viewModel.onSearchTriggered("kotlin") val result = viewModel.recentSearchQueriesUiState.value assertIs(result) - - collectJob.cancel() } @Test fun searchNotReady_withNoFtsTableEntity() = runTest { - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } viewModel.onSearchQueryChanged("") assertEquals(SearchNotReady, viewModel.searchResultUiState.value) - - collectJob.cancel() } @Test diff --git a/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt b/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt index 0de463042..a89c8494b 100644 --- a/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt +++ b/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt @@ -49,8 +49,7 @@ class SettingsViewModelTest { @OptIn(ExperimentalCoroutinesApi::class) @Test fun stateIsSuccessAfterUserDataLoaded() = runTest { - val collectJob = - launch(UnconfinedTestDispatcher()) { viewModel.settingsUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.settingsUiState.collect() } userDataRepository.setThemeBrand(ANDROID) userDataRepository.setDarkThemeConfig(DARK) @@ -65,7 +64,5 @@ class SettingsViewModelTest { ), viewModel.settingsUiState.value, ) - - collectJob.cancel() } } diff --git a/feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index c14e62e31..34f21a59a 100644 --- a/feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -85,7 +85,7 @@ class TopicViewModelTest { @Test fun uiStateTopic_whenSuccess_matchesTopicFromRepository() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } topicsRepository.sendTopics(testInputTopics.map(FollowableTopic::topic)) userDataRepository.setFollowedTopicIds(setOf(testInputTopics[1].topic.id)) @@ -97,8 +97,6 @@ class TopicViewModelTest { ).first() assertEquals(topicFromRepository, item.followableTopic.topic) - - collectJob.cancel() } @Test @@ -113,18 +111,16 @@ class TopicViewModelTest { @Test fun uiStateTopic_whenFollowedIdsSuccessAndTopicLoading_thenShowLoading() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } userDataRepository.setFollowedTopicIds(setOf(testInputTopics[1].topic.id)) assertEquals(TopicUiState.Loading, viewModel.topicUiState.value) - - collectJob.cancel() } @Test fun uiStateTopic_whenFollowedIdsSuccessAndTopicSuccess_thenTopicSuccessAndNewsLoading() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } topicsRepository.sendTopics(testInputTopics.map { it.topic }) userDataRepository.setFollowedTopicIds(setOf(testInputTopics[1].topic.id)) @@ -133,14 +129,12 @@ class TopicViewModelTest { assertIs(topicUiState) assertIs(newsUiState) - - collectJob.cancel() } @Test fun uiStateTopic_whenFollowedIdsSuccessAndTopicSuccessAndNewsIsSuccess_thenAllSuccess() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { + backgroundScope.launch(UnconfinedTestDispatcher()) { combine( viewModel.topicUiState, viewModel.newsUiState, @@ -155,13 +149,11 @@ class TopicViewModelTest { assertIs(topicUiState) assertIs(newsUiState) - - collectJob.cancel() } @Test fun uiStateTopic_whenFollowingTopic_thenShowUpdatedTopic() = runTest { - val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } + backgroundScope.launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() } topicsRepository.sendTopics(testInputTopics.map { it.topic }) // Set which topic IDs are followed, not including 0. @@ -173,8 +165,6 @@ class TopicViewModelTest { TopicUiState.Success(followableTopic = testOutputTopics[0]), viewModel.topicUiState.value, ) - - collectJob.cancel() } } diff --git a/gradle.properties b/gradle.properties index deb11f49b..56617a333 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,23 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Ensure important default jvmargs aren't overwritten. See https://github.com/gradle/gradle/issues/19750 -org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g +# +# For more information about how Gradle memory options were chosen: +# - Metaspace See https://www.jasonpearson.dev/metaspace-in-jvm-builds/ +# - SoftRefLRUPolicyMSPerMB would default to 1000 which with a 4gb heap translates to ~51 minutes. +# A value of 1 means ~4 seconds before SoftRefs can be collected, which means its realistic to +# collect them as needed during a build that should take seconds to minutes. +# - CodeCache normally defaults to a very small size. Increasing it from platform defaults of 32-48m +# because of how many classes can be loaded into memory and then cached as native compiled code +# for a small speed boost. +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx4g -Xms4g + +# For more information about how Kotlin Daemon memory options were chosen: +# - Kotlin JVM args only inherit Xmx, ReservedCodeCache, and MaxMetaspace. Since we are specifying +# other args we need to specify all of them here. +# - We're using the Kotlin Gradle Plugin's default value for ReservedCodeCacheSize, if we do not then +# the Gradle JVM arg value for ReservedCodeCacheSize will be used. +kotlin.daemon.jvmargs=-Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:ReservedCodeCacheSize=320m -XX:+HeapDumpOnOutOfMemoryError -Xmx4g -Xms4g # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ce2b6d3ed..0d21a6a75 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -158,7 +158,7 @@ okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", protobuf-kotlin-lite = { group = "com.google.protobuf", name = "protobuf-kotlin-lite", version.ref = "protobuf" } protobuf-protoc = { group = "com.google.protobuf", name = "protoc", version.ref = "protobuf" } retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } -retrofit-kotlin-serialization = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "retrofitKotlinxSerializationJson" } +retrofit-kotlin-serialization = { group = "com.squareup.retrofit2", name = "converter-kotlinx-serialization", version.ref = "retrofit" } robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" } roborazzi = { group = "io.github.takahirom.roborazzi", name = "roborazzi", version.ref = "roborazzi" } room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }