1 /* <lambda>null2 * Copyright (C) 2022 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 package com.android.keyguard 18 19 import android.animation.Animator 20 import android.animation.AnimatorListenerAdapter 21 import android.animation.AnimatorSet 22 import android.animation.ObjectAnimator 23 import android.content.Context 24 import android.content.res.ColorStateList 25 import android.util.AttributeSet 26 import android.view.View 27 import com.android.app.animation.Interpolators 28 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.TITLE 29 30 /** Displays security messages for the keyguard bouncer. */ 31 open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) : 32 KeyguardMessageArea(context, attrs) { 33 private val DEFAULT_COLOR = -1 34 private var mDefaultColorState: ColorStateList? = null 35 private var mNextMessageColorState: ColorStateList? = ColorStateList.valueOf(DEFAULT_COLOR) 36 private val animatorSet = AnimatorSet() 37 private var textAboutToShow: CharSequence? = null 38 protected open val SHOW_DURATION_MILLIS = 150L 39 protected open val HIDE_DURATION_MILLIS = 200L 40 41 override fun onFinishInflate() { 42 super.onFinishInflate() 43 mDefaultColorState = getColorInStyle() 44 } 45 46 private fun getColorInStyle(): ColorStateList? { 47 val styledAttributes = 48 context.obtainStyledAttributes(styleResId, intArrayOf(android.R.attr.textColor)) 49 var colorStateList: ColorStateList? = null 50 if (styledAttributes != null) { 51 colorStateList = styledAttributes.getColorStateList(0) 52 } 53 styledAttributes.recycle() 54 return colorStateList 55 } 56 57 override fun updateTextColor() { 58 var colorState = mDefaultColorState 59 mNextMessageColorState?.defaultColor?.let { color -> 60 if (color != DEFAULT_COLOR) { 61 colorState = mNextMessageColorState 62 mNextMessageColorState = mDefaultColorState ?: ColorStateList.valueOf(DEFAULT_COLOR) 63 } 64 } 65 setTextColor(colorState) 66 } 67 68 override fun setNextMessageColor(colorState: ColorStateList?) { 69 mNextMessageColorState = colorState 70 } 71 72 override fun onThemeChanged() { 73 mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE)) 74 super.onThemeChanged() 75 } 76 77 override fun reloadColor() { 78 mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE)) 79 super.reloadColor() 80 } 81 82 override fun setMessage(msg: CharSequence?, animate: Boolean) { 83 if ((msg == textAboutToShow && msg != null) || msg == text) { 84 return 85 } 86 87 if (!animate) { 88 super.setMessage(msg, animate) 89 return 90 } 91 92 textAboutToShow = msg 93 94 if (animatorSet.isRunning) { 95 animatorSet.cancel() 96 textAboutToShow = null 97 } 98 99 val hideAnimator = 100 ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f).apply { 101 duration = HIDE_DURATION_MILLIS 102 interpolator = Interpolators.STANDARD_ACCELERATE 103 } 104 105 hideAnimator.addListener( 106 object : AnimatorListenerAdapter() { 107 override fun onAnimationEnd(animation: Animator) { 108 super@BouncerKeyguardMessageArea.setMessage(msg, animate) 109 } 110 } 111 ) 112 val showAnimator = 113 ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f).apply { 114 duration = SHOW_DURATION_MILLIS 115 interpolator = Interpolators.STANDARD_DECELERATE 116 } 117 118 showAnimator.addListener( 119 object : AnimatorListenerAdapter() { 120 override fun onAnimationEnd(animation: Animator) { 121 textAboutToShow = null 122 } 123 } 124 ) 125 126 animatorSet.playSequentially(hideAnimator, showAnimator) 127 animatorSet.start() 128 } 129 } 130