Loading src/com/android/customization/model/color/ColorOption.java +3 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ public abstract class ColorOption implements CustomizationOption<ColorOption> { if (other == null) { return false; } if (mStyle != other.getStyle()) { return false; } if (mIsDefault) { return other.isDefault() || TextUtils.isEmpty(other.getSerializedPackages()) || EMPTY_JSON.equals(other.getSerializedPackages()); Loading src/com/android/customization/module/ThemePickerInjector.kt +25 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel 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 Loading Loading @@ -100,6 +101,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null private var colorPickerInteractor: ColorPickerInteractor? = null private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null private var colorPickerSnapshotRestorer: ColorPickerSnapshotRestorer? = null private var darkModeSnapshotRestorer: DarkModeSnapshotRestorer? = null private var themedIconSnapshotRestorer: ThemedIconSnapshotRestorer? = null private var themedIconInteractor: ThemedIconInteractor? = null Loading @@ -113,8 +115,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject ?: DefaultCustomizationSections( getColorPickerViewModelFactory( context = activity, wallpaperColorsViewModel = ViewModelProvider(activity)[WallpaperColorsViewModel::class.java], wallpaperColorsViewModel = getWallpaperColorsViewModel(), ), getKeyguardQuickAffordancePickerInteractor(activity), getKeyguardQuickAffordancePickerViewModelFactory(activity), Loading Loading @@ -190,6 +191,8 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject 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()) } } Loading Loading @@ -346,7 +349,12 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject wallpaperColorsViewModel: WallpaperColorsViewModel, ): ColorPickerInteractor { return colorPickerInteractor ?: ColorPickerInteractor(ColorPickerRepositoryImpl(context, wallpaperColorsViewModel)) ?: ColorPickerInteractor( repository = ColorPickerRepositoryImpl(context, wallpaperColorsViewModel), snapshotRestorer = { getColorPickerSnapshotRestorer(context, wallpaperColorsViewModel) } ) .also { colorPickerInteractor = it } } Loading @@ -362,6 +370,17 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject .also { colorPickerViewModelFactory = it } } private fun getColorPickerSnapshotRestorer( context: Context, wallpaperColorsViewModel: WallpaperColorsViewModel, ): ColorPickerSnapshotRestorer { return colorPickerSnapshotRestorer ?: ColorPickerSnapshotRestorer( getColorPickerInteractor(context, wallpaperColorsViewModel) ) .also { colorPickerSnapshotRestorer = it } } fun getDarkModeSnapshotRestorer( context: Context, ): DarkModeSnapshotRestorer { Loading Loading @@ -460,6 +479,8 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject 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 /** * When this injector is overridden, this is the minimal value that should be used by Loading @@ -467,6 +488,6 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject * * It should always be greater than the biggest restorer key. */ @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_APP_GRID_SNAPSHOT_RESTORER + 1 @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_COLOR_PICKER_SNAPSHOT_RESTORER + 1 } } src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt +1 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import androidx.lifecycle.get import com.android.customization.module.ThemePickerInjector import com.android.customization.picker.clock.ui.binder.ClockSettingsBinder import com.android.wallpaper.R import com.android.wallpaper.model.WallpaperColorsViewModel import com.android.wallpaper.module.InjectorProvider import com.android.wallpaper.picker.AppbarFragment import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder Loading Loading @@ -63,7 +62,7 @@ class ClockSettingsFragment : AppbarFragment() { val injector = InjectorProvider.getInjector() as ThemePickerInjector val lockScreenView: CardView = view.requireViewById(R.id.lock_preview) val colorViewModel = ViewModelProvider(activity)[WallpaperColorsViewModel::class.java] val colorViewModel = injector.getWallpaperColorsViewModel() val displayUtils = injector.getDisplayUtils(context) ScreenPreviewBinder.bind( activity = activity, Loading src/com/android/customization/picker/color/data/repository/ColorPickerRepository.kt +4 −6 Original line number Diff line number Diff line Loading @@ -25,15 +25,13 @@ import kotlinx.coroutines.flow.Flow * system color. */ interface ColorPickerRepository { /** * The newly selected color option for overwriting the current active option during an * optimistic update, the value is null when no overwriting is needed */ val activeColorOption: Flow<ColorOptionModel?> /** List of wallpaper and preset color options on the device, categorized by Color Type */ val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> /** Selects a color option with optimistic update */ fun select(colorOptionModel: ColorOptionModel) suspend fun select(colorOptionModel: ColorOptionModel) /** Returns the current selected color option based on system settings */ fun getCurrentColorOption(): ColorOptionModel } src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt +43 −34 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.app.WallpaperColors import android.content.Context import android.util.Log import com.android.customization.model.CustomizationManager import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE import com.android.customization.model.color.ColorBundle import com.android.customization.model.color.ColorCustomizationManager import com.android.customization.model.color.ColorOption Loading @@ -27,11 +29,10 @@ import com.android.customization.model.color.ColorSeedOption import com.android.customization.model.theme.OverlayManagerCompat import com.android.customization.picker.color.shared.model.ColorOptionModel import com.android.customization.picker.color.shared.model.ColorType import com.android.systemui.monet.Style import com.android.wallpaper.model.WallpaperColorsViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.suspendCancellableCoroutine Loading @@ -50,17 +51,11 @@ class ColorPickerRepositoryImpl( private val colorManager: ColorCustomizationManager = ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context)) private val _activeColorOption = MutableStateFlow<ColorOptionModel?>(null) override val activeColorOption: StateFlow<ColorOptionModel?> = _activeColorOption.asStateFlow() override val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> = combine(activeColorOption, homeWallpaperColors, lockWallpaperColors) { activeOption, homeColors, lockColors -> Triple(activeOption, homeColors, lockColors) combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors -> homeColors to lockColors } .map { (activeOption, homeColors, lockColors) -> .map { (homeColors, lockColors) -> suspendCancellableCoroutine { continuation -> colorManager.setWallpaperColors(homeColors, lockColors) colorManager.fetchOptions( Loading @@ -73,9 +68,8 @@ class ColorPickerRepositoryImpl( options?.forEach { option -> when (option) { is ColorSeedOption -> wallpaperColorOptions.add(option.toModel(activeOption)) is ColorBundle -> presetColorOptions.add(option.toModel(activeOption)) wallpaperColorOptions.add(option.toModel()) is ColorBundle -> presetColorOptions.add(option.toModel()) } } continuation.resumeWith( Loading @@ -102,33 +96,48 @@ class ColorPickerRepositoryImpl( } } override fun select(colorOptionModel: ColorOptionModel) { _activeColorOption.value = colorOptionModel val colorOption: ColorOption = colorOptionModel.colorOption override suspend fun select(colorOptionModel: ColorOptionModel) = suspendCancellableCoroutine { continuation -> colorManager.apply( colorOption, colorOptionModel.colorOption, object : CustomizationManager.Callback { override fun onSuccess() { _activeColorOption.value = null continuation.resumeWith(Result.success(Unit)) } override fun onError(throwable: Throwable?) { _activeColorOption.value = null Log.w(TAG, "Apply theme with error", throwable) continuation.resumeWith( Result.failure(throwable ?: Throwable("Error loading theme bundles")) ) } } ) } override fun getCurrentColorOption(): ColorOptionModel { val overlays = colorManager.currentOverlays return ColorOptionModel( colorOption = // Does not matter whether ColorSeedOption or ColorBundle builder is used here // because to apply the color, one just needs a generic ColorOption ColorSeedOption.Builder() .addOverlayPackage( OVERLAY_CATEGORY_SYSTEM_PALETTE, overlays[OVERLAY_CATEGORY_SYSTEM_PALETTE] ) .addOverlayPackage(OVERLAY_CATEGORY_COLOR, overlays[OVERLAY_CATEGORY_COLOR]) .setSource(colorManager.currentColorSource) .setStyle(Style.valueOf(colorManager.currentStyle)) .build(), isSelected = false, ) } private fun ColorOption.toModel(activeColorOption: ColorOptionModel?): ColorOptionModel { private fun ColorOption.toModel(): ColorOptionModel { return ColorOptionModel( colorOption = this, isSelected = if (activeColorOption != null) { isEquivalent(activeColorOption.colorOption) } else { isActive(colorManager) }, isSelected = isActive(colorManager), ) } Loading Loading
src/com/android/customization/model/color/ColorOption.java +3 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ public abstract class ColorOption implements CustomizationOption<ColorOption> { if (other == null) { return false; } if (mStyle != other.getStyle()) { return false; } if (mIsDefault) { return other.isDefault() || TextUtils.isEmpty(other.getSerializedPackages()) || EMPTY_JSON.equals(other.getSerializedPackages()); Loading
src/com/android/customization/module/ThemePickerInjector.kt +25 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel 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 Loading Loading @@ -100,6 +101,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null private var colorPickerInteractor: ColorPickerInteractor? = null private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null private var colorPickerSnapshotRestorer: ColorPickerSnapshotRestorer? = null private var darkModeSnapshotRestorer: DarkModeSnapshotRestorer? = null private var themedIconSnapshotRestorer: ThemedIconSnapshotRestorer? = null private var themedIconInteractor: ThemedIconInteractor? = null Loading @@ -113,8 +115,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject ?: DefaultCustomizationSections( getColorPickerViewModelFactory( context = activity, wallpaperColorsViewModel = ViewModelProvider(activity)[WallpaperColorsViewModel::class.java], wallpaperColorsViewModel = getWallpaperColorsViewModel(), ), getKeyguardQuickAffordancePickerInteractor(activity), getKeyguardQuickAffordancePickerViewModelFactory(activity), Loading Loading @@ -190,6 +191,8 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject 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()) } } Loading Loading @@ -346,7 +349,12 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject wallpaperColorsViewModel: WallpaperColorsViewModel, ): ColorPickerInteractor { return colorPickerInteractor ?: ColorPickerInteractor(ColorPickerRepositoryImpl(context, wallpaperColorsViewModel)) ?: ColorPickerInteractor( repository = ColorPickerRepositoryImpl(context, wallpaperColorsViewModel), snapshotRestorer = { getColorPickerSnapshotRestorer(context, wallpaperColorsViewModel) } ) .also { colorPickerInteractor = it } } Loading @@ -362,6 +370,17 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject .also { colorPickerViewModelFactory = it } } private fun getColorPickerSnapshotRestorer( context: Context, wallpaperColorsViewModel: WallpaperColorsViewModel, ): ColorPickerSnapshotRestorer { return colorPickerSnapshotRestorer ?: ColorPickerSnapshotRestorer( getColorPickerInteractor(context, wallpaperColorsViewModel) ) .also { colorPickerSnapshotRestorer = it } } fun getDarkModeSnapshotRestorer( context: Context, ): DarkModeSnapshotRestorer { Loading Loading @@ -460,6 +479,8 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject 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 /** * When this injector is overridden, this is the minimal value that should be used by Loading @@ -467,6 +488,6 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject * * It should always be greater than the biggest restorer key. */ @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_APP_GRID_SNAPSHOT_RESTORER + 1 @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_COLOR_PICKER_SNAPSHOT_RESTORER + 1 } }
src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt +1 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import androidx.lifecycle.get import com.android.customization.module.ThemePickerInjector import com.android.customization.picker.clock.ui.binder.ClockSettingsBinder import com.android.wallpaper.R import com.android.wallpaper.model.WallpaperColorsViewModel import com.android.wallpaper.module.InjectorProvider import com.android.wallpaper.picker.AppbarFragment import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder Loading Loading @@ -63,7 +62,7 @@ class ClockSettingsFragment : AppbarFragment() { val injector = InjectorProvider.getInjector() as ThemePickerInjector val lockScreenView: CardView = view.requireViewById(R.id.lock_preview) val colorViewModel = ViewModelProvider(activity)[WallpaperColorsViewModel::class.java] val colorViewModel = injector.getWallpaperColorsViewModel() val displayUtils = injector.getDisplayUtils(context) ScreenPreviewBinder.bind( activity = activity, Loading
src/com/android/customization/picker/color/data/repository/ColorPickerRepository.kt +4 −6 Original line number Diff line number Diff line Loading @@ -25,15 +25,13 @@ import kotlinx.coroutines.flow.Flow * system color. */ interface ColorPickerRepository { /** * The newly selected color option for overwriting the current active option during an * optimistic update, the value is null when no overwriting is needed */ val activeColorOption: Flow<ColorOptionModel?> /** List of wallpaper and preset color options on the device, categorized by Color Type */ val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> /** Selects a color option with optimistic update */ fun select(colorOptionModel: ColorOptionModel) suspend fun select(colorOptionModel: ColorOptionModel) /** Returns the current selected color option based on system settings */ fun getCurrentColorOption(): ColorOptionModel }
src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt +43 −34 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.app.WallpaperColors import android.content.Context import android.util.Log import com.android.customization.model.CustomizationManager import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE import com.android.customization.model.color.ColorBundle import com.android.customization.model.color.ColorCustomizationManager import com.android.customization.model.color.ColorOption Loading @@ -27,11 +29,10 @@ import com.android.customization.model.color.ColorSeedOption import com.android.customization.model.theme.OverlayManagerCompat import com.android.customization.picker.color.shared.model.ColorOptionModel import com.android.customization.picker.color.shared.model.ColorType import com.android.systemui.monet.Style import com.android.wallpaper.model.WallpaperColorsViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.suspendCancellableCoroutine Loading @@ -50,17 +51,11 @@ class ColorPickerRepositoryImpl( private val colorManager: ColorCustomizationManager = ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context)) private val _activeColorOption = MutableStateFlow<ColorOptionModel?>(null) override val activeColorOption: StateFlow<ColorOptionModel?> = _activeColorOption.asStateFlow() override val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> = combine(activeColorOption, homeWallpaperColors, lockWallpaperColors) { activeOption, homeColors, lockColors -> Triple(activeOption, homeColors, lockColors) combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors -> homeColors to lockColors } .map { (activeOption, homeColors, lockColors) -> .map { (homeColors, lockColors) -> suspendCancellableCoroutine { continuation -> colorManager.setWallpaperColors(homeColors, lockColors) colorManager.fetchOptions( Loading @@ -73,9 +68,8 @@ class ColorPickerRepositoryImpl( options?.forEach { option -> when (option) { is ColorSeedOption -> wallpaperColorOptions.add(option.toModel(activeOption)) is ColorBundle -> presetColorOptions.add(option.toModel(activeOption)) wallpaperColorOptions.add(option.toModel()) is ColorBundle -> presetColorOptions.add(option.toModel()) } } continuation.resumeWith( Loading @@ -102,33 +96,48 @@ class ColorPickerRepositoryImpl( } } override fun select(colorOptionModel: ColorOptionModel) { _activeColorOption.value = colorOptionModel val colorOption: ColorOption = colorOptionModel.colorOption override suspend fun select(colorOptionModel: ColorOptionModel) = suspendCancellableCoroutine { continuation -> colorManager.apply( colorOption, colorOptionModel.colorOption, object : CustomizationManager.Callback { override fun onSuccess() { _activeColorOption.value = null continuation.resumeWith(Result.success(Unit)) } override fun onError(throwable: Throwable?) { _activeColorOption.value = null Log.w(TAG, "Apply theme with error", throwable) continuation.resumeWith( Result.failure(throwable ?: Throwable("Error loading theme bundles")) ) } } ) } override fun getCurrentColorOption(): ColorOptionModel { val overlays = colorManager.currentOverlays return ColorOptionModel( colorOption = // Does not matter whether ColorSeedOption or ColorBundle builder is used here // because to apply the color, one just needs a generic ColorOption ColorSeedOption.Builder() .addOverlayPackage( OVERLAY_CATEGORY_SYSTEM_PALETTE, overlays[OVERLAY_CATEGORY_SYSTEM_PALETTE] ) .addOverlayPackage(OVERLAY_CATEGORY_COLOR, overlays[OVERLAY_CATEGORY_COLOR]) .setSource(colorManager.currentColorSource) .setStyle(Style.valueOf(colorManager.currentStyle)) .build(), isSelected = false, ) } private fun ColorOption.toModel(activeColorOption: ColorOptionModel?): ColorOptionModel { private fun ColorOption.toModel(): ColorOptionModel { return ColorOptionModel( colorOption = this, isSelected = if (activeColorOption != null) { isEquivalent(activeColorOption.colorOption) } else { isActive(colorManager) }, isSelected = isActive(colorManager), ) } Loading