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.picker.customization.domain.interactor 19 20 import android.stats.style.StyleEnums.SET_WALLPAPER_ENTRY_POINT_RESET 21 import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository.Companion.DEFAULT_KEY 22 import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination 23 import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer 24 import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore 25 import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot 26 import kotlinx.coroutines.CoroutineScope 27 import kotlinx.coroutines.flow.combine 28 import kotlinx.coroutines.flow.drop 29 import kotlinx.coroutines.flow.filter 30 import kotlinx.coroutines.flow.first 31 import kotlinx.coroutines.launch 32 33 /** Stores and restores undo snapshots for wallpaper state. */ 34 class WallpaperSnapshotRestorer( 35 private val scope: CoroutineScope, 36 private val interactor: WallpaperInteractor, 37 ) : SnapshotRestorer { 38 39 private var store: SnapshotStore = SnapshotStore.NOOP 40 41 override suspend fun setUpSnapshotRestorer( 42 store: SnapshotStore, 43 ): RestorableSnapshot { 44 this.store = store 45 startObserving() 46 return snapshot() 47 } 48 49 override suspend fun restoreToSnapshot( 50 snapshot: RestorableSnapshot, 51 ) { 52 val homeWallpaperId = snapshot.args[SELECTED_HOME_SCREEN_WALLPAPER_ID] 53 if (!homeWallpaperId.isNullOrEmpty()) { 54 interactor.setRecentWallpaper( 55 setWallpaperEntryPoint = SET_WALLPAPER_ENTRY_POINT_RESET, 56 destination = WallpaperDestination.HOME, 57 wallpaperId = homeWallpaperId 58 ) 59 } 60 61 val lockWallpaperId = snapshot.args[SELECTED_LOCK_SCREEN_WALLPAPER_ID] 62 if (!lockWallpaperId.isNullOrEmpty()) { 63 interactor.setRecentWallpaper( 64 setWallpaperEntryPoint = SET_WALLPAPER_ENTRY_POINT_RESET, 65 destination = WallpaperDestination.LOCK, 66 wallpaperId = lockWallpaperId 67 ) 68 } 69 } 70 71 private fun startObserving() { 72 scope.launch { 73 combine( 74 interactor.selectedWallpaperId(destination = WallpaperDestination.HOME), 75 interactor.selectedWallpaperId(destination = WallpaperDestination.LOCK), 76 ::Pair, 77 ) 78 .drop(1) // We skip the first value because it's the same as the initial. 79 .collect { (homeWallpaperId, lockWallpaperId) -> 80 store.store( 81 snapshot( 82 homeWallpaperId, 83 lockWallpaperId, 84 ) 85 ) 86 } 87 } 88 } 89 90 private suspend fun snapshot( 91 homeWallpaperId: String? = null, 92 lockWallpaperId: String? = null, 93 ): RestorableSnapshot { 94 return RestorableSnapshot( 95 args = 96 buildMap { 97 put( 98 SELECTED_HOME_SCREEN_WALLPAPER_ID, 99 homeWallpaperId 100 ?: querySelectedWallpaperId(destination = WallpaperDestination.HOME), 101 ) 102 put( 103 SELECTED_LOCK_SCREEN_WALLPAPER_ID, 104 lockWallpaperId 105 ?: querySelectedWallpaperId(destination = WallpaperDestination.LOCK), 106 ) 107 } 108 ) 109 } 110 111 private suspend fun querySelectedWallpaperId(destination: WallpaperDestination): String { 112 return interactor 113 .selectedWallpaperId(destination = destination) 114 .filter { it != DEFAULT_KEY } 115 .first() 116 } 117 118 companion object { 119 private const val SELECTED_HOME_SCREEN_WALLPAPER_ID = "selected_home_screen_wallpaper_id" 120 private const val SELECTED_LOCK_SCREEN_WALLPAPER_ID = "selected_lock_screen_wallpaper_id" 121 } 122 } 123