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 android.os.Handler 25 import com.android.wallpaper.asset.Asset 26 import com.android.wallpaper.model.Screen 27 import com.android.wallpaper.model.WallpaperModelsPair 28 import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint 29 import com.android.wallpaper.picker.customization.data.content.WallpaperClient 30 import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination 31 import com.android.wallpaper.picker.customization.shared.model.WallpaperModel 32 import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel 33 import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel 34 import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel 35 import javax.inject.Inject 36 import javax.inject.Singleton 37 import kotlin.math.min 38 import kotlinx.coroutines.flow.Flow 39 import kotlinx.coroutines.flow.MutableStateFlow 40 import kotlinx.coroutines.flow.map 41 42 @Singleton 43 class FakeWallpaperClient @Inject constructor() : WallpaperClient { 44 val wallpapersSet = 45 mutableMapOf( 46 WallpaperDestination.HOME to null as com.android.wallpaper.picker.data.WallpaperModel?, 47 WallpaperDestination.LOCK to null as com.android.wallpaper.picker.data.WallpaperModel?, 48 ) 49 private var wallpaperColors: WallpaperColors? = null 50 51 private val _recentWallpapers = 52 MutableStateFlow( 53 buildMap { 54 WallpaperDestination.values() 55 .filter { it != WallpaperDestination.BOTH } 56 .forEach { screen -> put(screen, INITIAL_RECENT_WALLPAPERS) } 57 } 58 ) 59 private var isPaused = false 60 private var deferred = mutableListOf<(suspend () -> Unit)>() 61 62 fun setRecentWallpapers( 63 recentWallpapersByDestination: Map<WallpaperDestination, List<WallpaperModel>> 64 ) { 65 _recentWallpapers.value = recentWallpapersByDestination 66 } 67 68 fun pause() { 69 isPaused = true 70 } 71 72 suspend fun unpause() { 73 isPaused = false 74 deferred.forEach { it.invoke() } 75 deferred.clear() 76 } 77 78 override fun recentWallpapers( 79 destination: WallpaperDestination, 80 limit: Int, 81 ): Flow<List<WallpaperModel>> { 82 return _recentWallpapers.map { wallpapersByScreen -> 83 val wallpapers = 84 wallpapersByScreen[destination] ?: error("No wallpapers for screen $destination") 85 if (wallpapers.size > limit) { 86 wallpapers.subList(0, min(limit, wallpapers.size)) 87 } else { 88 wallpapers 89 } 90 } 91 } 92 93 fun getCurrentWallpaper(destination: WallpaperDestination): 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[destination] = wallpaperModel 123 } 124 125 override suspend fun setRecentWallpaper( 126 @SetWallpaperEntryPoint setWallpaperEntryPoint: Int, 127 destination: WallpaperDestination, 128 wallpaperId: String, 129 onDone: () -> Unit, 130 ) { 131 if (isPaused) { 132 deferred.add { 133 setRecentWallpaper(setWallpaperEntryPoint, destination, wallpaperId, onDone) 134 } 135 } else { 136 _recentWallpapers.value = 137 _recentWallpapers.value.toMutableMap().apply { 138 this[destination] = 139 _recentWallpapers.value[destination]?.sortedBy { 140 it.wallpaperId != wallpaperId 141 } ?: error("No wallpapers for screen $destination") 142 } 143 onDone.invoke() 144 } 145 } 146 147 override suspend fun loadThumbnail( 148 wallpaperId: String, 149 destination: WallpaperDestination, 150 ): Bitmap? { 151 return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) 152 } 153 154 override fun areRecentsAvailable(): Boolean { 155 return true 156 } 157 158 override fun getCurrentCropHints(displaySizes: List<Point>, which: Int): Map<Point, Rect>? { 159 return emptyMap() 160 } 161 162 fun setWallpaperColors(wallpaperColors: WallpaperColors) { 163 this.wallpaperColors = wallpaperColors 164 } 165 166 override suspend fun getWallpaperColors( 167 bitmap: Bitmap, 168 cropHints: Map<Point, Rect>?, 169 ): WallpaperColors? { 170 return wallpaperColors 171 } 172 173 override fun getWallpaperColors(screen: Screen): WallpaperColors? { 174 return wallpaperColors 175 } 176 177 fun setCurrentWallpaperModels( 178 homeWallpaper: com.android.wallpaper.picker.data.WallpaperModel, 179 lockWallpaper: com.android.wallpaper.picker.data.WallpaperModel?, 180 ) { 181 wallpapersSet[WallpaperDestination.HOME] = homeWallpaper 182 wallpapersSet[WallpaperDestination.LOCK] = lockWallpaper 183 } 184 185 // Getting current home wallpaper should always return non-null value 186 override suspend fun getCurrentWallpaperModels(forceRefresh: Boolean): WallpaperModelsPair { 187 return WallpaperModelsPair( 188 wallpapersSet[WallpaperDestination.HOME] 189 ?: (WallpaperModelUtils.getStaticWallpaperModel( 190 wallpaperId = "defaultWallpaperId", 191 collectionId = "defaultCollection", 192 ) 193 .also { wallpapersSet[WallpaperDestination.HOME] = it }), 194 wallpapersSet[WallpaperDestination.LOCK], 195 ) 196 } 197 198 override fun addOnColorsChangedListener( 199 listener: (WallpaperColors?, Int) -> Unit, 200 handler: Handler, 201 ) { 202 TODO("Not yet implemented") 203 } 204 205 override fun removeOnColorsChangedListener(listener: (WallpaperColors?, Int) -> Unit) { 206 TODO("Not yet implemented") 207 } 208 209 companion object { 210 val INITIAL_RECENT_WALLPAPERS = 211 listOf( 212 WallpaperModel(wallpaperId = "zero", placeholderColor = 0, title = "title1"), 213 WallpaperModel(wallpaperId = "one", placeholderColor = 1, title = "title2"), 214 WallpaperModel(wallpaperId = "two", placeholderColor = 2, title = "title3"), 215 ) 216 } 217 } 218