blob: 3dbbca08186e4aded3706b5e99e7668e10aff4f9 [file] [log] [blame]
/*
* Copyright (C) 2019 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
*
* http://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.android.customization.module
import android.app.UiModeManager
import android.app.WallpaperManager
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import com.android.customization.model.color.ColorCustomizationManager
import com.android.customization.model.color.ColorOptionsProvider
import com.android.customization.model.grid.GridOptionsManager
import com.android.customization.model.grid.data.repository.GridRepositoryImpl
import com.android.customization.model.grid.domain.interactor.GridInteractor
import com.android.customization.model.grid.domain.interactor.GridSnapshotRestorer
import com.android.customization.model.grid.ui.viewmodel.GridScreenViewModel
import com.android.customization.model.mode.DarkModeSnapshotRestorer
import com.android.customization.model.theme.OverlayManagerCompat
import com.android.customization.model.theme.ThemeBundleProvider
import com.android.customization.model.theme.ThemeManager
import com.android.customization.model.themedicon.ThemedIconSwitchProvider
import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
import com.android.customization.model.themedicon.domain.interactor.ThemedIconSnapshotRestorer
import com.android.customization.picker.clock.data.repository.ClockPickerRepositoryImpl
import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
import com.android.customization.picker.clock.domain.interactor.ClockPickerSnapshotRestorer
import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
import com.android.customization.picker.clock.utils.ClockDescriptionUtils
import com.android.customization.picker.clock.utils.ThemePickerClockDescriptionUtils
import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
import com.android.customization.picker.notifications.data.repository.NotificationsRepository
import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
import com.android.customization.picker.notifications.domain.interactor.NotificationsSnapshotRestorer
import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
import com.android.wallpaper.dispatchers.BackgroundDispatcher
import com.android.wallpaper.dispatchers.MainDispatcher
import com.android.wallpaper.model.LiveWallpaperInfo
import com.android.wallpaper.model.WallpaperColorsViewModel
import com.android.wallpaper.model.WallpaperInfo
import com.android.wallpaper.module.CustomizationSections
import com.android.wallpaper.module.FragmentFactory
import com.android.wallpaper.module.UserEventLogger
import com.android.wallpaper.module.WallpaperPicker2Injector
import com.android.wallpaper.module.WallpaperPreferences
import com.android.wallpaper.picker.CustomizationPickerActivity
import com.android.wallpaper.picker.ImagePreviewFragment
import com.android.wallpaper.picker.LivePreviewFragment
import com.android.wallpaper.picker.PreviewFragment
import com.android.wallpaper.picker.customization.data.content.WallpaperClientImpl
import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository
import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
import com.android.wallpaper.util.ScreenSizeCalculator
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@Singleton
open class ThemePickerInjector
@Inject
internal constructor(
@MainDispatcher private val mainScope: CoroutineScope,
@MainDispatcher private val mainDispatcher: CoroutineDispatcher,
@BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
) : WallpaperPicker2Injector(mainScope, bgDispatcher), CustomizationInjector {
private var customizationSections: CustomizationSections? = null
private var userEventLogger: UserEventLogger? = null
private var prefs: WallpaperPreferences? = null
private var wallpaperInteractor: WallpaperInteractor? = null
private var keyguardQuickAffordancePickerInteractor: KeyguardQuickAffordancePickerInteractor? =
null
private var keyguardQuickAffordancePickerViewModelFactory:
KeyguardQuickAffordancePickerViewModel.Factory? =
null
private var customizationProviderClient: CustomizationProviderClient? = null
private var fragmentFactory: FragmentFactory? = null
private var keyguardQuickAffordanceSnapshotRestorer: KeyguardQuickAffordanceSnapshotRestorer? =
null
private var notificationsSnapshotRestorer: NotificationsSnapshotRestorer? = null
private var clockPickerInteractor: ClockPickerInteractor? = null
private var clockSectionViewModel: ClockSectionViewModel? = null
private var clockCarouselViewModelFactory: ClockCarouselViewModel.Factory? = null
private var clockViewFactories: MutableMap<Int, ClockViewFactory> = HashMap()
private var clockPickerSnapshotRestorer: ClockPickerSnapshotRestorer? = null
private var notificationsInteractor: NotificationsInteractor? = null
private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null
private var colorPickerInteractor: ColorPickerInteractor? = null
private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null
private var colorPickerSnapshotRestorer: ColorPickerSnapshotRestorer? = null
private var colorCustomizationManager: ColorCustomizationManager? = null
private var darkModeSnapshotRestorer: DarkModeSnapshotRestorer? = null
private var themedIconSnapshotRestorer: ThemedIconSnapshotRestorer? = null
private var themedIconInteractor: ThemedIconInteractor? = null
private var clockSettingsViewModelFactory: ClockSettingsViewModel.Factory? = null
private var clockDescriptionUtils: ClockDescriptionUtils? = null
private var gridInteractor: GridInteractor? = null
private var gridSnapshotRestorer: GridSnapshotRestorer? = null
private var gridScreenViewModelFactory: GridScreenViewModel.Factory? = null
private var clockRegistryProvider: ClockRegistryProvider? = null
override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections {
return customizationSections
?: DefaultCustomizationSections(
getColorPickerViewModelFactory(
context = activity,
wallpaperColorsViewModel = getWallpaperColorsViewModel(),
),
getKeyguardQuickAffordancePickerInteractor(activity),
getKeyguardQuickAffordancePickerViewModelFactory(activity),
NotificationSectionViewModel.Factory(
interactor = getNotificationsInteractor(activity),
),
getFlags(),
getClockCarouselViewModelFactory(
getClockPickerInteractor(activity.applicationContext),
),
getClockViewFactory(activity),
getDarkModeSnapshotRestorer(activity),
getThemedIconSnapshotRestorer(activity),
getThemedIconInteractor(),
getColorPickerInteractor(activity, getWallpaperColorsViewModel()),
)
.also { customizationSections = it }
}
override fun getDeepLinkRedirectIntent(context: Context, uri: Uri): Intent {
val intent = Intent()
intent.setClass(context, CustomizationPickerActivity::class.java)
intent.data = uri
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
return intent
}
override fun getDownloadableIntentAction(): String? {
return null
}
override fun getPreviewFragment(
context: Context,
wallpaperInfo: WallpaperInfo,
mode: Int,
viewAsHome: Boolean,
viewFullScreen: Boolean,
testingModeEnabled: Boolean
): Fragment {
return if (wallpaperInfo is LiveWallpaperInfo) LivePreviewFragment()
else
ImagePreviewFragment().apply {
arguments =
Bundle().apply {
putParcelable(PreviewFragment.ARG_WALLPAPER, wallpaperInfo)
putInt(PreviewFragment.ARG_PREVIEW_MODE, mode)
putBoolean(PreviewFragment.ARG_VIEW_AS_HOME, viewAsHome)
putBoolean(PreviewFragment.ARG_FULL_SCREEN, viewFullScreen)
putBoolean(PreviewFragment.ARG_TESTING_MODE_ENABLED, testingModeEnabled)
}
}
}
@Synchronized
override fun getUserEventLogger(context: Context): ThemesUserEventLogger {
return userEventLogger as? ThemesUserEventLogger
?: StatsLogUserEventLogger(
getPreferences(context.applicationContext),
getWallpaperStatusChecker(context.applicationContext),
)
.also { userEventLogger = it }
}
@Synchronized
override fun getPreferences(context: Context): WallpaperPreferences {
return prefs
?: DefaultCustomizationPreferences(context.applicationContext).also { prefs = it }
}
override fun getFragmentFactory(): FragmentFactory? {
return fragmentFactory ?: ThemePickerFragmentFactory().also { fragmentFactory }
}
override fun getSnapshotRestorers(
context: Context,
): Map<Int, SnapshotRestorer> {
return super<WallpaperPicker2Injector>.getSnapshotRestorers(context).toMutableMap().apply {
this[KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER] =
getKeyguardQuickAffordanceSnapshotRestorer(context)
// TODO(b/285047815): Enable after adding wallpaper id for default static wallpaper
if (getFlags().isWallpaperRestorerEnabled()) {
this[KEY_WALLPAPER_SNAPSHOT_RESTORER] = getWallpaperSnapshotRestorer(context)
}
this[KEY_NOTIFICATIONS_SNAPSHOT_RESTORER] = getNotificationsSnapshotRestorer(context)
this[KEY_DARK_MODE_SNAPSHOT_RESTORER] = getDarkModeSnapshotRestorer(context)
this[KEY_THEMED_ICON_SNAPSHOT_RESTORER] = getThemedIconSnapshotRestorer(context)
this[KEY_APP_GRID_SNAPSHOT_RESTORER] = getGridSnapshotRestorer(context)
this[KEY_COLOR_PICKER_SNAPSHOT_RESTORER] =
getColorPickerSnapshotRestorer(context, getWallpaperColorsViewModel())
this[KEY_CLOCKS_SNAPSHOT_RESTORER] = getClockPickerSnapshotRestorer(context)
}
}
override fun getCustomizationPreferences(context: Context): CustomizationPreferences {
return getPreferences(context) as CustomizationPreferences
}
override fun getThemeManager(
provider: ThemeBundleProvider,
activity: FragmentActivity,
overlayManagerCompat: OverlayManagerCompat,
logger: ThemesUserEventLogger
): ThemeManager {
return ThemeManager(provider, activity, overlayManagerCompat, logger)
}
override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
val appContext = context.applicationContext
return wallpaperInteractor
?: WallpaperInteractor(
repository =
WallpaperRepository(
scope = getApplicationCoroutineScope(),
client =
WallpaperClientImpl(
context = appContext,
infoFactory = getCurrentWallpaperInfoFactory(appContext),
wallpaperManager = WallpaperManager.getInstance(appContext)
),
wallpaperPreferences = getPreferences(context = appContext),
backgroundDispatcher = bgDispatcher,
),
shouldHandleReload = {
TextUtils.equals(
getColorCustomizationManager(appContext).currentColorSource,
ColorOptionsProvider.COLOR_SOURCE_PRESET
)
}
)
.also { wallpaperInteractor = it }
}
override fun getKeyguardQuickAffordancePickerInteractor(
context: Context
): KeyguardQuickAffordancePickerInteractor {
return keyguardQuickAffordancePickerInteractor
?: getKeyguardQuickAffordancePickerInteractorImpl(context).also {
keyguardQuickAffordancePickerInteractor = it
}
}
fun getKeyguardQuickAffordancePickerViewModelFactory(
context: Context
): KeyguardQuickAffordancePickerViewModel.Factory {
return keyguardQuickAffordancePickerViewModelFactory
?: KeyguardQuickAffordancePickerViewModel.Factory(
context.applicationContext,
getKeyguardQuickAffordancePickerInteractor(context),
getWallpaperInteractor(context),
getCurrentWallpaperInfoFactory(context),
)
.also { keyguardQuickAffordancePickerViewModelFactory = it }
}
private fun getKeyguardQuickAffordancePickerInteractorImpl(
context: Context
): KeyguardQuickAffordancePickerInteractor {
val client = getKeyguardQuickAffordancePickerProviderClient(context)
val appContext = context.applicationContext
return KeyguardQuickAffordancePickerInteractor(
KeyguardQuickAffordancePickerRepository(client, bgDispatcher),
client
) {
getKeyguardQuickAffordanceSnapshotRestorer(appContext)
}
}
private fun getKeyguardQuickAffordancePickerProviderClient(
context: Context
): CustomizationProviderClient {
return customizationProviderClient
?: CustomizationProviderClientImpl(context.applicationContext, bgDispatcher).also {
customizationProviderClient = it
}
}
private fun getKeyguardQuickAffordanceSnapshotRestorer(
context: Context
): KeyguardQuickAffordanceSnapshotRestorer {
return keyguardQuickAffordanceSnapshotRestorer
?: KeyguardQuickAffordanceSnapshotRestorer(
getKeyguardQuickAffordancePickerInteractor(context),
getKeyguardQuickAffordancePickerProviderClient(context)
)
.also { keyguardQuickAffordanceSnapshotRestorer = it }
}
fun getNotificationSectionViewModelFactory(
context: Context,
): NotificationSectionViewModel.Factory {
return notificationSectionViewModelFactory
?: NotificationSectionViewModel.Factory(
interactor = getNotificationsInteractor(context),
)
.also { notificationSectionViewModelFactory = it }
}
private fun getNotificationsInteractor(
context: Context,
): NotificationsInteractor {
val appContext = context.applicationContext
return notificationsInteractor
?: NotificationsInteractor(
repository =
NotificationsRepository(
scope = getApplicationCoroutineScope(),
backgroundDispatcher = bgDispatcher,
secureSettingsRepository = getSecureSettingsRepository(context),
),
snapshotRestorer = { getNotificationsSnapshotRestorer(appContext) },
)
.also { notificationsInteractor = it }
}
private fun getNotificationsSnapshotRestorer(context: Context): NotificationsSnapshotRestorer {
return notificationsSnapshotRestorer
?: NotificationsSnapshotRestorer(
interactor =
getNotificationsInteractor(
context = context,
),
)
.also { notificationsSnapshotRestorer = it }
}
override fun getClockRegistry(context: Context): ClockRegistry {
return (clockRegistryProvider
?: ClockRegistryProvider(
context = context.applicationContext,
coroutineScope = getApplicationCoroutineScope(),
mainDispatcher = mainDispatcher,
backgroundDispatcher = bgDispatcher,
)
.also { clockRegistryProvider = it })
.get()
}
override fun getClockPickerInteractor(
context: Context,
): ClockPickerInteractor {
val appContext = context.applicationContext
return clockPickerInteractor
?: ClockPickerInteractor(
repository =
ClockPickerRepositoryImpl(
secureSettingsRepository = getSecureSettingsRepository(appContext),
registry = getClockRegistry(appContext),
scope = getApplicationCoroutineScope(),
mainDispatcher = mainDispatcher,
),
snapshotRestorer = { getClockPickerSnapshotRestorer(appContext) },
)
.also { clockPickerInteractor = it }
}
override fun getClockSectionViewModel(
context: Context,
): ClockSectionViewModel {
return clockSectionViewModel
?: ClockSectionViewModel(
context.applicationContext,
getClockPickerInteractor(context.applicationContext)
)
.also { clockSectionViewModel = it }
}
override fun getClockCarouselViewModelFactory(
interactor: ClockPickerInteractor,
): ClockCarouselViewModel.Factory {
return clockCarouselViewModelFactory
?: ClockCarouselViewModel.Factory(interactor, bgDispatcher).also {
clockCarouselViewModelFactory = it
}
}
override fun getClockViewFactory(activity: ComponentActivity): ClockViewFactory {
val activityHashCode = activity.hashCode()
return clockViewFactories[activityHashCode]
?: ClockViewFactory(
activity.applicationContext,
ScreenSizeCalculator.getInstance()
.getScreenSize(activity.windowManager.defaultDisplay),
WallpaperManager.getInstance(activity.applicationContext),
getClockRegistry(activity.applicationContext),
)
.also {
clockViewFactories[activityHashCode] = it
activity.lifecycle.addObserver(
object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
clockViewFactories[activityHashCode]?.onDestroy()
clockViewFactories.remove(activityHashCode)
}
}
)
}
}
private fun getClockPickerSnapshotRestorer(
context: Context,
): ClockPickerSnapshotRestorer {
return clockPickerSnapshotRestorer
?: ClockPickerSnapshotRestorer(getClockPickerInteractor(context)).also {
clockPickerSnapshotRestorer = it
}
}
override fun getColorPickerInteractor(
context: Context,
wallpaperColorsViewModel: WallpaperColorsViewModel,
): ColorPickerInteractor {
val appContext = context.applicationContext
return colorPickerInteractor
?: ColorPickerInteractor(
repository =
ColorPickerRepositoryImpl(
wallpaperColorsViewModel,
getColorCustomizationManager(appContext)
),
snapshotRestorer = {
getColorPickerSnapshotRestorer(appContext, wallpaperColorsViewModel)
}
)
.also { colorPickerInteractor = it }
}
override fun getColorPickerViewModelFactory(
context: Context,
wallpaperColorsViewModel: WallpaperColorsViewModel,
): ColorPickerViewModel.Factory {
return colorPickerViewModelFactory
?: ColorPickerViewModel.Factory(
context.applicationContext,
getColorPickerInteractor(context, wallpaperColorsViewModel),
)
.also { colorPickerViewModelFactory = it }
}
private fun getColorPickerSnapshotRestorer(
context: Context,
wallpaperColorsViewModel: WallpaperColorsViewModel,
): ColorPickerSnapshotRestorer {
return colorPickerSnapshotRestorer
?: ColorPickerSnapshotRestorer(
getColorPickerInteractor(context, wallpaperColorsViewModel)
)
.also { colorPickerSnapshotRestorer = it }
}
private fun getColorCustomizationManager(context: Context): ColorCustomizationManager {
return colorCustomizationManager
?: ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context)).also {
colorCustomizationManager = it
}
}
fun getDarkModeSnapshotRestorer(
context: Context,
): DarkModeSnapshotRestorer {
val appContext = context.applicationContext
return darkModeSnapshotRestorer
?: DarkModeSnapshotRestorer(
context = appContext,
manager = appContext.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager,
backgroundDispatcher = bgDispatcher,
)
.also { darkModeSnapshotRestorer = it }
}
protected fun getThemedIconSnapshotRestorer(
context: Context,
): ThemedIconSnapshotRestorer {
val optionProvider = ThemedIconSwitchProvider.getInstance(context)
return themedIconSnapshotRestorer
?: ThemedIconSnapshotRestorer(
isActivated = { optionProvider.isThemedIconEnabled },
setActivated = { isActivated ->
optionProvider.isThemedIconEnabled = isActivated
},
interactor = getThemedIconInteractor(),
)
.also { themedIconSnapshotRestorer = it }
}
protected fun getThemedIconInteractor(): ThemedIconInteractor {
return themedIconInteractor
?: ThemedIconInteractor(
repository = ThemeIconRepository(),
)
.also { themedIconInteractor = it }
}
override fun getClockSettingsViewModelFactory(
context: Context,
wallpaperColorsViewModel: WallpaperColorsViewModel,
clockViewFactory: ClockViewFactory,
): ClockSettingsViewModel.Factory {
return clockSettingsViewModelFactory
?: ClockSettingsViewModel.Factory(
context.applicationContext,
getClockPickerInteractor(context),
getColorPickerInteractor(
context,
wallpaperColorsViewModel,
),
) { clockId ->
clockId?.let { clockViewFactory.getController(clockId).config.isReactiveToTone }
?: false
}
.also { clockSettingsViewModelFactory = it }
}
override fun getClockDescriptionUtils(resources: Resources): ClockDescriptionUtils {
return clockDescriptionUtils
?: ThemePickerClockDescriptionUtils().also { clockDescriptionUtils = it }
}
fun getGridScreenViewModelFactory(
context: Context,
): ViewModelProvider.Factory {
return gridScreenViewModelFactory
?: GridScreenViewModel.Factory(
context = context,
interactor = getGridInteractor(context),
)
.also { gridScreenViewModelFactory = it }
}
private fun getGridInteractor(
context: Context,
): GridInteractor {
val appContext = context.applicationContext
return gridInteractor
?: GridInteractor(
applicationScope = getApplicationCoroutineScope(),
repository =
GridRepositoryImpl(
context = appContext,
applicationScope = getApplicationCoroutineScope(),
manager = GridOptionsManager.getInstance(context),
backgroundDispatcher = bgDispatcher,
),
snapshotRestorer = { getGridSnapshotRestorer(appContext) },
)
.also { gridInteractor = it }
}
private fun getGridSnapshotRestorer(
context: Context,
): GridSnapshotRestorer {
return gridSnapshotRestorer
?: GridSnapshotRestorer(
interactor = getGridInteractor(context),
)
.also { gridSnapshotRestorer = it }
}
companion object {
@JvmStatic
private val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER =
WallpaperPicker2Injector.MIN_SNAPSHOT_RESTORER_KEY
@JvmStatic
private val KEY_WALLPAPER_SNAPSHOT_RESTORER = KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER + 1
@JvmStatic
private val KEY_NOTIFICATIONS_SNAPSHOT_RESTORER = KEY_WALLPAPER_SNAPSHOT_RESTORER + 1
@JvmStatic
private val KEY_DARK_MODE_SNAPSHOT_RESTORER = KEY_NOTIFICATIONS_SNAPSHOT_RESTORER + 1
@JvmStatic
private val KEY_THEMED_ICON_SNAPSHOT_RESTORER = KEY_DARK_MODE_SNAPSHOT_RESTORER + 1
@JvmStatic
private val KEY_APP_GRID_SNAPSHOT_RESTORER = KEY_THEMED_ICON_SNAPSHOT_RESTORER + 1
@JvmStatic
private val KEY_COLOR_PICKER_SNAPSHOT_RESTORER = KEY_APP_GRID_SNAPSHOT_RESTORER + 1
@JvmStatic private val KEY_CLOCKS_SNAPSHOT_RESTORER = KEY_COLOR_PICKER_SNAPSHOT_RESTORER + 1
/**
* When this injector is overridden, this is the minimal value that should be used by
* restorers returns in [getSnapshotRestorers].
*
* It should always be greater than the biggest restorer key.
*/
@JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_CLOCKS_SNAPSHOT_RESTORER + 1
}
}