1 /* <lambda>null2 * Copyright (C) 2024 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 package com.android.wallpaper.picker.common.preview.ui.binder 18 19 import android.os.Bundle 20 import android.os.Message 21 import androidx.core.os.bundleOf 22 import com.android.customization.model.grid.DefaultShapeGridManager.Companion.COL_GRID_NAME 23 import com.android.customization.model.grid.DefaultShapeGridManager.Companion.COL_SHAPE_KEY 24 import com.android.customization.picker.clock.shared.ClockSize 25 import com.android.customization.picker.clock.ui.view.ClockViewFactory 26 import com.android.customization.picker.color.data.util.MaterialColorsGenerator 27 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END 28 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START 29 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.CLOCK_SIZE_DYNAMIC 30 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.CLOCK_SIZE_SMALL 31 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_CLOCK_SIZE 32 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE 33 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID 34 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_QUICK_AFFORDANCE_ID 35 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_SLOT_ID 36 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_DEFAULT_PREVIEW 37 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE 38 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_PREVIEW_CLOCK_SIZE 39 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED 40 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED 41 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES 42 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption 43 import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel 44 import com.android.wallpaper.model.Screen 45 import com.android.wallpaper.picker.common.preview.ui.binder.WorkspaceCallbackBinder.Companion.sendMessage 46 import com.android.wallpaper.picker.customization.ui.viewmodel.ColorUpdateViewModel 47 import com.android.wallpaper.picker.customization.ui.viewmodel.CustomizationOptionsViewModel 48 import javax.inject.Inject 49 import javax.inject.Singleton 50 import kotlinx.coroutines.coroutineScope 51 import kotlinx.coroutines.flow.combine 52 import kotlinx.coroutines.launch 53 54 @Singleton 55 class ThemePickerWorkspaceCallbackBinder 56 @Inject 57 constructor( 58 private val defaultWorkspaceCallbackBinder: DefaultWorkspaceCallbackBinder, 59 private val materialColorsGenerator: MaterialColorsGenerator, 60 ) : WorkspaceCallbackBinder { 61 62 override suspend fun bind( 63 workspaceCallback: Message, 64 viewModel: CustomizationOptionsViewModel, 65 colorUpdateViewModel: ColorUpdateViewModel, 66 screen: Screen, 67 clockViewFactory: ClockViewFactory, 68 ) { 69 defaultWorkspaceCallbackBinder.bind( 70 workspaceCallback = workspaceCallback, 71 viewModel = viewModel, 72 colorUpdateViewModel = colorUpdateViewModel, 73 screen = screen, 74 clockViewFactory = clockViewFactory, 75 ) 76 77 if (viewModel !is ThemePickerCustomizationOptionsViewModel) { 78 throw IllegalArgumentException( 79 "viewModel $viewModel is not a ThemePickerCustomizationOptionsViewModel." 80 ) 81 } 82 83 when (screen) { 84 Screen.LOCK_SCREEN -> 85 coroutineScope { 86 launch { 87 viewModel.selectedOption.collect { 88 when (it) { 89 ThemePickerLockCustomizationOption.SHORTCUTS -> 90 workspaceCallback.sendMessage( 91 MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES, 92 Bundle().apply { 93 putString( 94 KEY_INITIALLY_SELECTED_SLOT_ID, 95 SLOT_ID_BOTTOM_START, 96 ) 97 }, 98 ) 99 else -> 100 workspaceCallback.sendMessage( 101 MESSAGE_ID_DEFAULT_PREVIEW, 102 Bundle.EMPTY, 103 ) 104 } 105 } 106 } 107 108 launch { 109 viewModel.keyguardQuickAffordancePickerViewModel2.selectedSlotId.collect { 110 workspaceCallback.sendMessage( 111 MESSAGE_ID_SLOT_SELECTED, 112 Bundle().apply { putString(KEY_SLOT_ID, it) }, 113 ) 114 } 115 } 116 117 launch { 118 viewModel.keyguardQuickAffordancePickerViewModel2.previewingQuickAffordances 119 .collect { 120 it[SLOT_ID_BOTTOM_START]?.let { 121 workspaceCallback.sendMessage( 122 MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED, 123 Bundle().apply { 124 putString(KEY_SLOT_ID, SLOT_ID_BOTTOM_START) 125 putString(KEY_QUICK_AFFORDANCE_ID, it) 126 }, 127 ) 128 } 129 it[SLOT_ID_BOTTOM_END]?.let { 130 workspaceCallback.sendMessage( 131 MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED, 132 Bundle().apply { 133 putString(KEY_SLOT_ID, SLOT_ID_BOTTOM_END) 134 putString(KEY_QUICK_AFFORDANCE_ID, it) 135 }, 136 ) 137 } 138 } 139 } 140 141 launch { 142 combine( 143 viewModel.clockPickerViewModel.previewingClock, 144 viewModel.clockPickerViewModel.previewingClockSize, 145 ::Pair, 146 ) 147 .collect { (previewingClock, previewingClockSize) -> 148 val hideSmartspace = 149 clockViewFactory.getController(previewingClock.clockId)?.let { 150 when (previewingClockSize) { 151 ClockSize.DYNAMIC -> 152 it.largeClock.config.hasCustomWeatherDataDisplay 153 ClockSize.SMALL -> 154 it.smallClock.config.hasCustomWeatherDataDisplay 155 } 156 } ?: false 157 workspaceCallback.sendMessage( 158 MESSAGE_ID_HIDE_SMART_SPACE, 159 Bundle().apply { 160 putBoolean(KEY_HIDE_SMART_SPACE, hideSmartspace) 161 }, 162 ) 163 164 workspaceCallback.sendMessage( 165 MESSAGE_ID_PREVIEW_CLOCK_SIZE, 166 Bundle().apply { 167 putString( 168 KEY_CLOCK_SIZE, 169 when (previewingClockSize) { 170 ClockSize.DYNAMIC -> CLOCK_SIZE_DYNAMIC 171 ClockSize.SMALL -> CLOCK_SIZE_SMALL 172 }, 173 ) 174 }, 175 ) 176 } 177 } 178 } 179 Screen.HOME_SCREEN -> 180 coroutineScope { 181 launch { 182 viewModel.shapeGridPickerViewModel.previewingShapeKey.collect { 183 workspaceCallback.sendMessage( 184 MESSAGE_ID_UPDATE_SHAPE, 185 bundleOf(COL_SHAPE_KEY to it), 186 ) 187 } 188 } 189 190 launch { 191 viewModel.shapeGridPickerViewModel.previewingGridKey.collect { 192 workspaceCallback.sendMessage( 193 MESSAGE_ID_UPDATE_GRID, 194 bundleOf(COL_GRID_NAME to it), 195 ) 196 } 197 } 198 199 launch { 200 combine( 201 viewModel.colorPickerViewModel2.previewingColorOption, 202 viewModel.darkModeViewModel.overridingIsDarkMode, 203 ::Pair, 204 ) 205 .collect { (colorOption, darkMode) -> 206 val bundle = 207 Bundle().apply { 208 if (colorOption != null) { 209 val (ids, colors) = 210 materialColorsGenerator.generate( 211 colorOption.seedColor, 212 colorOption.style, 213 ) 214 putIntArray(KEY_COLOR_RESOURCE_IDS, ids) 215 putIntArray(KEY_COLOR_VALUES, colors) 216 } 217 218 if (darkMode != null) { 219 putBoolean(KEY_DARK_MODE, darkMode) 220 } 221 } 222 workspaceCallback.sendMessage(MESSAGE_ID_UPDATE_COLOR, bundle) 223 } 224 } 225 226 launch { 227 viewModel.themedIconViewModel.isActivated.collect { 228 workspaceCallback.sendMessage(MESSAGE_ID_UPDATE_COLOR, Bundle.EMPTY) 229 } 230 } 231 232 launch { 233 viewModel.appIconPickerViewModel.previewingIsThemeIconEnabled.collect { 234 workspaceCallback.sendMessage( 235 MESSAGE_ID_UPDATE_ICON_THEMED, 236 Bundle().apply { putBoolean(KEY_BOOLEAN_VALUE, it) }, 237 ) 238 } 239 } 240 } 241 } 242 } 243 244 companion object { 245 const val MESSAGE_ID_UPDATE_SHAPE = 2586 246 const val MESSAGE_ID_UPDATE_GRID = 7414 247 const val MESSAGE_ID_UPDATE_COLOR = 856 248 const val MESSAGE_ID_UPDATE_ICON_THEMED = 311 249 const val KEY_COLOR_RESOURCE_IDS: String = "color_resource_ids" 250 const val KEY_COLOR_VALUES: String = "color_values" 251 const val KEY_DARK_MODE: String = "use_dark_mode" 252 const val KEY_BOOLEAN_VALUE: String = "boolean_value" 253 } 254 } 255