1 /*
<lambda>null2  * Copyright (C) 2023 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  */
17 
18 package com.android.wallpaper.testing
19 
20 import android.app.WallpaperColors
21 import android.graphics.Bitmap
22 import android.graphics.Point
23 import android.graphics.Rect
24 import com.android.wallpaper.asset.Asset
25 import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint
26 import com.android.wallpaper.picker.customization.data.content.WallpaperClient
27 import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination
28 import com.android.wallpaper.picker.customization.shared.model.WallpaperModel
29 import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
30 import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
31 import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
32 import javax.inject.Inject
33 import javax.inject.Singleton
34 import kotlin.math.min
35 import kotlinx.coroutines.flow.Flow
36 import kotlinx.coroutines.flow.MutableStateFlow
37 import kotlinx.coroutines.flow.map
38 
39 @Singleton
40 class FakeWallpaperClient @Inject constructor() : WallpaperClient {
41     val wallpapersSet =
42         mutableMapOf(
43             WallpaperDestination.HOME to
44                 mutableListOf<com.android.wallpaper.picker.data.WallpaperModel>(),
45             WallpaperDestination.LOCK to mutableListOf()
46         )
47     private var wallpaperColors: WallpaperColors? = null
48 
49     private val _recentWallpapers =
50         MutableStateFlow(
51             buildMap {
52                 WallpaperDestination.values()
53                     .filter { it != WallpaperDestination.BOTH }
54                     .forEach { screen -> put(screen, INITIAL_RECENT_WALLPAPERS) }
55             }
56         )
57     private var isPaused = false
58     private var deferred = mutableListOf<(suspend () -> Unit)>()
59 
60     fun setRecentWallpapers(
61         recentWallpapersByDestination: Map<WallpaperDestination, List<WallpaperModel>>,
62     ) {
63         _recentWallpapers.value = recentWallpapersByDestination
64     }
65 
66     fun pause() {
67         isPaused = true
68     }
69 
70     suspend fun unpause() {
71         isPaused = false
72         deferred.forEach { it.invoke() }
73         deferred.clear()
74     }
75 
76     override fun recentWallpapers(
77         destination: WallpaperDestination,
78         limit: Int,
79     ): Flow<List<WallpaperModel>> {
80         return _recentWallpapers.map { wallpapersByScreen ->
81             val wallpapers =
82                 wallpapersByScreen[destination] ?: error("No wallpapers for screen $destination")
83             if (wallpapers.size > limit) {
84                 wallpapers.subList(0, min(limit, wallpapers.size))
85             } else {
86                 wallpapers
87             }
88         }
89     }
90 
91     fun getCurrentWallpaper(
92         destination: WallpaperDestination,
93     ): WallpaperModel {
94         return _recentWallpapers.value[destination]?.get(0)
95             ?: error("No wallpapers for screen $destination")
96     }
97 
98     override suspend fun setStaticWallpaper(
99         setWallpaperEntryPoint: Int,
100         destination: WallpaperDestination,
101         wallpaperModel: StaticWallpaperModel,
102         bitmap: Bitmap,
103         wallpaperSize: Point,
104         asset: Asset,
105         fullPreviewCropModels: Map<Point, FullPreviewCropModel>?,
106     ) {
107         addToWallpapersSet(wallpaperModel, destination)
108     }
109 
110     override suspend fun setLiveWallpaper(
111         setWallpaperEntryPoint: Int,
112         destination: WallpaperDestination,
113         wallpaperModel: LiveWallpaperModel,
114     ) {
115         addToWallpapersSet(wallpaperModel, destination)
116     }
117 
118     private fun addToWallpapersSet(
119         wallpaperModel: com.android.wallpaper.picker.data.WallpaperModel,
120         destination: WallpaperDestination
121     ) {
122         wallpapersSet.forEach { entry ->
123             if (destination == entry.key || destination == WallpaperDestination.BOTH) {
124                 entry.value.add(wallpaperModel)
125             }
126         }
127     }
128 
129     override suspend fun setRecentWallpaper(
130         @SetWallpaperEntryPoint setWallpaperEntryPoint: Int,
131         destination: WallpaperDestination,
132         wallpaperId: String,
133         onDone: () -> Unit
134     ) {
135         if (isPaused) {
136             deferred.add {
137                 setRecentWallpaper(setWallpaperEntryPoint, destination, wallpaperId, onDone)
138             }
139         } else {
140             _recentWallpapers.value =
141                 _recentWallpapers.value.toMutableMap().apply {
142                     this[destination] =
143                         _recentWallpapers.value[destination]?.sortedBy {
144                             it.wallpaperId != wallpaperId
145                         }
146                             ?: error("No wallpapers for screen $destination")
147                 }
148             onDone.invoke()
149         }
150     }
151 
152     override suspend fun loadThumbnail(
153         wallpaperId: String,
154         destination: WallpaperDestination
155     ): Bitmap? {
156         return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
157     }
158 
159     override fun areRecentsAvailable(): Boolean {
160         return true
161     }
162 
163     override fun getCurrentCropHints(displaySizes: List<Point>, which: Int): Map<Point, Rect>? {
164         return emptyMap()
165     }
166 
167     fun setWallpaperColors(wallpaperColors: WallpaperColors) {
168         this.wallpaperColors = wallpaperColors
169     }
170 
171     override suspend fun getWallpaperColors(
172         bitmap: Bitmap,
173         cropHints: Map<Point, Rect>?
174     ): WallpaperColors? {
175         return wallpaperColors
176     }
177 
178     companion object {
179         val INITIAL_RECENT_WALLPAPERS =
180             listOf(
181                 WallpaperModel(wallpaperId = "zero", placeholderColor = 0, title = "title1"),
182                 WallpaperModel(wallpaperId = "one", placeholderColor = 1, title = "title2"),
183                 WallpaperModel(wallpaperId = "two", placeholderColor = 2, title = "title3"),
184             )
185     }
186 }
187