1 /*
2  * Copyright (C) 2017 The Android Open Source Project
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 package com.android.wallpaper.module
17 
18 import android.app.WallpaperColors
19 import android.app.WallpaperManager
20 import android.content.Context
21 import android.content.Intent
22 import android.net.Uri
23 import android.os.Bundle
24 import androidx.activity.ComponentActivity
25 import androidx.fragment.app.Fragment
26 import androidx.lifecycle.LifecycleOwner
27 import com.android.customization.model.color.DefaultWallpaperColorResources
28 import com.android.customization.model.color.WallpaperColorResources
29 import com.android.wallpaper.config.BaseFlags
30 import com.android.wallpaper.effects.EffectsController
31 import com.android.wallpaper.model.CategoryProvider
32 import com.android.wallpaper.model.InlinePreviewIntentFactory
33 import com.android.wallpaper.model.LiveWallpaperInfo
34 import com.android.wallpaper.model.WallpaperInfo
35 import com.android.wallpaper.module.logging.UserEventLogger
36 import com.android.wallpaper.monitor.PerformanceMonitor
37 import com.android.wallpaper.network.Requester
38 import com.android.wallpaper.picker.CustomizationPickerActivity
39 import com.android.wallpaper.picker.ImagePreviewFragment
40 import com.android.wallpaper.picker.LivePreviewFragment
41 import com.android.wallpaper.picker.MyPhotosStarter
42 import com.android.wallpaper.picker.PreviewActivity
43 import com.android.wallpaper.picker.PreviewFragment
44 import com.android.wallpaper.picker.ViewOnlyPreviewActivity
45 import com.android.wallpaper.picker.category.wrapper.WallpaperCategoryWrapper
46 import com.android.wallpaper.picker.customization.data.content.WallpaperClient
47 import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository
48 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
49 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperSnapshotRestorer
50 import com.android.wallpaper.picker.di.modules.MainDispatcher
51 import com.android.wallpaper.picker.individual.IndividualPickerFragment2
52 import com.android.wallpaper.picker.undo.data.repository.UndoRepository
53 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
54 import com.android.wallpaper.system.UiModeManagerWrapper
55 import com.android.wallpaper.util.DisplayUtils
56 import dagger.Lazy
57 import javax.inject.Inject
58 import javax.inject.Singleton
59 import kotlinx.coroutines.CoroutineScope
60 
61 @Singleton
62 open class WallpaperPicker2Injector
63 @Inject
64 constructor(
65     @MainDispatcher private val mainScope: CoroutineScope,
66     private val displayUtils: Lazy<DisplayUtils>,
67     private val requester: Lazy<Requester>,
68     private val networkStatusNotifier: Lazy<NetworkStatusNotifier>,
69     private val partnerProvider: Lazy<PartnerProvider>,
70     private val uiModeManager: Lazy<UiModeManagerWrapper>,
71     private val userEventLogger: Lazy<UserEventLogger>,
72     private val injectedWallpaperClient: Lazy<WallpaperClient>,
73     private val injectedWallpaperInteractor: Lazy<WallpaperInteractor>,
74     private val prefs: Lazy<WallpaperPreferences>,
75     private val wallpaperColorsRepository: Lazy<WallpaperColorsRepository>,
76     private val defaultWallpaperCategoryWrapper: Lazy<WallpaperCategoryWrapper>,
77     private val packageNotifier: Lazy<PackageStatusNotifier>,
78 ) : Injector {
79     private var alarmManagerWrapper: AlarmManagerWrapper? = null
80     private var bitmapCropper: BitmapCropper? = null
81     private var categoryProvider: CategoryProvider? = null
82     private var currentWallpaperFactory: CurrentWallpaperInfoFactory? = null
83     private var customizationSections: CustomizationSections? = null
84     private var drawableLayerResolver: DrawableLayerResolver? = null
85     private var exploreIntentChecker: ExploreIntentChecker? = null
86     private var liveWallpaperInfoFactory: LiveWallpaperInfoFactory? = null
87     private var performanceMonitor: PerformanceMonitor? = null
88     private var systemFeatureChecker: SystemFeatureChecker? = null
89     private var wallpaperPersister: WallpaperPersister? = null
90     private var wallpaperRefresher: WallpaperRefresher? = null
91     private var wallpaperStatusChecker: WallpaperStatusChecker? = null
92     private var flags: BaseFlags? = null
93     private var undoInteractor: UndoInteractor? = null
94     private var wallpaperInteractor: WallpaperInteractor? = null
95     private var wallpaperClient: WallpaperClient? = null
96     private var wallpaperSnapshotRestorer: WallpaperSnapshotRestorer? = null
97 
98     private var previewActivityIntentFactory: InlinePreviewIntentFactory? = null
99     private var viewOnlyPreviewActivityIntentFactory: InlinePreviewIntentFactory? = null
100 
getApplicationCoroutineScopenull101     override fun getApplicationCoroutineScope(): CoroutineScope {
102         return mainScope
103     }
104 
getWallpaperCategoryWrappernull105     override fun getWallpaperCategoryWrapper(): WallpaperCategoryWrapper {
106         return defaultWallpaperCategoryWrapper.get()
107     }
108 
109     @Synchronized
getAlarmManagerWrappernull110     override fun getAlarmManagerWrapper(context: Context): AlarmManagerWrapper {
111         return alarmManagerWrapper
112             ?: DefaultAlarmManagerWrapper(context.applicationContext).also {
113                 alarmManagerWrapper = it
114             }
115     }
116 
117     @Synchronized
getBitmapCroppernull118     override fun getBitmapCropper(): BitmapCropper {
119         return bitmapCropper ?: DefaultBitmapCropper().also { bitmapCropper = it }
120     }
121 
getCategoryProvidernull122     override fun getCategoryProvider(context: Context): CategoryProvider {
123         return categoryProvider
124             ?: DefaultCategoryProvider(context.applicationContext).also { categoryProvider = it }
125     }
126 
127     @Synchronized
getCurrentWallpaperInfoFactorynull128     override fun getCurrentWallpaperInfoFactory(context: Context): CurrentWallpaperInfoFactory {
129         return currentWallpaperFactory
130             ?: DefaultCurrentWallpaperInfoFactory(
131                     getWallpaperRefresher(context.applicationContext),
132                     getLiveWallpaperInfoFactory(context.applicationContext),
133                 )
134                 .also { currentWallpaperFactory = it }
135     }
136 
getCustomizationSectionsnull137     override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections {
138         return customizationSections
139             ?: WallpaperPickerSections().also { customizationSections = it }
140     }
141 
getDeepLinkRedirectIntentnull142     override fun getDeepLinkRedirectIntent(context: Context, uri: Uri): Intent {
143         val intent = Intent()
144         intent.setClass(context, CustomizationPickerActivity::class.java)
145         intent.data = uri
146         intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
147         return intent
148     }
149 
getDisplayUtilsnull150     override fun getDisplayUtils(context: Context): DisplayUtils {
151         return displayUtils.get()
152     }
153 
getDownloadableIntentActionnull154     override fun getDownloadableIntentAction(): String? {
155         return null
156     }
157 
getDrawableLayerResolvernull158     override fun getDrawableLayerResolver(): DrawableLayerResolver {
159         return drawableLayerResolver
160             ?: DefaultDrawableLayerResolver().also { drawableLayerResolver = it }
161     }
162 
getEffectsControllernull163     override fun getEffectsController(context: Context): EffectsController? {
164         return null
165     }
166 
167     @Synchronized
getExploreIntentCheckernull168     override fun getExploreIntentChecker(context: Context): ExploreIntentChecker {
169         return exploreIntentChecker
170             ?: DefaultExploreIntentChecker(context.applicationContext).also {
171                 exploreIntentChecker = it
172             }
173     }
174 
getIndividualPickerFragmentnull175     override fun getIndividualPickerFragment(context: Context, collectionId: String): Fragment {
176         return IndividualPickerFragment2.newInstance(collectionId)
177     }
178 
getLiveWallpaperInfoFactorynull179     override fun getLiveWallpaperInfoFactory(context: Context): LiveWallpaperInfoFactory {
180         return liveWallpaperInfoFactory
181             ?: DefaultLiveWallpaperInfoFactory().also { liveWallpaperInfoFactory = it }
182     }
183 
184     @Synchronized
getNetworkStatusNotifiernull185     override fun getNetworkStatusNotifier(context: Context): NetworkStatusNotifier {
186         return networkStatusNotifier.get()
187     }
188 
189     @Synchronized
getPackageStatusNotifiernull190     override fun getPackageStatusNotifier(context: Context): PackageStatusNotifier {
191         return packageNotifier.get()
192     }
193 
194     @Synchronized
getPartnerProvidernull195     override fun getPartnerProvider(context: Context): PartnerProvider {
196         return partnerProvider.get()
197     }
198 
199     @Synchronized
getPerformanceMonitornull200     override fun getPerformanceMonitor(): PerformanceMonitor? {
201 
202         return performanceMonitor
203             ?: PerformanceMonitor {
204                     /** No Op */
205                 }
206                 .also { performanceMonitor = it }
207     }
208 
getPreviewFragmentnull209     override fun getPreviewFragment(
210         context: Context,
211         wallpaperInfo: WallpaperInfo,
212         viewAsHome: Boolean,
213         isAssetIdPresent: Boolean,
214         isNewTask: Boolean,
215     ): Fragment {
216         val isLiveWallpaper = wallpaperInfo is LiveWallpaperInfo
217         return (if (isLiveWallpaper) LivePreviewFragment() else ImagePreviewFragment()).apply {
218             arguments =
219                 Bundle().apply {
220                     putParcelable(PreviewFragment.ARG_WALLPAPER, wallpaperInfo)
221                     putBoolean(PreviewFragment.ARG_VIEW_AS_HOME, viewAsHome)
222                     putBoolean(PreviewFragment.ARG_IS_ASSET_ID_PRESENT, isAssetIdPresent)
223                     putBoolean(PreviewFragment.ARG_IS_NEW_TASK, isNewTask)
224                 }
225         }
226     }
227 
228     @Synchronized
getRequesternull229     override fun getRequester(context: Context): Requester {
230         return requester.get()
231     }
232 
233     @Synchronized
getSystemFeatureCheckernull234     override fun getSystemFeatureChecker(): SystemFeatureChecker {
235         return systemFeatureChecker
236             ?: DefaultSystemFeatureChecker().also { systemFeatureChecker = it }
237     }
238 
getUserEventLoggernull239     override fun getUserEventLogger(): UserEventLogger {
240         return userEventLogger.get()
241     }
242 
243     @Synchronized
getWallpaperPersisternull244     override fun getWallpaperPersister(context: Context): WallpaperPersister {
245         return wallpaperPersister
246             ?: DefaultWallpaperPersister(
247                     context.applicationContext,
248                     WallpaperManager.getInstance(context.applicationContext),
249                     getPreferences(context),
250                     WallpaperChangedNotifier.getInstance(),
251                     displayUtils.get(),
252                     getBitmapCropper(),
253                     getWallpaperStatusChecker(context),
254                     getCurrentWallpaperInfoFactory(context),
255                     getFlags().isRefactorSettingWallpaper(),
256                 )
257                 .also { wallpaperPersister = it }
258     }
259 
260     @Synchronized
getPreferencesnull261     override fun getPreferences(context: Context): WallpaperPreferences {
262         return prefs.get()
263     }
264 
265     @Synchronized
getWallpaperRefreshernull266     override fun getWallpaperRefresher(context: Context): WallpaperRefresher {
267         return wallpaperRefresher
268             ?: DefaultWallpaperRefresher(context.applicationContext).also {
269                 wallpaperRefresher = it
270             }
271     }
272 
getWallpaperStatusCheckernull273     override fun getWallpaperStatusChecker(context: Context): WallpaperStatusChecker {
274         return wallpaperStatusChecker
275             ?: DefaultWallpaperStatusChecker(
276                     wallpaperManager = WallpaperManager.getInstance(context.applicationContext)
277                 )
278                 .also { wallpaperStatusChecker = it }
279     }
280 
getFlagsnull281     override fun getFlags(): BaseFlags {
282         return flags ?: object : BaseFlags() {}.also { flags = it }
283     }
284 
getUndoInteractornull285     override fun getUndoInteractor(
286         context: Context,
287         lifecycleOwner: LifecycleOwner,
288     ): UndoInteractor {
289         return undoInteractor
290             ?: UndoInteractor(
291                     getApplicationCoroutineScope(),
292                     UndoRepository(),
293                     getSnapshotRestorers(context),
294                 )
295                 .also { undoInteractor = it }
296     }
297 
getWallpaperInteractornull298     override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
299         return injectedWallpaperInteractor.get()
300     }
301 
getWallpaperClientnull302     override fun getWallpaperClient(context: Context): WallpaperClient {
303         return injectedWallpaperClient.get()
304     }
305 
getWallpaperSnapshotRestorernull306     override fun getWallpaperSnapshotRestorer(context: Context): WallpaperSnapshotRestorer {
307         return wallpaperSnapshotRestorer
308             ?: WallpaperSnapshotRestorer(
309                     scope = getApplicationCoroutineScope(),
310                     interactor = getWallpaperInteractor(context),
311                 )
312                 .also { wallpaperSnapshotRestorer = it }
313     }
314 
getWallpaperColorsRepositorynull315     override fun getWallpaperColorsRepository(): WallpaperColorsRepository {
316         return wallpaperColorsRepository.get()
317     }
318 
getWallpaperColorResourcesnull319     override fun getWallpaperColorResources(
320         wallpaperColors: WallpaperColors,
321         context: Context,
322     ): WallpaperColorResources {
323         return DefaultWallpaperColorResources(wallpaperColors)
324     }
325 
getMyPhotosIntentProvidernull326     override fun getMyPhotosIntentProvider(): MyPhotosStarter.MyPhotosIntentProvider {
327         return object : MyPhotosStarter.MyPhotosIntentProvider {}
328     }
329 
isCurrentSelectedColorPresetnull330     override fun isCurrentSelectedColorPreset(context: Context): Boolean {
331         return false
332     }
333 
getPreviewActivityIntentFactorynull334     override fun getPreviewActivityIntentFactory(): InlinePreviewIntentFactory {
335         return previewActivityIntentFactory
336             ?: PreviewActivity.PreviewActivityIntentFactory().also {
337                 previewActivityIntentFactory = it
338             }
339     }
340 
getViewOnlyPreviewActivityIntentFactorynull341     override fun getViewOnlyPreviewActivityIntentFactory(): InlinePreviewIntentFactory {
342         return viewOnlyPreviewActivityIntentFactory
343             ?: ViewOnlyPreviewActivity.ViewOnlyPreviewActivityIntentFactory().also {
344                 viewOnlyPreviewActivityIntentFactory = it
345             }
346     }
347 
348     companion object {
349         /**
350          * When this injector is overridden, this is the minimal value that should be used by
351          * restorers returns in [getSnapshotRestorers].
352          */
353         @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = 0
354     }
355 }
356