1 /*
2  * Copyright (C) 2023 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.systemui.keyguard.ui.view.layout.sections
19 
20 import android.content.Context
21 import android.view.View
22 import android.view.View.GONE
23 import android.view.View.VISIBLE
24 import androidx.constraintlayout.widget.ConstraintLayout
25 import androidx.constraintlayout.widget.ConstraintSet
26 import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
27 import androidx.constraintlayout.widget.ConstraintSet.END
28 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
29 import androidx.constraintlayout.widget.ConstraintSet.START
30 import androidx.constraintlayout.widget.ConstraintSet.TOP
31 import com.android.systemui.common.ui.ConfigurationState
32 import com.android.systemui.keyguard.MigrateClocksToBlueprint
33 import com.android.systemui.keyguard.shared.model.KeyguardSection
34 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
35 import com.android.systemui.res.R
36 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore
37 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder
38 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarIconViewBindingFailureTracker
39 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
40 import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor
41 import com.android.systemui.statusbar.phone.NotificationIconAreaController
42 import com.android.systemui.statusbar.phone.NotificationIconContainer
43 import com.android.systemui.statusbar.ui.SystemBarUtilsState
44 import com.android.systemui.util.ui.value
45 import javax.inject.Inject
46 import kotlinx.coroutines.DisposableHandle
47 
48 class AodNotificationIconsSection
49 @Inject
50 constructor(
51     private val context: Context,
52     private val configurationState: ConfigurationState,
53     private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker,
54     private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
55     private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore,
56     private val notificationIconAreaController: NotificationIconAreaController,
57     private val systemBarUtilsState: SystemBarUtilsState,
58     private val rootViewModel: KeyguardRootViewModel,
59 ) : KeyguardSection() {
60 
61     private var nicBindingDisposable: DisposableHandle? = null
62     private val nicId = R.id.aod_notification_icon_container
63     private lateinit var nic: NotificationIconContainer
64 
addViewsnull65     override fun addViews(constraintLayout: ConstraintLayout) {
66         if (!MigrateClocksToBlueprint.isEnabled) {
67             return
68         }
69         nic =
70             NotificationIconContainer(context, null).apply {
71                 id = nicId
72                 setPaddingRelative(
73                     resources.getDimensionPixelSize(R.dimen.below_clock_padding_start_icons),
74                     0,
75                     0,
76                     0
77                 )
78                 setVisibility(View.INVISIBLE)
79             }
80 
81         constraintLayout.addView(nic)
82     }
83 
bindDatanull84     override fun bindData(constraintLayout: ConstraintLayout) {
85         if (!MigrateClocksToBlueprint.isEnabled) {
86             return
87         }
88 
89         if (NotificationIconContainerRefactor.isEnabled) {
90             nicBindingDisposable?.dispose()
91             nicBindingDisposable =
92                 NotificationIconContainerViewBinder.bindWhileAttached(
93                     nic,
94                     nicAodViewModel,
95                     configurationState,
96                     systemBarUtilsState,
97                     iconBindingFailureTracker,
98                     nicAodIconViewStore,
99                 )
100         } else {
101             notificationIconAreaController.setupAodIcons(nic)
102         }
103     }
104 
applyConstraintsnull105     override fun applyConstraints(constraintSet: ConstraintSet) {
106         if (!MigrateClocksToBlueprint.isEnabled) {
107             return
108         }
109 
110         val bottomMargin =
111             context.resources.getDimensionPixelSize(R.dimen.keyguard_status_view_bottom_margin)
112         val isVisible = rootViewModel.isNotifIconContainerVisible.value
113         constraintSet.apply {
114             connect(nicId, TOP, R.id.smart_space_barrier_bottom, BOTTOM, bottomMargin)
115             setGoneMargin(nicId, BOTTOM, bottomMargin)
116             setVisibility(nicId, if (isVisible.value) VISIBLE else GONE)
117 
118             connect(
119                 nicId,
120                 START,
121                 PARENT_ID,
122                 START,
123                 context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
124             )
125             connect(
126                 nicId,
127                 END,
128                 PARENT_ID,
129                 END,
130                 context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
131             )
132             constrainHeight(
133                 nicId,
134                 context.resources.getDimensionPixelSize(R.dimen.notification_shelf_height)
135             )
136         }
137     }
138 
removeViewsnull139     override fun removeViews(constraintLayout: ConstraintLayout) {
140         constraintLayout.removeView(nicId)
141         nicBindingDisposable?.dispose()
142     }
143 }
144