8000 Decouple the DaggerWorkerFactory using plugins (#1075) · libandroid/Android@05e86b4 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 05e86b4

Browse files
authored
Decouple the DaggerWorkerFactory using plugins (duckduckgo#1075)
* Decouple the DaggerWorkerFactory using plugins * Fix ClearDataNotificationWorkerInjectorPlugin
1 parent 17cfcb2 commit 05e86b4

File tree

11 files changed

+261
-93
lines changed

11 files changed

+261
-93
lines changed

app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.duckduckgo.app.browser.di.BrowserModule
2323
import com.duckduckgo.app.browser.favicon.FaviconModule
2424
import com.duckduckgo.app.browser.rating.di.RatingModule
2525
import com.duckduckgo.app.global.exception.UncaughtExceptionModule
26+
import com.duckduckgo.app.global.plugins.worker.WorkerPluginsModule
2627
import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule
2728
import com.duckduckgo.app.onboarding.di.OnboardingModule
2829
import com.duckduckgo.app.onboarding.di.WelcomePageModule
@@ -48,6 +49,7 @@ import javax.inject.Singleton
4849
StubStatisticsModule::class,
4950

5051
/* real modules */
52+
WorkerPluginsModule::class,
5153
ApplicationModule::class,
5254
WorkerModule::class,
5355
AndroidBindingModule::class,

app/src/main/java/com/duckduckgo/app/di/AppComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.duckduckgo.app.browser.favicon.FaviconModule
2424
import com.duckduckgo.app.browser.rating.di.RatingModule
2525
import com.duckduckgo.app.global.DuckDuckGoApplication
2626
import com.duckduckgo.app.global.exception.UncaughtExceptionModule
27+
import com.duckduckgo.app.global.plugins.worker.WorkerPluginsModule
2728
import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule
2829
import com.duckduckgo.app.onboarding.di.OnboardingModule
2930
import com.duckduckgo.app.onboarding.di.WelcomePageModule
@@ -41,6 +42,7 @@ import javax.inject.Singleton
4142
@Singleton
4243
@Component(
4344
modules = [
45+
WorkerPluginsModule::class,
4446
ApplicationModule::class,
4547
JobsModule::class,
4648
WorkerModule::class,

app/src/main/java/com/duckduckgo/app/di/DaggerWorkerFactory.kt

Lines changed: 8 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,14 @@
1717
package com.duckduckgo.app.di
1818

1919
import android.content.Context
20-
import androidx.core.app.NotificationManagerCompat
2120
import androidx.work.ListenableWorker
2221
import androidx.work.WorkerFactory
2322
import androidx.work.WorkerParameters
24-
import com.duckduckgo.app.fire.DataClearingWorker
25-
import com.duckduckgo.app.global.job.AppConfigurationWorker
26-
import com.duckduckgo.app.global.view.ClearDataAction
27-
import com.duckduckgo.app.job.ConfigurationDownloader
28-
import com.duckduckgo.app.notification.NotificationFactory
29-
import com.duckduckgo.app.notification.NotificationScheduler.ClearDataNotificationWorker
30-
import com.duckduckgo.app.notification.NotificationScheduler.PrivacyNotificationWorker
31-
import com.duckduckgo.app.notification.db.NotificationDao
32-
import com.duckduckgo.app.notification.model.ClearDataNotification
33-
import com.duckduckgo.app.notification.model.PrivacyProtectionNotification
34-
import com.duckduckgo.app.settings.db.SettingsDataStore
35-
import com.duckduckgo.app.statistics.api.OfflinePixelScheduler
36-
import com.duckduckgo.app.statistics.api.OfflinePixelSender
37-
import com.duckduckgo.app.statistics.pixels.Pixel
23+
import com.duckduckgo.app.global.plugins.worker.WorkerInjectorPluginPoint
3824
import timber.log.Timber
3925

4026
class DaggerWorkerFactory(
41-
private val offlinePixelSender: OfflinePixelSender,
42-
private val settingsDataStore: SettingsDataStore,
43-
private val clearDataAction: ClearDataAction,
44-
private val notificationManager: NotificationManagerCompat,
45-
private val notificationDao: NotificationDao,
46-
private val notificationFactory: NotificationFactory,
47-
private val clearDataNotification: ClearDataNotification,
48-
private val privacyProtectionNotification: PrivacyProtectionNotification,
49-
private val configurationDownloader: ConfigurationDownloader,
50-
private val pixel: Pixel
27+
private val workerInjectorPluginPoint: WorkerInjectorPluginPoint,
5128
) : WorkerFactory() {
5229

5330
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
@@ -57,13 +34,12 @@ class DaggerWorkerFactory(
5734
val constructor = workerClass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
5835
val instance = constructor.newInstance(appContext, workerParameters)
5936

60-
when (instance) {
61-
is OfflinePixelScheduler.OfflinePixelWorker -> injectOfflinePixelWorker(instance)
62-
is DataClearingWorker -> injectDataClearWorker(instance)
63-
is ClearDataNotificationWorker -> injectClearDataNotificationWorker(instance)
64-
is PrivacyNotificationWorker -> injectPrivacyNotificationWorker(instance)
65-
is AppConfigurationWorker -> injectAppConfigurationWorker(instance)
66-
else -> Timber.i("No injection required for worker $workerClassName")
37+
workerInjectorPluginPoint.getPlugins().forEach { plugin ->
38+
if (plugin.inject(instance)) {
39+
Timber.i("Injected using plugin $workerClassName")
40+
return@forEach
41+
}
42+
Timber.i("No injection required for worker $workerClassName")
6743
}
6844

6945
return instance
@@ -73,33 +49,4 @@ class DaggerWorkerFactory(
7349
}
7450

7551
}
76-
77-
private fun injectAppConfigurationWorker(worker: AppConfigurationWorker) {
78-
worker.appConfigurationDownloader = configurationDownloader
79-
}
80-
81-
private fun injectOfflinePixelWorker(worker: OfflinePixelScheduler.OfflinePixelWorker) {
82-
worker.offlinePixelSender = offlinePixelSender
83-
}
84-
85-
private fun injectDataClearWorker(worker: DataClearingWorker) {
86-
worker.settingsDataStore = settingsDataStore
87-
worker.clearDataAction = clearDataAction
88-
}
89-
90-
private fun injectClearDataNotificationWorker(worker: ClearDataNotificationWorker) {
91-
worker.manager = notificationManager
92-
worker.notificationDao = notificationDao
93-
worker.factory = notificationFactory
94-
worker.pixel = pixel
95-
worker.notification = clearDataNotification
96-
}
97-
98-
private fun injectPrivacyNotificationWorker(worker: PrivacyNotificationWorker) {
99-
worker.manager = notificationManager
100-
worker.notificationDao = notificationDao
101-
worker.factory = notificationFactory
102-
worker.pixel = pixel
103-
worker.notification = privacyProtectionNotification
104-
}
10552
}

app/src/main/java/com/duckduckgo/app/di/WorkerModule.kt

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,10 @@
1717
package com.duckduckgo.app.di
1818

1919
import android.content.Context
20-
import androidx.core.app.NotificationManagerCompat
2120
import androidx.work.Configuration
2221
import androidx.work.WorkManager
2322
import androidx.work.WorkerFactory
24-
import com.duckduckgo.app.global.view.ClearDataAction
25-
import com.duckduckgo.app.job.ConfigurationDownloader
26-
import com.duckduckgo.app.notification.NotificationFactory
27-
import com.duckduckgo.app.notification.db.NotificationDao
28-
import com.duckduckgo.app.notification.model.ClearDataNotification
29-
import com.duckduckgo.app.notification.model.PrivacyProtectionNotification
30-
import com.duckduckgo.app.settings.db.SettingsDataStore
31-
import com.duckduckgo.app.statistics.api.OfflinePixelSender
32-
import com.duckduckgo.app.statistics.pixels.Pixel
23+
import com.duckduckgo.app.global.plugins.worker.WorkerInjectorPluginPoint
3324
import dagger.Module
3425
import dagger.Provides
3526
import javax.inject.Singleton
@@ -50,28 +41,8 @@ class WorkerModule {
5041
@Provides
5142
@Singleton
5243
fun workerFactory(
53-
offlinePixelSender: OfflinePixelSender,
54-
settingsDataStore: SettingsDataStore,
55-
clearDataAction: ClearDataAction,
56-
notificationManager: NotificationManagerCompat,
57-
notificationDao: NotificationDao,
58-
notificationFactory: NotificationFactory,
59-
clearDataNotification: ClearDataNotification,
60-
privacyProtectionNotification: PrivacyProtectionNotification,
61-
configurationDownloader: ConfigurationDownloader,
62-
pixel: Pixel
44+
workerInjectorPluginPoint: WorkerInjectorPluginPoint,
6345
): WorkerFactory {
64-
return DaggerWorkerFactory(
65-
offlinePixelSender,
66-
settingsDataStore,
67-
clearDataAction,
68-
notificationManager,
69-
notificationDao,
70-
notificationFactory,
71-
clearDataNotification,
72-
privacyProtectionNotification,
73-
configurationDownloader,
74-
pixel
75-
)
46+
return DaggerWorkerFactory(workerInjectorPluginPoint)
7647
}
7748
}

app/src/main/java/com/duckduckgo/app/fire/DataClearingWorker.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ package com.duckduckgo.app.fire
1919
import android.content.Context
2020
import androidx.annotation.WorkerThread
2121
import androidx.work.CoroutineWorker
22+
import androidx.work.ListenableWorker
2223
import androidx.work.ListenableWorker.Result.success
2324
import androidx.work.WorkerParameters
25+
import com.duckduckgo.app.global.plugins.worker.WorkerInjectorPlugin
2426
import com.duckduckgo.app.global.view.ClearDataAction
2527
import com.duckduckgo.app.settings.clear.ClearWhatOption
2628
import com.duckduckgo.app.settings.db.SettingsDataStore
@@ -87,3 +89,18 @@ class DataClearingWorker(context: Context, workerParams: WorkerParameters) : Cor
8789
const val WORK_REQUEST_TAG = "background-clear-data"
8890
}
8991
}
92+
93+
class DataClearingWorkerInjectorPlugin(
94+
private val settingsDataStore: SettingsDataStore,
95+
private val clearDataAction: ClearDataAction
96+
) : WorkerInjectorPlugin {
97+
98+
override fun inject(worker: ListenableWorker): Boolean {
99+
if (worker is DataClearingWorker) {
100+
worker.settingsDataStore = settingsDataStore
101+
worker.clearDataAction = clearDataAction
102+
return true
103+
}
104+
return false
105+
}
106+
}

app/src/main/java/com/duckduckgo/app/global/job/AppConfigurationSyncWorkRequestBuilder.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.duckduckgo.app.global.job
1818

1919
import android.content.Context
2020
import androidx.work.*
21+
import com.duckduckgo.app.global.plugins.worker.WorkerInjectorPlugin
2122
import com.duckduckgo.app.job.ConfigurationDownloader
2223
import io.reactivex.Single
2324
import timber.log.Timber
@@ -59,3 +60,16 @@ class AppConfigurationWorker(context: Context, workerParams: WorkerParameters) :
5960
}
6061
}
6162
}
63+
64+
class AppConfigurationWorkerInjectorPlugin(
65+
private val configurationDownloader: ConfigurationDownloader
66+
) : WorkerInjectorPlugin {
67+
68+
override fun inject(worker: ListenableWorker): Boolean {
69+
if (worker is AppConfigurationWorker) {
70+
worker.appConfigurationDownloader = configurationDownloader
71+
return true
72+
}
73+
return false
74+
}
75+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2018 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.global.plugins
18+
19+
/**
20+
* A PluginPoint provides a list of plugins of a particular type T
21+
*/
22+
interface PluginPoint<T> {
23+
/**
24+
* @return the list of plugins of type <T>
25+
*/
26+
fun getPlugins(): List<T>
27+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2020 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.global.plugins.worker
18+
19+
import androidx.work.ListenableWorker
20+
import com.duckduckgo.app.global.plugins.PluginPoint
21+
import javax.inject.Inject
22+
import javax.inject.Singleton
23+
24+
interface WorkerInjectorPlugin {
25+
/**
26+
* @return whether the worker has been injected
27+
*/
28+
fun inject(worker: ListenableWorker): Boolean
29+
}
30+
31+
@Singleton
32+
class WorkerInjectorPluginPoint @Inject constructor(
33+
private val injectorPlugins: Set<@JvmSuppressWildcards WorkerInjectorPlugin>
34+
) : PluginPoint<WorkerInjectorPlugin> {
35+
override fun getPlugins(): List<WorkerInjectorPlugin> {
36+
return injectorPlugins.toList()
37+
}
38+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2020 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.global.plugins.worker
18+
19+
import androidx.core.app.NotificationManagerCompat
20+
import com.duckduckgo.app.fire.DataClearingWorkerInjectorPlugin
21+
import com.duckduckgo.app.global.job.AppConfigurationWorkerInjectorPlugin
22+
import com.duckduckgo.app.global.view.ClearDataAction
23+
import com.duckduckgo.app.job.ConfigurationDownloader
24+
import com.duckduckgo.app.notification.ClearDataNotificationWorkerInjectorPlugin
25+
import com.duckduckgo.app.notification.NotificationFactory
26+
import com.duckduckgo.app.notification.PrivacyNotificationWorkerInjectorPlugin
27+
import com.duckduckgo.app.notification.db.NotificationDao
28+
import com.duckduckgo.app.notification.model.ClearDataNotification
29+
import com.duckduckgo.app.notification.model.PrivacyProtectionNotification
30+
import com.duckduckgo.app.settings.db.SettingsDataStore
31+
import com.duckduckgo.app.statistics.api.OfflinePixelSender
32+
import com.duckduckgo.app.statistics.api.OfflinePixelWorkerInjectorPlugin
33+
import com.duckduckgo.app.statistics.pixels.Pixel
34+
import dagger.Module
35+
import dagger.Provides
36+
import dagger.multibindings.IntoSet
37+
38+
@Module
39+
class WorkerPluginsModule {
40+
41+
@Provides
42+
@IntoSet
43+
fun dataClearingWorkerInjectorPlugin(
44+
settingsDataStore: SettingsDataStore,
45+
clearDataAction: ClearDataAction
46+
): WorkerInjectorPlugin = DataClearingWorkerInjectorPlugin(settingsDataStore, clearDataAction)
47+
48+
@Provides
49+
@IntoSet
50+
fun clearDataNotificationWorkerInjectorPlugin(
51+
notificationManagerCompat: NotificationManagerCompat,
52+
notificationDao: NotificationDao,
53+
notificationFactory: NotificationFactory,
54+
pixel: Pixel,
55+
clearDataNotification: ClearDataNotification
56+
): WorkerInjectorPlugin = ClearDataNotificationWorkerInjectorPlugin(
57+
notificationManagerCompat,
58+
notificationDao,
59+
notificationFactory,
60+
pixel,
61+
clearDataNotification
62+
)
63+
64+
@Provides
65+
@IntoSet
66+
fun privacyNotificationWorkerInjectorPlugin(
67+
notificationManagerCompat: NotificationManagerCompat,
68+
notificationDao: NotificationDao,
69+
notificationFactory: NotificationFactory,
70+
pixel: Pixel,
71+
privacyProtectionNotification: PrivacyProtectionNotification
72+
): WorkerInjectorPlugin = PrivacyNotificationWorkerInjectorPlugin(
73+
notificationManagerCompat,
74+
notificationDao,
75+
notificationFactory,
76+
pixel,
77+
privacyProtectionNotification
78+
)
79+
80+
@Provides
81+
@IntoSet
82+
fun appConfigurationWorkerInjectorPlugin(
83+
configurationDownloader: ConfigurationDownloader
84+
): WorkerInjectorPlugin = AppConfigurationWorkerInjectorPlugin(configurationDownloader)
85+
86+
@Provides
87+
@IntoSet
88+
fun offlinePixelWorkerInjectorPlugin(
89+
offlinePixelSender: OfflinePixelSender
90+
): WorkerInjectorPlugin = OfflinePixelWorkerInjectorPlugin(offlinePixelSender)
91+
}

0 commit comments

Comments
 (0)
0