• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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.customization.ui.util
18 
19 import android.content.Context
20 import android.view.LayoutInflater
21 import android.view.View
22 import android.view.ViewGroup
23 import android.widget.FrameLayout
24 import android.widget.LinearLayout
25 import androidx.compose.ui.platform.ComposeView
26 import com.android.customization.picker.mode.shared.util.DarkModeLifecycleUtil
27 import com.android.themepicker.R
28 import com.android.wallpaper.config.BaseFlags
29 import com.android.wallpaper.customization.ui.compose.ColorFloatingSheet
30 import com.android.wallpaper.model.Screen
31 import com.android.wallpaper.model.Screen.HOME_SCREEN
32 import com.android.wallpaper.model.Screen.LOCK_SCREEN
33 import com.android.wallpaper.picker.customization.ui.util.CustomizationOptionUtil
34 import com.android.wallpaper.picker.customization.ui.util.DefaultCustomizationOptionUtil
35 import dagger.hilt.android.qualifiers.ActivityContext
36 import dagger.hilt.android.scopes.ActivityScoped
37 import javax.inject.Inject
38 
39 @ActivityScoped
40 class ThemePickerCustomizationOptionUtil
41 @Inject
42 constructor(
43     private val defaultCustomizationOptionUtil: DefaultCustomizationOptionUtil,
44     @ActivityContext private val context: Context,
45 ) : CustomizationOptionUtil {
46 
47     // Instantiate DarkModeLifecycleUtil for it to observe lifecycle and update DarkModeRepository
48     @Inject lateinit var darkModeLifecycleUtil: DarkModeLifecycleUtil
49 
50     enum class ThemePickerLockCustomizationOption : CustomizationOptionUtil.CustomizationOption {
51         CLOCK,
52         SHORTCUTS,
53         LOCK_SCREEN_NOTIFICATIONS,
54         MORE_LOCK_SCREEN_SETTINGS,
55     }
56 
57     enum class ThemePickerHomeCustomizationOption : CustomizationOptionUtil.CustomizationOption {
58         PACK_THEME,
59         COLORS,
60         THEMED_ICONS,
61         APP_SHAPE_GRID,
62         COLOR_CONTRAST,
63     }
64 
getOptionEntriesnull65     override fun getOptionEntries(
66         screen: Screen,
67         optionContainer: LinearLayout,
68         layoutInflater: LayoutInflater,
69     ): List<Pair<CustomizationOptionUtil.CustomizationOption, View>> {
70         val defaultOptionEntries =
71             defaultCustomizationOptionUtil.getOptionEntries(screen, optionContainer, layoutInflater)
72         return when (screen) {
73             LOCK_SCREEN ->
74                 buildList {
75                     addAll(defaultOptionEntries)
76                     if (BaseFlags.get().isPackThemeEnabled()) {
77                         add(
78                             ThemePickerHomeCustomizationOption.PACK_THEME to
79                                 layoutInflater.inflate(
80                                     R.layout.customization_option_entry_pack_theme,
81                                     optionContainer,
82                                     false,
83                                 )
84                         )
85                     }
86                     add(
87                         ThemePickerLockCustomizationOption.CLOCK to
88                             layoutInflater.inflate(
89                                 R.layout.customization_option_entry_clock,
90                                 optionContainer,
91                                 false,
92                             )
93                     )
94                     add(
95                         ThemePickerLockCustomizationOption.SHORTCUTS to
96                             layoutInflater.inflate(
97                                 R.layout.customization_option_entry_keyguard_quick_affordance,
98                                 optionContainer,
99                                 false,
100                             )
101                     )
102                     add(
103                         ThemePickerLockCustomizationOption.LOCK_SCREEN_NOTIFICATIONS to
104                             layoutInflater.inflate(
105                                 R.layout.customization_option_entry_lock_screen_notifications,
106                                 optionContainer,
107                                 false,
108                             )
109                     )
110                     add(
111                         ThemePickerLockCustomizationOption.MORE_LOCK_SCREEN_SETTINGS to
112                             layoutInflater.inflate(
113                                 R.layout.customization_option_entry_more_lock_settings,
114                                 optionContainer,
115                                 false,
116                             )
117                     )
118                 }
119             HOME_SCREEN ->
120                 buildList {
121                     addAll(defaultOptionEntries)
122                     if (BaseFlags.get().isPackThemeEnabled()) {
123                         add(
124                             ThemePickerHomeCustomizationOption.PACK_THEME to
125                                 layoutInflater.inflate(
126                                     R.layout.customization_option_entry_pack_theme,
127                                     optionContainer,
128                                     false,
129                                 )
130                         )
131                     }
132                     add(
133                         ThemePickerHomeCustomizationOption.COLORS to
134                             layoutInflater.inflate(
135                                 R.layout.customization_option_entry_colors,
136                                 optionContainer,
137                                 false,
138                             )
139                     )
140                     add(
141                         ThemePickerHomeCustomizationOption.THEMED_ICONS to
142                             layoutInflater.inflate(
143                                 R.layout.customization_option_entry_themed_icons,
144                                 optionContainer,
145                                 false,
146                             )
147                     )
148                     add(
149                         ThemePickerHomeCustomizationOption.APP_SHAPE_GRID to
150                             layoutInflater.inflate(
151                                 R.layout.customization_option_entry_app_shape_grid,
152                                 optionContainer,
153                                 false,
154                             )
155                     )
156                     add(
157                         ThemePickerHomeCustomizationOption.COLOR_CONTRAST to
158                             layoutInflater.inflate(
159                                 R.layout.customization_option_entry_color_contrast,
160                                 optionContainer,
161                                 false,
162                             )
163                     )
164                 }
165         }
166     }
167 
initFloatingSheetnull168     override fun initFloatingSheet(
169         bottomSheetContainer: FrameLayout,
170         layoutInflater: LayoutInflater,
171     ): Map<CustomizationOptionUtil.CustomizationOption, View> {
172         val map =
173             defaultCustomizationOptionUtil.initFloatingSheet(bottomSheetContainer, layoutInflater)
174         val isComposeRefactorEnabled = BaseFlags.get().isComposeRefactorEnabled()
175         return buildMap {
176             putAll(map)
177             put(
178                 ThemePickerLockCustomizationOption.CLOCK,
179                 inflateFloatingSheet(
180                         ThemePickerLockCustomizationOption.CLOCK,
181                         bottomSheetContainer,
182                         layoutInflater,
183                     )
184                     .also { bottomSheetContainer.addView(it) },
185             )
186             put(
187                 ThemePickerLockCustomizationOption.SHORTCUTS,
188                 inflateFloatingSheet(
189                         ThemePickerLockCustomizationOption.SHORTCUTS,
190                         bottomSheetContainer,
191                         layoutInflater,
192                     )
193                     .also { bottomSheetContainer.addView(it) },
194             )
195             put(
196                 ThemePickerHomeCustomizationOption.COLORS,
197                 if (isComposeRefactorEnabled) {
198                         ComposeView(context).apply { setContent { ColorFloatingSheet() } }
199                     } else {
200                         inflateFloatingSheet(
201                             ThemePickerHomeCustomizationOption.COLORS,
202                             bottomSheetContainer,
203                             layoutInflater,
204                         )
205                     }
206                     .also { bottomSheetContainer.addView(it) },
207             )
208             put(
209                 ThemePickerHomeCustomizationOption.APP_SHAPE_GRID,
210                 inflateFloatingSheet(
211                         ThemePickerHomeCustomizationOption.APP_SHAPE_GRID,
212                         bottomSheetContainer,
213                         layoutInflater,
214                     )
215                     .also { bottomSheetContainer.addView(it) },
216             )
217         }
218     }
219 
createClockPreviewAndAddToParentnull220     override fun createClockPreviewAndAddToParent(
221         parentView: ViewGroup,
222         layoutInflater: LayoutInflater,
223     ): View? {
224         val clockHostView = layoutInflater.inflate(R.layout.clock_host_view, parentView, false)
225         parentView.addView(clockHostView)
226         return clockHostView
227     }
228 
inflateFloatingSheetnull229     private fun inflateFloatingSheet(
230         option: CustomizationOptionUtil.CustomizationOption,
231         bottomSheetContainer: FrameLayout,
232         layoutInflater: LayoutInflater,
233     ): View =
234         when (option) {
235             ThemePickerLockCustomizationOption.CLOCK -> R.layout.floating_sheet_clock
236             ThemePickerLockCustomizationOption.SHORTCUTS -> R.layout.floating_sheet_shortcut
237             ThemePickerHomeCustomizationOption.COLORS -> R.layout.floating_sheet_colors
238             ThemePickerHomeCustomizationOption.APP_SHAPE_GRID -> R.layout.floating_sheet_shape_grid
239             else ->
240                 throw IllegalStateException(
241                     "Customization option $option does not have a bottom sheet view"
242                 )
243         }.let { layoutInflater.inflate(it, bottomSheetContainer, false) }
244 }
245