From 1a89c975b8c067858a3753cb45dc2b77c4126851 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 22 Apr 2023 15:38:35 +0200 Subject: [PATCH 1/5] Add Application-wide `CoroutineScope` in the DI graph Following the work of #607. --- .../core/network/di/CoroutineScopesModule.kt | 39 +++++++++++++++++++ .../datastore/test/TestDataStoreModule.kt | 7 +--- .../core/datastore/di/DataStoreModule.kt | 6 +-- 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt new file mode 100644 index 000000000..bc44e394d --- /dev/null +++ b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.network.di + +import com.google.samples.apps.nowinandroid.core.network.Dispatcher +import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object CoroutineScopesModule { + @Provides + @Singleton + @Dispatcher(IO) + fun providesIOCoroutineScope( + @Dispatcher(IO) ioDispatcher: CoroutineDispatcher, + ): CoroutineScope = CoroutineScope(SupervisorJob() + ioDispatcher) +} diff --git a/core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt b/core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt index fad7ac382..cb7e38db7 100644 --- a/core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt +++ b/core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt @@ -27,9 +27,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent import dagger.hilt.testing.TestInstallIn -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob import org.junit.rules.TemporaryFolder import javax.inject.Singleton @@ -43,13 +41,12 @@ object TestDataStoreModule { @Provides @Singleton fun providesUserPreferencesDataStore( - @Dispatcher(IO) ioDispatcher: CoroutineDispatcher, + @Dispatcher(IO) ioScope: CoroutineScope, userPreferencesSerializer: UserPreferencesSerializer, tmpFolder: TemporaryFolder, ): DataStore = tmpFolder.testUserPreferencesDataStore( - // TODO: Provide an application-wide CoroutineScope in the DI graph - coroutineScope = CoroutineScope(SupervisorJob() + ioDispatcher), + coroutineScope = ioScope, userPreferencesSerializer = userPreferencesSerializer, ) } diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt index 895e22307..89a6eb734 100644 --- a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt +++ b/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt @@ -30,9 +30,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob import javax.inject.Singleton @Module @@ -43,12 +41,12 @@ object DataStoreModule { @Singleton fun providesUserPreferencesDataStore( @ApplicationContext context: Context, - @Dispatcher(IO) ioDispatcher: CoroutineDispatcher, + @Dispatcher(IO) ioScope: CoroutineScope, userPreferencesSerializer: UserPreferencesSerializer, ): DataStore = DataStoreFactory.create( serializer = userPreferencesSerializer, - scope = CoroutineScope(ioDispatcher + SupervisorJob()), + scope = ioScope, migrations = listOf( IntToStringIdsMigration, ), From c0f1423427e5f311babc71df584c7787ee30a513 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 22 Apr 2023 15:46:15 +0200 Subject: [PATCH 2/5] Run Spotless --- .../core/network/di/CoroutineScopesModule.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt index bc44e394d..b73c63568 100644 --- a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt +++ b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt @@ -1,17 +1,17 @@ /* * Copyright 2023 The Android Open Source Project * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.google.samples.apps.nowinandroid.core.network.di From 6e47364af319227dcbcb5adbb32243a727a20acb Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 19 May 2023 11:45:38 +0100 Subject: [PATCH 3/5] Grant `POST_NOTIFICATIONS` permission in instrumented tests --- .../apps/nowinandroid/feature/foryou/ForYouScreenTest.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index eb27473bb..404ad55b9 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.feature.foryou +import android.Manifest import androidx.activity.ComponentActivity import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.ui.test.assertHasClickAction @@ -28,6 +29,8 @@ import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode +import androidx.test.rule.GrantPermissionRule +import androidx.test.rule.GrantPermissionRule.grant import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState @@ -35,6 +38,10 @@ import org.junit.Rule import org.junit.Test class ForYouScreenTest { + + @get:Rule + val permissionTestRule: GrantPermissionRule = grant(Manifest.permission.POST_NOTIFICATIONS) + @get:Rule val composeTestRule = createAndroidComposeRule() From d6ea3cb8b9b93c1c87fcbe14fd45db0d7b930a4d Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 19 May 2023 12:28:01 +0100 Subject: [PATCH 4/5] Grant permission only if TIRAMISU or above --- .../apps/nowinandroid/feature/foryou/ForYouScreenTest.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index 404ad55b9..7a750a13d 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -17,6 +17,8 @@ package com.google.samples.apps.nowinandroid.feature.foryou import android.Manifest +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.TIRAMISU import androidx.activity.ComponentActivity import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.ui.test.assertHasClickAction @@ -40,7 +42,9 @@ import org.junit.Test class ForYouScreenTest { @get:Rule - val permissionTestRule: GrantPermissionRule = grant(Manifest.permission.POST_NOTIFICATIONS) + val permissionTestRule: GrantPermissionRule = + if (SDK_INT < TIRAMISU) grant() + else grant(Manifest.permission.POST_NOTIFICATIONS) @get:Rule val composeTestRule = createAndroidComposeRule() From 38c75556cffd1a93a08788e4022b087901b6d75b Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 19 May 2023 12:51:35 +0100 Subject: [PATCH 5/5] Update ForYouScreenTest.kt --- .../apps/nowinandroid/feature/foryou/ForYouScreenTest.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index 7a750a13d..b138cba06 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -43,8 +43,11 @@ class ForYouScreenTest { @get:Rule val permissionTestRule: GrantPermissionRule = - if (SDK_INT < TIRAMISU) grant() - else grant(Manifest.permission.POST_NOTIFICATIONS) + if (SDK_INT >= TIRAMISU) { + grant(Manifest.permission.POST_NOTIFICATIONS) + } else { + grant() + } @get:Rule val composeTestRule = createAndroidComposeRule()