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.customization.R as customR 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.shade.ShadeDisplayAware 37 import com.android.systemui.shade.domain.interactor.ShadeModeInteractor 38 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore 39 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder 40 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarIconViewBindingFailureTracker 41 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel 42 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi 43 import com.android.systemui.statusbar.phone.NotificationIconContainer 44 import com.android.systemui.statusbar.ui.SystemBarUtilsState 45 import com.android.systemui.util.ui.value 46 import javax.inject.Inject 47 import kotlinx.coroutines.DisposableHandle 48 49 class AodNotificationIconsSection 50 @Inject 51 constructor( 52 @ShadeDisplayAware private val context: Context, 53 @ShadeDisplayAware private val configurationState: ConfigurationState, 54 private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker, 55 private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, 56 private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore, 57 private val systemBarUtilsState: SystemBarUtilsState, 58 private val rootViewModel: KeyguardRootViewModel, 59 private val shadeModeInteractor: ShadeModeInteractor, 60 ) : KeyguardSection() { 61 62 private var nicBindingDisposable: DisposableHandle? = null 63 private val nicId = R.id.aod_notification_icon_container 64 private lateinit var nic: NotificationIconContainer 65 addViewsnull66 override fun addViews(constraintLayout: ConstraintLayout) { 67 nic = 68 NotificationIconContainer(context, null).apply { 69 id = nicId 70 setPaddingRelative( 71 resources.getDimensionPixelSize(R.dimen.below_clock_padding_start_icons), 72 0, 73 0, 74 0, 75 ) 76 setVisibility(View.INVISIBLE) 77 } 78 79 constraintLayout.addView(nic) 80 } 81 bindDatanull82 override fun bindData(constraintLayout: ConstraintLayout) { 83 nicBindingDisposable?.dispose() 84 nicBindingDisposable = 85 NotificationIconContainerViewBinder.bindWhileAttached( 86 nic, 87 nicAodViewModel, 88 configurationState, 89 systemBarUtilsState, 90 iconBindingFailureTracker, 91 nicAodIconViewStore, 92 ) 93 } 94 applyConstraintsnull95 override fun applyConstraints(constraintSet: ConstraintSet) { 96 val bottomMargin = 97 context.resources.getDimensionPixelSize(R.dimen.keyguard_status_view_bottom_margin) 98 val horizontalMargin = 99 context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal) 100 val height = context.resources.getDimensionPixelSize(R.dimen.notification_shelf_height) 101 val isVisible = rootViewModel.isNotifIconContainerVisible.value 102 val isShadeLayoutWide = shadeModeInteractor.isShadeLayoutWide.value 103 104 constraintSet.apply { 105 if (PromotedNotificationUi.isEnabled) { 106 connect(nicId, TOP, AodPromotedNotificationSection.viewId, BOTTOM, bottomMargin) 107 } else { 108 connect(nicId, TOP, R.id.smart_space_barrier_bottom, BOTTOM, bottomMargin) 109 } 110 111 setGoneMargin(nicId, BOTTOM, bottomMargin) 112 setVisibility(nicId, if (isVisible.value) VISIBLE else GONE) 113 114 if (PromotedNotificationUi.isEnabled && isShadeLayoutWide) { 115 // Don't create a start constraint, so the icons can hopefully right-align. 116 } else { 117 connect(nicId, START, PARENT_ID, START, horizontalMargin) 118 } 119 connect(nicId, END, PARENT_ID, END, horizontalMargin) 120 121 constrainHeight(nicId, height) 122 } 123 } 124 removeViewsnull125 override fun removeViews(constraintLayout: ConstraintLayout) { 126 constraintLayout.removeView(nicId) 127 nicBindingDisposable?.dispose() 128 } 129 } 130