diff --git a/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/di/AppModule.kt b/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/di/AppModule.kt index a858a38c7..6ace94977 100644 --- a/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/di/AppModule.kt +++ b/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/di/AppModule.kt @@ -30,6 +30,7 @@ import com.google.samples.apps.nowinandroid.feature.interests.di.interestModule import com.google.samples.apps.nowinandroid.feature.search.di.searchModule import com.google.samples.apps.nowinandroid.feature.settings.di.settingsModule import com.google.samples.apps.nowinandroid.feature.topic.di.topicModule +import com.google.samples.apps.nowinandroid.sync.di.syncModule import com.google.samples.apps.nowinandroid.ui.interests2pane.Interests2PaneViewModel import org.koin.core.annotation.ComponentScan import org.koin.core.annotation.Module @@ -68,6 +69,7 @@ internal val appModules = module { notificationModule, ) includes(featureModules) + includes(syncModule) includes(appViewModelModule) includes(AppModule().module) } diff --git a/feature/foryou/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/di/ForYouModule.kt b/feature/foryou/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/di/ForYouModule.kt index 2031e63b9..f2510d59f 100644 --- a/feature/foryou/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/di/ForYouModule.kt +++ b/feature/foryou/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/di/ForYouModule.kt @@ -18,8 +18,9 @@ package com.google.samples.apps.nowinandroid.feature.foryou.di import com.google.samples.apps.nowinandroid.feature.foryou.ForYouViewModel import org.koin.core.module.dsl.viewModel +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module val forYouModule = module { - viewModel { ForYouViewModel(get(), get(), get(), get(), get(), get()) } + viewModelOf(::ForYouViewModel) } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 0eb5d1bba..4b56ead00 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -38,6 +38,7 @@ kotlin { api(projects.core.model) api(projects.core.analytics) api(projects.core.notifications) + api(projects.sync.work) api(compose.components.resources) } commonTest.dependencies { diff --git a/sync/work/build.gradle.kts b/sync/work/build.gradle.kts index 7b4b55a18..1f9a20044 100644 --- a/sync/work/build.gradle.kts +++ b/sync/work/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.kmp.library) alias(libs.plugins.nowinandroid.android.library.jacoco) - alias(libs.plugins.nowinandroid.hilt) + alias(libs.plugins.nowinandroid.di.koin) } android { @@ -26,21 +26,28 @@ android { namespace = "com.google.samples.apps.nowinandroid.sync" } -dependencies { - ksp(libs.hilt.ext.compiler) - - implementation(libs.androidx.tracing.ktx) - implementation(libs.androidx.work.ktx) - implementation(libs.hilt.ext.work) - implementation(projects.core.analytics) - implementation(projects.core.data) - implementation(projects.core.notifications) - - prodImplementation(libs.firebase.cloud.messaging) - prodImplementation(platform(libs.firebase.bom)) - - androidTestImplementation(libs.androidx.work.testing) - androidTestImplementation(libs.hilt.android.testing) - androidTestImplementation(libs.kotlinx.coroutines.guava) - androidTestImplementation(projects.core.testing) +kotlin { + sourceSets{ + commonMain.dependencies { + implementation(projects.core.analytics) + implementation(projects.core.data) + implementation(projects.core.notifications) + } + commonTest.dependencies { + implementation(projects.core.testing) + } + androidMain.dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.tracing.ktx) + implementation(libs.androidx.work.ktx) + } + androidInstrumentedTest.dependencies { + implementation(projects.core.testing) + implementation(libs.androidx.work.testing) + implementation(libs.kotlinx.coroutines.guava) + } + } } + +// prodImplementation(libs.firebase.cloud.messaging) +// prodImplementation(platform(libs.firebase.bom)) diff --git a/sync/work/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt b/sync/work/src/androidInstrumentedTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt similarity index 95% rename from sync/work/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt rename to sync/work/src/androidInstrumentedTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt index 9c9d13510..4822d3eb5 100644 --- a/sync/work/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt +++ b/sync/work/src/androidInstrumentedTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt @@ -23,14 +23,12 @@ import androidx.work.WorkInfo import androidx.work.WorkManager import androidx.work.testing.SynchronousExecutor import androidx.work.testing.WorkManagerTestInitHelper -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest import org.junit.Before import org.junit.Rule import org.junit.Test import kotlin.test.assertEquals -@HiltAndroidTest +//@HiltAndroidTest class SyncWorkerTest { @get:Rule(order = 0) diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt similarity index 96% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt rename to sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt index 0a631534b..17ddca172 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt +++ b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2024 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. diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt similarity index 92% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt rename to sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt index 6c4a29373..8a14d1593 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt +++ b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2024 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. @@ -71,7 +71,8 @@ private fun Context.syncWorkNotification(): Notification { SYNC_NOTIFICATION_CHANNEL_ID, ) .setSmallIcon( - com.google.samples.apps.nowinandroid.core.notifications.R.drawable.core_notifications_ic_nia_notification, + android.R.drawable.stat_notify_sync, +// com.google.samples.apps.nowinandroid.core.notifications.R.drawable.core_notifications_ic_nia_notification, ) .setContentTitle(getString(R.string.sync_work_notification_title)) .setPriority(NotificationCompat.PRIORITY_DEFAULT) diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt similarity index 88% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt rename to sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt index d4b6e0df6..3d08e4446 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt +++ b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2024 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. @@ -24,17 +24,14 @@ import androidx.work.WorkManager import com.google.samples.apps.nowinandroid.core.data.util.SyncManager import com.google.samples.apps.nowinandroid.sync.initializers.SYNC_WORK_NAME import com.google.samples.apps.nowinandroid.sync.workers.SyncWorker -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.map -import javax.inject.Inject - /** * [SyncManager] backed by [WorkInfo] from [WorkManager] */ -internal class WorkManagerSyncManager @Inject constructor( - @ApplicationContext private val context: Context, +internal class WorkManagerSyncManager( + private val context: Context, ) : SyncManager { override val isSyncing: Flow = WorkManager.getInstance(context).getWorkInfosForUniqueWorkFlow(SYNC_WORK_NAME) diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt similarity index 73% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt rename to sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt index 0114ad6ec..b9842f397 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt +++ b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt @@ -17,25 +17,20 @@ package com.google.samples.apps.nowinandroid.sync.workers import android.content.Context -import androidx.hilt.work.HiltWorkerFactory import androidx.work.CoroutineWorker import androidx.work.Data import androidx.work.ForegroundInfo import androidx.work.WorkerParameters -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.android.EntryPointAccessors -import dagger.hilt.components.SingletonComponent import kotlin.reflect.KClass -/** - * An entry point to retrieve the [HiltWorkerFactory] at runtime - */ -@EntryPoint -@InstallIn(SingletonComponent::class) -interface HiltWorkerFactoryEntryPoint { - fun hiltWorkerFactory(): HiltWorkerFactory -} +///** +// * An entry point to retrieve the [HiltWorkerFactory] at runtime +// */ +//@EntryPoint +//@InstallIn(SingletonComponent::class) +//interface HiltWorkerFactoryEntryPoint { +// fun hiltWorkerFactory(): HiltWorkerFactory +//} private const val WORKER_CLASS_NAME = "RouterWorkerDelegateClassName" @@ -65,12 +60,14 @@ class DelegatingWorker( private val workerClassName = workerParams.inputData.getString(WORKER_CLASS_NAME) ?: "" - private val delegateWorker = - EntryPointAccessors.fromApplication(appContext) - .hiltWorkerFactory() - .createWorker(appContext, workerClassName, workerParams) - as? CoroutineWorker - ?: throw IllegalArgumentException("Unable to find appropriate worker") +// private val delegateWorker = +// EntryPointAccessors.fromApplication(appContext) +// .hiltWorkerFactory() +// .createWorker(appContext, workerClassName, workerParams) +// as? CoroutineWorker +// ?: throw IllegalArgumentException("Unable to find appropriate worker") + + private val delegateWorker: DelegatingWorker = TODO() override suspend fun getForegroundInfo(): ForegroundInfo = delegateWorker.getForegroundInfo() diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt similarity index 87% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt rename to sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt index ea5f36042..5c5af802e 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt +++ b/sync/work/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2024 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. @@ -17,7 +17,6 @@ package com.google.samples.apps.nowinandroid.sync.workers import android.content.Context -import androidx.hilt.work.HiltWorker import androidx.tracing.traceAsync import androidx.work.CoroutineWorker import androidx.work.ForegroundInfo @@ -31,13 +30,9 @@ import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsR import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.datastore.ChangeListVersions import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource -import com.google.samples.apps.nowinandroid.core.network.Dispatcher -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.sync.initializers.SyncConstraints import com.google.samples.apps.nowinandroid.sync.initializers.syncForegroundInfo import com.google.samples.apps.nowinandroid.sync.status.SyncSubscriber -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -47,15 +42,14 @@ import kotlinx.coroutines.withContext * Syncs the data layer by delegating to the appropriate repository instances with * sync functionality. */ -@HiltWorker -internal class SyncWorker @AssistedInject constructor( - @Assisted private val appContext: Context, - @Assisted workerParams: WorkerParameters, +internal class SyncWorker( + private val appContext: Context, + workerParams: WorkerParameters, private val niaPreferences: NiaPreferencesDataSource, private val topicRepository: TopicsRepository, private val newsRepository: NewsRepository, private val searchContentsRepository: SearchContentsRepository, - @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, + private val ioDispatcher: CoroutineDispatcher, private val analyticsHelper: AnalyticsHelper, private val syncSubscriber: SyncSubscriber, ) : CoroutineWorker(appContext, workerParams), Synchronizer { diff --git a/sync/work/src/main/res/values/strings.xml b/sync/work/src/androidMain/res/values/strings.xml similarity index 99% rename from sync/work/src/main/res/values/strings.xml rename to sync/work/src/androidMain/res/values/strings.xml index 4d77f6a7b..3016071fb 100644 --- a/sync/work/src/main/res/values/strings.xml +++ b/sync/work/src/androidMain/res/values/strings.xml @@ -18,5 +18,4 @@ Now in Android Sync Background tasks for Now in Android - diff --git a/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt new file mode 100644 index 000000000..70cd1c851 --- /dev/null +++ b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2024 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.sync.di + +import com.google.samples.apps.nowinandroid.core.data.util.SyncManager +import com.google.samples.apps.nowinandroid.sync.status.StubSyncSubscriber +import com.google.samples.apps.nowinandroid.sync.status.SyncSubscriber +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import org.koin.dsl.module + +val syncModule = module { + // TODO use the actual implementation for syncing data + single { StubSyncSubscriber() } + single { + object : SyncManager { + override val isSyncing: Flow + get() = flowOf(false) + + override fun requestSync() { + // no-op + } + } + } +} diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt similarity index 79% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt rename to sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt index 0ef90fb29..bad4e180c 100644 --- a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt +++ b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt @@ -16,16 +16,13 @@ package com.google.samples.apps.nowinandroid.sync.status -import android.util.Log -import javax.inject.Inject - -private const val TAG = "StubSyncSubscriber" +import co.touchlab.kermit.Logger /** * Stub implementation of [SyncSubscriber] */ -class StubSyncSubscriber @Inject constructor() : SyncSubscriber { +class StubSyncSubscriber : SyncSubscriber { override suspend fun subscribe() { - Log.d(TAG, "Subscribing to sync") + Logger.d { "Subscribing to sync" } } } diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt similarity index 100% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt rename to sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt diff --git a/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt b/sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt similarity index 100% rename from sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt rename to sync/work/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt