1 /* <lambda>null2 * Copyright (C) 2022 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.ui.viewmodel 19 20 import android.os.Bundle 21 import androidx.annotation.VisibleForTesting 22 import androidx.lifecycle.AbstractSavedStateViewModelFactory 23 import androidx.lifecycle.SavedStateHandle 24 import androidx.lifecycle.ViewModel 25 import androidx.lifecycle.viewModelScope 26 import androidx.savedstate.SavedStateRegistryOwner 27 import com.android.wallpaper.module.CustomizationSections 28 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor 29 import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination 30 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor 31 import com.android.wallpaper.picker.undo.ui.viewmodel.UndoViewModel 32 import kotlinx.coroutines.flow.Flow 33 import kotlinx.coroutines.flow.MutableStateFlow 34 import kotlinx.coroutines.flow.asStateFlow 35 import kotlinx.coroutines.flow.map 36 37 /** Models UI state for the customization picker. */ 38 class CustomizationPickerViewModel 39 @VisibleForTesting 40 constructor( 41 undoInteractor: UndoInteractor, 42 wallpaperInteractor: WallpaperInteractor, 43 private val savedStateHandle: SavedStateHandle, 44 ) : AnimationStateViewModel() { 45 46 val undo: UndoViewModel = 47 UndoViewModel( 48 interactor = undoInteractor, 49 ) 50 51 private val homeWallpaperQuickSwitchViewModel: WallpaperQuickSwitchViewModel = 52 WallpaperQuickSwitchViewModel( 53 interactor = wallpaperInteractor, 54 destination = WallpaperDestination.HOME, 55 coroutineScope = viewModelScope, 56 ) 57 58 private val lockWallpaperQuickSwitchViewModel: WallpaperQuickSwitchViewModel = 59 WallpaperQuickSwitchViewModel( 60 interactor = wallpaperInteractor, 61 destination = WallpaperDestination.LOCK, 62 coroutineScope = viewModelScope, 63 ) 64 65 fun getWallpaperQuickSwitchViewModel( 66 screen: CustomizationSections.Screen 67 ): WallpaperQuickSwitchViewModel { 68 return if (screen == CustomizationSections.Screen.LOCK_SCREEN) 69 lockWallpaperQuickSwitchViewModel 70 else homeWallpaperQuickSwitchViewModel 71 } 72 73 private val _isOnLockScreen = MutableStateFlow(true) 74 /** Whether we are on the lock screen. If `false`, we are on the home screen. */ 75 val isOnLockScreen: Flow<Boolean> = _isOnLockScreen.asStateFlow() 76 77 /** A view-model for the "lock screen" tab. */ 78 val lockScreenTab: Flow<CustomizationPickerTabViewModel> = 79 isOnLockScreen.map { onLockScreen -> 80 CustomizationPickerTabViewModel( 81 isSelected = onLockScreen, 82 onClicked = 83 if (!onLockScreen) { 84 { 85 _isOnLockScreen.value = true 86 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = true 87 } 88 } else { 89 null 90 } 91 ) 92 } 93 /** A view-model for the "home screen" tab. */ 94 val homeScreenTab: Flow<CustomizationPickerTabViewModel> = 95 isOnLockScreen.map { onLockScreen -> 96 CustomizationPickerTabViewModel( 97 isSelected = !onLockScreen, 98 onClicked = 99 if (onLockScreen) { 100 { 101 _isOnLockScreen.value = false 102 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = false 103 } 104 } else { 105 null 106 } 107 ) 108 } 109 110 init { 111 savedStateHandle.get<Boolean>(KEY_SAVED_STATE_IS_ON_LOCK_SCREEN)?.let { 112 _isOnLockScreen.value = it 113 } 114 } 115 116 /** 117 * Sets the initial screen we should be on, unless there's already a selected screen from a 118 * previous saved state, in which case we ignore the passed-in one. 119 */ 120 fun setInitialScreen(onLockScreen: Boolean) { 121 _isOnLockScreen.value = 122 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] 123 ?: run { 124 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = onLockScreen 125 onLockScreen 126 } 127 } 128 129 companion object { 130 @JvmStatic 131 fun newFactory( 132 owner: SavedStateRegistryOwner, 133 defaultArgs: Bundle? = null, 134 undoInteractor: UndoInteractor, 135 wallpaperInteractor: WallpaperInteractor, 136 ): AbstractSavedStateViewModelFactory = 137 object : AbstractSavedStateViewModelFactory(owner, defaultArgs) { 138 @Suppress("UNCHECKED_CAST") 139 override fun <T : ViewModel> create( 140 key: String, 141 modelClass: Class<T>, 142 handle: SavedStateHandle, 143 ): T { 144 return CustomizationPickerViewModel( 145 undoInteractor = undoInteractor, 146 wallpaperInteractor = wallpaperInteractor, 147 savedStateHandle = handle, 148 ) 149 as T 150 } 151 } 152 153 private const val KEY_SAVED_STATE_IS_ON_LOCK_SCREEN = "is_on_lock_screen" 154 } 155 } 156