• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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