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.systemui.shared.settings.data.repository.SecureSettingsRepository 30 import com.android.systemui.shared.settings.data.repository.SecureSettingsRepositoryImpl 31 import com.android.wallpaper.config.BaseFlags 32 import com.android.wallpaper.effects.EffectsController 33 import com.android.wallpaper.model.CategoryProvider 34 import com.android.wallpaper.model.InlinePreviewIntentFactory 35 import com.android.wallpaper.model.LiveWallpaperInfo 36 import com.android.wallpaper.model.WallpaperInfo 37 import com.android.wallpaper.module.logging.UserEventLogger 38 import com.android.wallpaper.monitor.PerformanceMonitor 39 import com.android.wallpaper.network.Requester 40 import com.android.wallpaper.picker.CustomizationPickerActivity 41 import com.android.wallpaper.picker.ImagePreviewFragment 42 import com.android.wallpaper.picker.LivePreviewFragment 43 import com.android.wallpaper.picker.MyPhotosStarter 44 import com.android.wallpaper.picker.PreviewActivity 45 import com.android.wallpaper.picker.PreviewFragment 46 import com.android.wallpaper.picker.ViewOnlyPreviewActivity 47 import com.android.wallpaper.picker.customization.data.content.WallpaperClient 48 import com.android.wallpaper.picker.customization.data.content.WallpaperClientImpl 49 import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository 50 import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository 51 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor 52 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperSnapshotRestorer 53 import com.android.wallpaper.picker.di.modules.BackgroundDispatcher 54 import com.android.wallpaper.picker.di.modules.MainDispatcher 55 import com.android.wallpaper.picker.individual.IndividualPickerFragment 56 import com.android.wallpaper.picker.undo.data.repository.UndoRepository 57 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor 58 import com.android.wallpaper.system.UiModeManagerWrapper 59 import com.android.wallpaper.util.DisplayUtils 60 import dagger.Lazy 61 import javax.inject.Inject 62 import javax.inject.Singleton 63 import kotlinx.coroutines.CoroutineDispatcher 64 import kotlinx.coroutines.CoroutineScope 65 66 @Singleton 67 open class WallpaperPicker2Injector 68 @Inject 69 constructor( 70 @MainDispatcher private val mainScope: CoroutineScope, 71 @BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher, 72 ) : Injector { 73 private var alarmManagerWrapper: AlarmManagerWrapper? = null 74 private var bitmapCropper: BitmapCropper? = null 75 private var categoryProvider: CategoryProvider? = null 76 private var currentWallpaperFactory: CurrentWallpaperInfoFactory? = null 77 private var customizationSections: CustomizationSections? = null 78 private var drawableLayerResolver: DrawableLayerResolver? = null 79 private var exploreIntentChecker: ExploreIntentChecker? = null 80 private var liveWallpaperInfoFactory: LiveWallpaperInfoFactory? = null 81 private var packageStatusNotifier: PackageStatusNotifier? = null 82 private var performanceMonitor: PerformanceMonitor? = null 83 private var systemFeatureChecker: SystemFeatureChecker? = null 84 private var wallpaperPersister: WallpaperPersister? = null 85 private var wallpaperRefresher: WallpaperRefresher? = null 86 private var wallpaperStatusChecker: WallpaperStatusChecker? = null 87 private var flags: BaseFlags? = null 88 private var undoInteractor: UndoInteractor? = null 89 private var wallpaperInteractor: WallpaperInteractor? = null 90 private var wallpaperClient: WallpaperClient? = null 91 private var wallpaperSnapshotRestorer: WallpaperSnapshotRestorer? = null 92 private var secureSettingsRepository: SecureSettingsRepository? = null 93 private var wallpaperColorsRepository: WallpaperColorsRepository? = null 94 private var previewActivityIntentFactory: InlinePreviewIntentFactory? = null 95 private var viewOnlyPreviewActivityIntentFactory: InlinePreviewIntentFactory? = null 96 97 // Injected objects, sorted by alphabetical order on the type of object 98 @Inject lateinit var displayUtils: Lazy<DisplayUtils> 99 @Inject lateinit var requester: Lazy<Requester> 100 @Inject lateinit var networkStatusNotifier: Lazy<NetworkStatusNotifier> 101 @Inject lateinit var partnerProvider: Lazy<PartnerProvider> 102 @Inject lateinit var uiModeManager: Lazy<UiModeManagerWrapper> 103 @Inject lateinit var userEventLogger: Lazy<UserEventLogger> 104 @Inject lateinit var injectedWallpaperClient: Lazy<WallpaperClient> 105 @Inject lateinit var injectedWallpaperInteractor: Lazy<WallpaperInteractor> 106 @Inject lateinit var prefs: Lazy<WallpaperPreferences> 107 getApplicationCoroutineScopenull108 override fun getApplicationCoroutineScope(): CoroutineScope { 109 return mainScope 110 } 111 112 @Synchronized getAlarmManagerWrappernull113 override fun getAlarmManagerWrapper(context: Context): AlarmManagerWrapper { 114 return alarmManagerWrapper 115 ?: DefaultAlarmManagerWrapper(context.applicationContext).also { 116 alarmManagerWrapper = it 117 } 118 } 119 120 @Synchronized getBitmapCroppernull121 override fun getBitmapCropper(): BitmapCropper { 122 return bitmapCropper ?: DefaultBitmapCropper().also { bitmapCropper = it } 123 } 124 getCategoryProvidernull125 override fun getCategoryProvider(context: Context): CategoryProvider { 126 return categoryProvider 127 ?: DefaultCategoryProvider(context.applicationContext).also { categoryProvider = it } 128 } 129 130 @Synchronized getCurrentWallpaperInfoFactorynull131 override fun getCurrentWallpaperInfoFactory(context: Context): CurrentWallpaperInfoFactory { 132 return currentWallpaperFactory 133 ?: DefaultCurrentWallpaperInfoFactory( 134 getWallpaperRefresher(context.applicationContext), 135 getLiveWallpaperInfoFactory(context.applicationContext), 136 ) 137 .also { currentWallpaperFactory = it } 138 } 139 getCustomizationSectionsnull140 override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections { 141 return customizationSections 142 ?: WallpaperPickerSections().also { customizationSections = it } 143 } 144 getDeepLinkRedirectIntentnull145 override fun getDeepLinkRedirectIntent(context: Context, uri: Uri): Intent { 146 val intent = Intent() 147 intent.setClass(context, CustomizationPickerActivity::class.java) 148 intent.data = uri 149 intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK 150 return intent 151 } 152 getDisplayUtilsnull153 override fun getDisplayUtils(context: Context): DisplayUtils { 154 return displayUtils.get() 155 } 156 getDownloadableIntentActionnull157 override fun getDownloadableIntentAction(): String? { 158 return null 159 } 160 getDrawableLayerResolvernull161 override fun getDrawableLayerResolver(): DrawableLayerResolver { 162 return drawableLayerResolver 163 ?: DefaultDrawableLayerResolver().also { drawableLayerResolver = it } 164 } 165 getEffectsControllernull166 override fun getEffectsController( 167 context: Context, 168 ): EffectsController? { 169 return null 170 } 171 172 @Synchronized getExploreIntentCheckernull173 override fun getExploreIntentChecker(context: Context): ExploreIntentChecker { 174 return exploreIntentChecker 175 ?: DefaultExploreIntentChecker(context.applicationContext).also { 176 exploreIntentChecker = it 177 } 178 } 179 getIndividualPickerFragmentnull180 override fun getIndividualPickerFragment(context: Context, collectionId: String): Fragment { 181 return IndividualPickerFragment.newInstance(collectionId) 182 } 183 getLiveWallpaperInfoFactorynull184 override fun getLiveWallpaperInfoFactory(context: Context): LiveWallpaperInfoFactory { 185 return liveWallpaperInfoFactory 186 ?: DefaultLiveWallpaperInfoFactory().also { liveWallpaperInfoFactory = it } 187 } 188 189 @Synchronized getNetworkStatusNotifiernull190 override fun getNetworkStatusNotifier(context: Context): NetworkStatusNotifier { 191 return networkStatusNotifier.get() 192 } 193 194 @Synchronized getPackageStatusNotifiernull195 override fun getPackageStatusNotifier(context: Context): PackageStatusNotifier { 196 return packageStatusNotifier 197 ?: DefaultPackageStatusNotifier(context.applicationContext).also { 198 packageStatusNotifier = it 199 } 200 } 201 202 @Synchronized getPartnerProvidernull203 override fun getPartnerProvider(context: Context): PartnerProvider { 204 return partnerProvider.get() 205 } 206 207 @Synchronized getPerformanceMonitornull208 override fun getPerformanceMonitor(): PerformanceMonitor? { 209 210 return performanceMonitor 211 ?: PerformanceMonitor { 212 /** No Op */ 213 } 214 .also { performanceMonitor = it } 215 } 216 getPreviewFragmentnull217 override fun getPreviewFragment( 218 context: Context, 219 wallpaperInfo: WallpaperInfo, 220 viewAsHome: Boolean, 221 isAssetIdPresent: Boolean, 222 isNewTask: Boolean, 223 ): Fragment { 224 val isLiveWallpaper = wallpaperInfo is LiveWallpaperInfo 225 return (if (isLiveWallpaper) LivePreviewFragment() else ImagePreviewFragment()).apply { 226 arguments = 227 Bundle().apply { 228 putParcelable(PreviewFragment.ARG_WALLPAPER, wallpaperInfo) 229 putBoolean(PreviewFragment.ARG_VIEW_AS_HOME, viewAsHome) 230 putBoolean(PreviewFragment.ARG_IS_ASSET_ID_PRESENT, isAssetIdPresent) 231 putBoolean(PreviewFragment.ARG_IS_NEW_TASK, isNewTask) 232 } 233 } 234 } 235 236 @Synchronized getRequesternull237 override fun getRequester(context: Context): Requester { 238 return requester.get() 239 } 240 241 @Synchronized getSystemFeatureCheckernull242 override fun getSystemFeatureChecker(): SystemFeatureChecker { 243 return systemFeatureChecker 244 ?: DefaultSystemFeatureChecker().also { systemFeatureChecker = it } 245 } 246 getUserEventLoggernull247 override fun getUserEventLogger(): UserEventLogger { 248 return userEventLogger.get() 249 } 250 251 @Synchronized getWallpaperPersisternull252 override fun getWallpaperPersister(context: Context): WallpaperPersister { 253 return wallpaperPersister 254 ?: DefaultWallpaperPersister( 255 context.applicationContext, 256 WallpaperManager.getInstance(context.applicationContext), 257 getPreferences(context), 258 WallpaperChangedNotifier.getInstance(), 259 displayUtils.get(), 260 getBitmapCropper(), 261 getWallpaperStatusChecker(context), 262 getCurrentWallpaperInfoFactory(context), 263 getFlags().isRefactorSettingWallpaper(), 264 ) 265 .also { wallpaperPersister = it } 266 } 267 268 @Synchronized getPreferencesnull269 override fun getPreferences(context: Context): WallpaperPreferences { 270 return prefs.get() 271 } 272 273 @Synchronized getWallpaperRefreshernull274 override fun getWallpaperRefresher(context: Context): WallpaperRefresher { 275 return wallpaperRefresher 276 ?: DefaultWallpaperRefresher(context.applicationContext).also { 277 wallpaperRefresher = it 278 } 279 } 280 getWallpaperStatusCheckernull281 override fun getWallpaperStatusChecker(context: Context): WallpaperStatusChecker { 282 return wallpaperStatusChecker 283 ?: DefaultWallpaperStatusChecker( 284 wallpaperManager = WallpaperManager.getInstance(context.applicationContext), 285 ) 286 .also { wallpaperStatusChecker = it } 287 } 288 getFlagsnull289 override fun getFlags(): BaseFlags { 290 return flags ?: object : BaseFlags() {}.also { flags = it } 291 } 292 getUndoInteractornull293 override fun getUndoInteractor( 294 context: Context, 295 lifecycleOwner: LifecycleOwner 296 ): UndoInteractor { 297 return undoInteractor 298 ?: UndoInteractor( 299 getApplicationCoroutineScope(), 300 UndoRepository(), 301 getSnapshotRestorers(context), 302 ) 303 .also { undoInteractor = it } 304 } 305 getWallpaperInteractornull306 override fun getWallpaperInteractor(context: Context): WallpaperInteractor { 307 if (getFlags().isMultiCropEnabled()) { 308 return injectedWallpaperInteractor.get() 309 } 310 311 val appContext = context.applicationContext 312 return wallpaperInteractor 313 ?: WallpaperInteractor( 314 repository = 315 WallpaperRepository( 316 scope = getApplicationCoroutineScope(), 317 client = getWallpaperClient(context), 318 wallpaperPreferences = getPreferences(context = appContext), 319 backgroundDispatcher = bgDispatcher, 320 ), 321 ) 322 .also { wallpaperInteractor = it } 323 } 324 getWallpaperClientnull325 override fun getWallpaperClient(context: Context): WallpaperClient { 326 if (getFlags().isMultiCropEnabled()) { 327 return injectedWallpaperClient.get() 328 } 329 330 val appContext = context.applicationContext 331 return wallpaperClient 332 ?: WallpaperClientImpl( 333 context = appContext, 334 wallpaperManager = WallpaperManager.getInstance(appContext), 335 wallpaperPreferences = getPreferences(appContext), 336 ) 337 .also { wallpaperClient = it } 338 } 339 getWallpaperSnapshotRestorernull340 override fun getWallpaperSnapshotRestorer(context: Context): WallpaperSnapshotRestorer { 341 return wallpaperSnapshotRestorer 342 ?: WallpaperSnapshotRestorer( 343 scope = getApplicationCoroutineScope(), 344 interactor = getWallpaperInteractor(context), 345 ) 346 .also { wallpaperSnapshotRestorer = it } 347 } 348 getSecureSettingsRepositorynull349 protected fun getSecureSettingsRepository(context: Context): SecureSettingsRepository { 350 return secureSettingsRepository 351 ?: SecureSettingsRepositoryImpl( 352 contentResolver = context.applicationContext.contentResolver, 353 backgroundDispatcher = bgDispatcher, 354 ) 355 .also { secureSettingsRepository = it } 356 } 357 getWallpaperColorsRepositorynull358 override fun getWallpaperColorsRepository(): WallpaperColorsRepository { 359 return wallpaperColorsRepository 360 ?: WallpaperColorsRepository().also { wallpaperColorsRepository = it } 361 } 362 getWallpaperColorResourcesnull363 override fun getWallpaperColorResources( 364 wallpaperColors: WallpaperColors, 365 context: Context 366 ): WallpaperColorResources { 367 return DefaultWallpaperColorResources(wallpaperColors) 368 } 369 getMyPhotosIntentProvidernull370 override fun getMyPhotosIntentProvider(): MyPhotosStarter.MyPhotosIntentProvider { 371 return object : MyPhotosStarter.MyPhotosIntentProvider {} 372 } 373 isCurrentSelectedColorPresetnull374 override fun isCurrentSelectedColorPreset(context: Context): Boolean { 375 return false 376 } 377 getPreviewActivityIntentFactorynull378 override fun getPreviewActivityIntentFactory(): InlinePreviewIntentFactory { 379 return previewActivityIntentFactory 380 ?: PreviewActivity.PreviewActivityIntentFactory().also { 381 previewActivityIntentFactory = it 382 } 383 } 384 getViewOnlyPreviewActivityIntentFactorynull385 override fun getViewOnlyPreviewActivityIntentFactory(): InlinePreviewIntentFactory { 386 return viewOnlyPreviewActivityIntentFactory 387 ?: ViewOnlyPreviewActivity.ViewOnlyPreviewActivityIntentFactory().also { 388 viewOnlyPreviewActivityIntentFactory = it 389 } 390 } 391 392 companion object { 393 /** 394 * When this injector is overridden, this is the minimal value that should be used by 395 * restorers returns in [getSnapshotRestorers]. 396 */ 397 @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = 0 398 } 399 } 400