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