1 /* 2 * Copyright (C) 2014 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 package com.android.systemui.statusbar.phone 17 18 import android.content.Context 19 import android.content.res.Configuration 20 import android.util.AttributeSet 21 import android.view.View 22 import android.view.ViewGroup 23 import android.view.ViewPropertyAnimator 24 import android.view.WindowInsets 25 import android.widget.FrameLayout 26 import androidx.annotation.StringRes 27 import com.android.keyguard.LockIconViewController 28 import com.android.systemui.R 29 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder 30 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind 31 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel 32 import com.android.systemui.plugins.ActivityStarter 33 import com.android.systemui.plugins.FalsingManager 34 import com.android.systemui.statusbar.VibratorHelper 35 import com.android.systemui.util.animation.requiresRemeasuring 36 37 /** 38 * Renders the bottom area of the lock-screen. Concerned primarily with the quick affordance UI 39 * elements. A secondary concern is the interaction of the quick affordance elements with the 40 * indication area between them, though the indication area is primarily controlled elsewhere. 41 */ 42 @Deprecated("Deprecated as part of b/278057014") 43 class KeyguardBottomAreaView 44 @JvmOverloads 45 constructor( 46 context: Context, 47 attrs: AttributeSet? = null, 48 defStyleAttr: Int = 0, 49 defStyleRes: Int = 0, 50 ) : 51 FrameLayout( 52 context, 53 attrs, 54 defStyleAttr, 55 defStyleRes, 56 ) { 57 58 @Deprecated("Deprecated as part of b/278057014") 59 interface MessageDisplayer { 60 fun display(@StringRes stringResourceId: Int) 61 } 62 63 private var ambientIndicationArea: View? = null 64 private var binding: KeyguardBottomAreaViewBinder.Binding? = null 65 private var lockIconViewController: LockIconViewController? = null 66 67 /** Initializes the view. */ 68 @Deprecated("Deprecated as part of b/278057014") 69 fun init( 70 viewModel: KeyguardBottomAreaViewModel, 71 falsingManager: FalsingManager? = null, 72 lockIconViewController: LockIconViewController? = null, 73 messageDisplayer: MessageDisplayer? = null, 74 vibratorHelper: VibratorHelper? = null, 75 activityStarter: ActivityStarter? = null, 76 ) { 77 binding?.destroy() 78 binding = 79 bind( 80 this, 81 viewModel, 82 falsingManager, 83 vibratorHelper, 84 activityStarter, 85 ) { 86 messageDisplayer?.display(it) 87 } 88 this.lockIconViewController = lockIconViewController 89 } 90 91 /** 92 * Initializes this instance of [KeyguardBottomAreaView] based on the given instance of another 93 * [KeyguardBottomAreaView] 94 */ 95 @Deprecated("Deprecated as part of b/278057014") 96 fun initFrom(oldBottomArea: KeyguardBottomAreaView) { 97 // if it exists, continue to use the original ambient indication container 98 // instead of the newly inflated one 99 ambientIndicationArea?.let { nonNullAmbientIndicationArea -> 100 // remove old ambient indication from its parent 101 val originalAmbientIndicationView = 102 oldBottomArea.requireViewById<View>(R.id.ambient_indication_container) 103 (originalAmbientIndicationView.parent as ViewGroup).removeView( 104 originalAmbientIndicationView 105 ) 106 107 // remove current ambient indication from its parent (discard) 108 val ambientIndicationParent = nonNullAmbientIndicationArea.parent as ViewGroup 109 val ambientIndicationIndex = 110 ambientIndicationParent.indexOfChild(nonNullAmbientIndicationArea) 111 ambientIndicationParent.removeView(nonNullAmbientIndicationArea) 112 113 // add the old ambient indication to this view 114 ambientIndicationParent.addView(originalAmbientIndicationView, ambientIndicationIndex) 115 ambientIndicationArea = originalAmbientIndicationView 116 } 117 } 118 119 override fun onFinishInflate() { 120 super.onFinishInflate() 121 ambientIndicationArea = findViewById(R.id.ambient_indication_container) 122 } 123 124 override fun onConfigurationChanged(newConfig: Configuration) { 125 super.onConfigurationChanged(newConfig) 126 binding?.onConfigurationChanged() 127 } 128 129 /** Returns a list of animators to use to animate the indication areas. */ 130 @Deprecated("Deprecated as part of b/278057014") 131 val indicationAreaAnimators: List<ViewPropertyAnimator> 132 get() = checkNotNull(binding).getIndicationAreaAnimators() 133 134 135 override fun hasOverlappingRendering(): Boolean { 136 return false 137 } 138 139 override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { 140 val bottom = insets.displayCutout?.safeInsetBottom ?: 0 141 if (isPaddingRelative) { 142 setPaddingRelative(paddingStart, paddingTop, paddingEnd, bottom) 143 } else { 144 setPadding(paddingLeft, paddingTop, paddingRight, bottom) 145 } 146 return insets 147 } 148 149 override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { 150 super.onLayout(changed, left, top, right, bottom) 151 findViewById<View>(R.id.ambient_indication_container)?.let { 152 val (ambientLeft, ambientTop) = it.locationOnScreen 153 if (binding?.shouldConstrainToTopOfLockIcon() == true) { 154 // make top of ambient indication view the bottom of the lock icon 155 it.layout( 156 ambientLeft, 157 lockIconViewController?.bottom?.toInt() ?: 0, 158 right - ambientLeft, 159 ambientTop + it.measuredHeight 160 ) 161 } else { 162 // make bottom of ambient indication view the top of the lock icon 163 val lockLocationTop = lockIconViewController?.top ?: 0 164 it.layout( 165 ambientLeft, 166 lockLocationTop.toInt() - it.measuredHeight, 167 right - ambientLeft, 168 lockLocationTop.toInt() 169 ) 170 } 171 } 172 } 173 } 174