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