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