• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.systemui.qs.tiles.impl.uimodenight.ui.mapper
18 
19 import android.app.UiModeManager
20 import android.content.res.Resources
21 import android.content.res.Resources.Theme
22 import android.text.TextUtils
23 import com.android.systemui.common.shared.model.Icon
24 import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
25 import com.android.systemui.qs.tiles.base.shared.model.QSTileState
26 import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
27 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
28 import com.android.systemui.res.R
29 import com.android.systemui.shade.ShadeDisplayAware
30 import java.time.LocalTime
31 import java.time.format.DateTimeFormatter
32 import javax.inject.Inject
33 
34 /** Maps [UiModeNightTileModel] to [QSTileState]. */
35 class UiModeNightTileMapper
36 @Inject
37 constructor(@ShadeDisplayAware private val resources: Resources, private val theme: Theme) :
38     QSTileDataToStateMapper<UiModeNightTileModel> {
39     companion object {
40         val formatter12Hour: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a")
41         val formatter24Hour: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm")
42     }
43 
mapnull44     override fun map(config: QSTileConfig, data: UiModeNightTileModel): QSTileState =
45         with(data) {
46             QSTileState.build(resources, theme, config.uiConfig) {
47                 var shouldSetSecondaryLabel = false
48 
49                 if (isPowerSave) {
50                     secondaryLabel =
51                         resources.getString(
52                             R.string.quick_settings_dark_mode_secondary_label_battery_saver
53                         )
54                 } else if (uiMode == UiModeManager.MODE_NIGHT_AUTO && isLocationEnabled) {
55                     secondaryLabel =
56                         resources.getString(
57                             if (isNightMode)
58                                 R.string.quick_settings_dark_mode_secondary_label_until_sunrise
59                             else R.string.quick_settings_dark_mode_secondary_label_on_at_sunset
60                         )
61                 } else if (uiMode == UiModeManager.MODE_NIGHT_CUSTOM) {
62                     if (nightModeCustomType == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_SCHEDULE) {
63                         val time: LocalTime =
64                             if (isNightMode) {
65                                 customNightModeEnd
66                             } else {
67                                 customNightModeStart
68                             }
69 
70                         val formatter: DateTimeFormatter =
71                             if (is24HourFormat) formatter24Hour else formatter12Hour
72 
73                         secondaryLabel =
74                             resources.getString(
75                                 if (isNightMode)
76                                     R.string.quick_settings_dark_mode_secondary_label_until
77                                 else R.string.quick_settings_dark_mode_secondary_label_on_at,
78                                 formatter.format(time),
79                             )
80                     } else if (
81                         nightModeCustomType == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME
82                     ) {
83                         secondaryLabel =
84                             resources.getString(
85                                 if (isNightMode)
86                                     R.string
87                                         .quick_settings_dark_mode_secondary_label_until_bedtime_ends
88                                 else R.string.quick_settings_dark_mode_secondary_label_on_at_bedtime
89                             )
90                     } else {
91                         secondaryLabel = null // undefined type of nightModeCustomType
92                         shouldSetSecondaryLabel = true
93                     }
94                 } else {
95                     secondaryLabel = null
96                     shouldSetSecondaryLabel = true
97                 }
98 
99                 contentDescription =
100                     if (TextUtils.isEmpty(secondaryLabel)) label
101                     else TextUtils.concat(label, ", ", secondaryLabel)
102                 if (isPowerSave) {
103                     activationState = QSTileState.ActivationState.UNAVAILABLE
104                     if (shouldSetSecondaryLabel)
105                         secondaryLabel = resources.getStringArray(R.array.tile_states_dark)[0]
106                 } else {
107                     activationState =
108                         if (isNightMode) QSTileState.ActivationState.ACTIVE
109                         else QSTileState.ActivationState.INACTIVE
110 
111                     if (shouldSetSecondaryLabel) {
112                         secondaryLabel =
113                             if (activationState == QSTileState.ActivationState.INACTIVE)
114                                 resources.getStringArray(R.array.tile_states_dark)[1]
115                             else resources.getStringArray(R.array.tile_states_dark)[2]
116                     }
117                 }
118 
119                 val iconRes =
120                     if (activationState == QSTileState.ActivationState.ACTIVE)
121                         R.drawable.qs_light_dark_theme_icon_on
122                     else R.drawable.qs_light_dark_theme_icon_off
123                 icon = Icon.Loaded(resources.getDrawable(iconRes, theme), null, iconRes)
124 
125                 supportedActions =
126                     if (activationState == QSTileState.ActivationState.UNAVAILABLE)
127                         setOf(QSTileState.UserAction.LONG_CLICK)
128                     else setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
129             }
130         }
131 }
132