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.savedstate.SavedStateRegistryOwner 26 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor 27 import com.android.wallpaper.picker.undo.ui.viewmodel.UndoViewModel 28 import kotlinx.coroutines.flow.Flow 29 import kotlinx.coroutines.flow.MutableStateFlow 30 import kotlinx.coroutines.flow.asStateFlow 31 import kotlinx.coroutines.flow.map 32 33 /** Models UI state for the customization picker. */ 34 class CustomizationPickerViewModel 35 @VisibleForTesting 36 constructor( 37 undoInteractor: UndoInteractor, 38 private val savedStateHandle: SavedStateHandle, 39 ) : ViewModel() { 40 41 val undo: UndoViewModel = 42 UndoViewModel( 43 interactor = undoInteractor, 44 ) 45 46 private val _isOnLockScreen = MutableStateFlow(true) 47 /** Whether we are on the lock screen. If `false`, we are on the home screen. */ 48 val isOnLockScreen: Flow<Boolean> = _isOnLockScreen.asStateFlow() 49 50 /** A view-model for the "lock screen" tab. */ 51 val lockScreenTab: Flow<CustomizationPickerTabViewModel> = 52 isOnLockScreen.map { onLockScreen -> 53 CustomizationPickerTabViewModel( 54 isSelected = onLockScreen, 55 onClicked = 56 if (!onLockScreen) { 57 { 58 _isOnLockScreen.value = true 59 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = true 60 } 61 } else { 62 null 63 } 64 ) 65 } 66 /** A view-model for the "home screen" tab. */ 67 val homeScreenTab: Flow<CustomizationPickerTabViewModel> = 68 isOnLockScreen.map { onLockScreen -> 69 CustomizationPickerTabViewModel( 70 isSelected = !onLockScreen, 71 onClicked = 72 if (onLockScreen) { 73 { 74 _isOnLockScreen.value = false 75 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = false 76 } 77 } else { 78 null 79 } 80 ) 81 } 82 83 init { 84 savedStateHandle.get<Boolean>(KEY_SAVED_STATE_IS_ON_LOCK_SCREEN)?.let { 85 _isOnLockScreen.value = it 86 } 87 } 88 89 /** 90 * Sets the initial screen we should be on, unless there's already a selected screen from a 91 * previous saved state, in which case we ignore the passed-in one. 92 */ 93 fun setInitialScreen(onLockScreen: Boolean) { 94 _isOnLockScreen.value = 95 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] 96 ?: run { 97 savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = onLockScreen 98 onLockScreen 99 } 100 } 101 102 companion object { 103 @JvmStatic 104 fun newFactory( 105 owner: SavedStateRegistryOwner, 106 defaultArgs: Bundle? = null, 107 undoInteractor: UndoInteractor, 108 ): AbstractSavedStateViewModelFactory = 109 object : AbstractSavedStateViewModelFactory(owner, defaultArgs) { 110 @Suppress("UNCHECKED_CAST") 111 override fun <T : ViewModel> create( 112 key: String, 113 modelClass: Class<T>, 114 handle: SavedStateHandle, 115 ): T { 116 return CustomizationPickerViewModel( 117 undoInteractor = undoInteractor, 118 savedStateHandle = handle, 119 ) 120 as T 121 } 122 } 123 124 private const val KEY_SAVED_STATE_IS_ON_LOCK_SCREEN = "is_on_lock_screen" 125 } 126 } 127