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.LayoutInflater 22 import android.view.View 23 import android.view.ViewGroup 24 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT 25 import androidx.constraintlayout.widget.ConstraintLayout 26 import androidx.constraintlayout.widget.ConstraintSet 27 import androidx.constraintlayout.widget.ConstraintSet.END 28 import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT 29 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID 30 import androidx.constraintlayout.widget.ConstraintSet.START 31 import androidx.constraintlayout.widget.ConstraintSet.TOP 32 import com.android.keyguard.KeyguardStatusView 33 import com.android.keyguard.dagger.KeyguardStatusViewComponent 34 import com.android.systemui.keyguard.KeyguardViewConfigurator 35 import com.android.systemui.keyguard.MigrateClocksToBlueprint 36 import com.android.systemui.keyguard.shared.model.KeyguardSection 37 import com.android.systemui.media.controls.ui.controller.KeyguardMediaController 38 import com.android.systemui.res.R 39 import com.android.systemui.shade.NotificationPanelView 40 import com.android.systemui.shade.NotificationPanelViewController 41 import com.android.systemui.statusbar.policy.SplitShadeStateController 42 import com.android.systemui.util.Utils 43 import dagger.Lazy 44 import javax.inject.Inject 45 import kotlinx.coroutines.ExperimentalCoroutinesApi 46 47 class DefaultStatusViewSection 48 @Inject 49 constructor( 50 private val context: Context, 51 private val notificationPanelView: NotificationPanelView, 52 private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory, 53 private val keyguardViewConfigurator: Lazy<KeyguardViewConfigurator>, 54 private val notificationPanelViewController: Lazy<NotificationPanelViewController>, 55 private val keyguardMediaController: KeyguardMediaController, 56 private val splitShadeStateController: SplitShadeStateController, 57 ) : KeyguardSection() { 58 private val statusViewId = R.id.keyguard_status_view 59 addViewsnull60 override fun addViews(constraintLayout: ConstraintLayout) { 61 if (!MigrateClocksToBlueprint.isEnabled) { 62 return 63 } 64 // At startup, 2 views with the ID `R.id.keyguard_status_view` will be available. 65 // Disable one of them 66 notificationPanelView.findViewById<View>(statusViewId)?.let { 67 notificationPanelView.removeView(it) 68 } 69 val keyguardStatusView = 70 (LayoutInflater.from(context) 71 .inflate(R.layout.keyguard_status_view, constraintLayout, false) 72 as KeyguardStatusView) 73 .apply { clipChildren = false } 74 75 // This is diassembled and moved to [AodNotificationIconsSection] 76 keyguardStatusView.findViewById<View>(R.id.left_aligned_notification_icon_container)?.let { 77 it.setVisibility(View.GONE) 78 } 79 // Should keep this even if flag, migrating clocks to blueprint, is on 80 // cause some events in clockEventController rely on keyguardStatusViewController 81 // TODO(b/313499340): clean up 82 constraintLayout.addView(keyguardStatusView) 83 } 84 bindDatanull85 override fun bindData(constraintLayout: ConstraintLayout) { 86 if (MigrateClocksToBlueprint.isEnabled) { 87 constraintLayout.findViewById<KeyguardStatusView?>(R.id.keyguard_status_view)?.let { 88 val statusViewComponent = 89 keyguardStatusViewComponentFactory.build(it, context.display) 90 val controller = statusViewComponent.keyguardStatusViewController 91 controller.init() 92 keyguardMediaController.attachSplitShadeContainer( 93 it.requireViewById<ViewGroup>(R.id.status_view_media_container) 94 ) 95 keyguardViewConfigurator.get().keyguardStatusViewController = controller 96 notificationPanelViewController.get().updateStatusViewController() 97 } 98 } 99 } 100 applyConstraintsnull101 override fun applyConstraints(constraintSet: ConstraintSet) { 102 constraintSet.apply { 103 constrainWidth(statusViewId, MATCH_CONSTRAINT) 104 constrainHeight(statusViewId, WRAP_CONTENT) 105 // TODO(b/296122465): Constrain to the top of [DefaultStatusBarSection] and remove the 106 // extra margin below. 107 connect(statusViewId, TOP, PARENT_ID, TOP) 108 connect(statusViewId, START, PARENT_ID, START) 109 connect(statusViewId, END, PARENT_ID, END) 110 111 val margin = 112 if (splitShadeStateController.shouldUseSplitNotificationShade(context.resources)) { 113 context.resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin) 114 } else { 115 context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) + 116 Utils.getStatusBarHeaderHeightKeyguard(context) 117 } 118 setMargin(statusViewId, TOP, margin) 119 } 120 } 121 122 @OptIn(ExperimentalCoroutinesApi::class) removeViewsnull123 override fun removeViews(constraintLayout: ConstraintLayout) { 124 constraintLayout.removeView(statusViewId) 125 keyguardViewConfigurator.get().keyguardStatusViewController = null 126 } 127 } 128