blob: 70382c78826fa58923f7892d83a1f8ba3a423d28 [file] [log] [blame]
/*
* Copyright (C) 2023 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.picker.color.data.repository
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
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.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.suspendCancellableCoroutine
// TODO (b/262924623): refactor to remove dependency on ColorCustomizationManager & ColorOption
// TODO (b/268203200): Create test for ColorPickerRepositoryImpl
class ColorPickerRepositoryImpl(
context: Context,
wallpaperColorsViewModel: WallpaperColorsViewModel,
) : ColorPickerRepository {
private val homeWallpaperColors: StateFlow<WallpaperColors?> =
wallpaperColorsViewModel.homeWallpaperColors
private val lockWallpaperColors: StateFlow<WallpaperColors?> =
wallpaperColorsViewModel.lockWallpaperColors
private val colorManager: ColorCustomizationManager =
ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context))
override val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> =
combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors ->
homeColors to lockColors
}
.map { (homeColors, lockColors) ->
suspendCancellableCoroutine { continuation ->
colorManager.setWallpaperColors(homeColors, lockColors)
colorManager.fetchOptions(
object : CustomizationManager.OptionsFetchedListener<ColorOption?> {
override fun onOptionsLoaded(options: MutableList<ColorOption?>?) {
val wallpaperColorOptions: MutableList<ColorOptionModel> =
mutableListOf()
val presetColorOptions: MutableList<ColorOptionModel> =
mutableListOf()
options?.forEach { option ->
when (option) {
is ColorSeedOption ->
wallpaperColorOptions.add(option.toModel())
is ColorBundle -> presetColorOptions.add(option.toModel())
}
}
continuation.resumeWith(
Result.success(
mapOf(
ColorType.WALLPAPER_COLOR to wallpaperColorOptions,
ColorType.BASIC_COLOR to presetColorOptions
)
)
)
}
override fun onError(throwable: Throwable?) {
Log.e(TAG, "Error loading theme bundles", throwable)
continuation.resumeWith(
Result.failure(
throwable ?: Throwable("Error loading theme bundles")
)
)
}
},
/* reload= */ false
)
}
}
override suspend fun select(colorOptionModel: ColorOptionModel) =
suspendCancellableCoroutine { continuation ->
colorManager.apply(
colorOptionModel.colorOption,
object : CustomizationManager.Callback {
override fun onSuccess() {
continuation.resumeWith(Result.success(Unit))
}
override fun onError(throwable: Throwable?) {
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(): ColorOptionModel {
return ColorOptionModel(
colorOption = this,
isSelected = isActive(colorManager),
)
}
companion object {
private const val TAG = "ColorPickerRepositoryImpl"
}
}