blob: 400d0dc2b242cd9b2d50de5bf1d4baa37e82eb29 [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard.ui.view.layout.sections
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.Barrier
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.TOP
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.shade.NotificationPanelView
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
abstract class NotificationStackScrollLayoutSection
constructor(
protected val context: Context,
private val sceneContainerFlags: SceneContainerFlags,
private val notificationPanelView: NotificationPanelView,
private val sharedNotificationContainer: SharedNotificationContainer,
private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
private val notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel,
private val ambientState: AmbientState,
private val controller: NotificationStackScrollLayoutController,
private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
private val mainDispatcher: CoroutineDispatcher,
) : KeyguardSection() {
private val placeHolderId = R.id.nssl_placeholder
private var disposableHandle: DisposableHandle? = null
/**
* Align the notification placeholder bottom to the top of either the lock icon or the ambient
* indication area, whichever is higher.
*/
protected fun addNotificationPlaceholderBarrier(constraintSet: ConstraintSet) {
val lockId =
if (DeviceEntryUdfpsRefactor.isEnabled) {
R.id.device_entry_icon_view
} else {
R.id.lock_icon_view
}
constraintSet.apply {
createBarrier(
R.id.nssl_placeholder_barrier_bottom,
Barrier.TOP,
0,
*intArrayOf(lockId, R.id.ambient_indication_container)
)
connect(R.id.nssl_placeholder, BOTTOM, R.id.nssl_placeholder_barrier_bottom, TOP)
}
}
override fun addViews(constraintLayout: ConstraintLayout) {
if (!KeyguardShadeMigrationNssl.isEnabled) {
return
}
// This moves the existing NSSL view to a different parent, as the controller is a
// singleton and recreating it has other bad side effects
notificationPanelView.findViewById<View?>(R.id.notification_stack_scroller)?.let {
(it.parent as ViewGroup).removeView(it)
sharedNotificationContainer.addNotificationStackScrollLayout(it)
}
val view = View(context, null).apply { id = placeHolderId }
constraintLayout.addView(view)
}
override fun bindData(constraintLayout: ConstraintLayout) {
if (!KeyguardShadeMigrationNssl.isEnabled) {
return
}
disposableHandle?.dispose()
disposableHandle =
SharedNotificationContainerBinder.bind(
sharedNotificationContainer,
sharedNotificationContainerViewModel,
sceneContainerFlags,
controller,
notificationStackSizeCalculator,
mainDispatcher,
)
if (sceneContainerFlags.flexiNotifsEnabled()) {
NotificationStackAppearanceViewBinder.bind(
context,
sharedNotificationContainer,
notificationStackAppearanceViewModel,
ambientState,
controller,
)
}
}
override fun removeViews(constraintLayout: ConstraintLayout) {
disposableHandle?.dispose()
constraintLayout.removeView(placeHolderId)
}
}