summaryrefslogtreecommitdiff
path: root/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
blob: 41ef3a5759d5a9d54464c477823961de54dcd56a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * 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.util.Log
import com.android.customization.model.CustomizationManager
import com.android.customization.model.color.ColorCustomizationManager
import com.android.customization.model.color.ColorOption
import com.android.customization.model.color.ColorOptionImpl
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.WallpaperColorsModel
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(
    wallpaperColorsViewModel: WallpaperColorsViewModel,
    private val colorManager: ColorCustomizationManager,
) : ColorPickerRepository {

    private val homeWallpaperColors: StateFlow<WallpaperColorsModel?> =
        wallpaperColorsViewModel.homeWallpaperColors
    private val lockWallpaperColors: StateFlow<WallpaperColorsModel?> =
        wallpaperColorsViewModel.lockWallpaperColors

    override val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> =
        combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors ->
                homeColors to lockColors
            }
            .map { (homeColors, lockColors) ->
                suspendCancellableCoroutine { continuation ->
                    if (
                        homeColors is WallpaperColorsModel.Loading ||
                            lockColors is WallpaperColorsModel.Loading
                    ) {
                        continuation.resumeWith(
                            Result.success(
                                mapOf(
                                    ColorType.WALLPAPER_COLOR to listOf(),
                                    ColorType.PRESET_COLOR to listOf()
                                )
                            )
                        )
                        return@suspendCancellableCoroutine
                    }
                    val homeColorsLoaded = homeColors as WallpaperColorsModel.Loaded
                    val lockColorsLoaded = lockColors as WallpaperColorsModel.Loaded
                    colorManager.setWallpaperColors(
                        homeColorsLoaded.colors,
                        lockColorsLoaded.colors
                    )
                    colorManager.fetchRevampedUIOptions(
                        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 as ColorOptionImpl).type) {
                                        ColorType.WALLPAPER_COLOR ->
                                            wallpaperColorOptions.add(option.toModel())
                                        ColorType.PRESET_COLOR ->
                                            presetColorOptions.add(option.toModel())
                                    }
                                }
                                continuation.resumeWith(
                                    Result.success(
                                        mapOf(
                                            ColorType.WALLPAPER_COLOR to wallpaperColorOptions,
                                            ColorType.PRESET_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
        val styleOrNull = colorManager.currentStyle
        val style = styleOrNull?.let { Style.valueOf(it) } ?: Style.TONAL_SPOT
        val source = colorManager.currentColorSource
        val colorOptionBuilder = ColorOptionImpl.Builder()
        colorOptionBuilder.source = source
        colorOptionBuilder.style = style
        for (overlay in overlays) {
            colorOptionBuilder.addOverlayPackage(overlay.key, overlay.value)
        }
        val colorOption = colorOptionBuilder.build()
        return ColorOptionModel(
            key = "",
            colorOption = colorOption,
            isSelected = false,
        )
    }

    override fun getCurrentColorSource(): String? {
        return colorManager.currentColorSource
    }

    private fun ColorOptionImpl.toModel(): ColorOptionModel {
        return ColorOptionModel(
            key = "${this.type}::${this.style}::${this.serializedPackages}",
            colorOption = this,
            isSelected = isActive(colorManager),
        )
    }

    companion object {
        private const val TAG = "ColorPickerRepositoryImpl"
    }
}