1 package com.android.systemui.biometrics.ui
2
3 import android.content.Context
4 import android.content.res.Configuration.ORIENTATION_LANDSCAPE
5 import android.graphics.Insets
6 import android.text.TextUtils
7 import android.util.AttributeSet
8 import android.view.View
9 import android.view.WindowInsets
10 import android.view.accessibility.AccessibilityManager
11 import android.widget.LinearLayout
12 import android.widget.TextView
13 import com.android.systemui.biometrics.AuthPanelController
14 import com.android.systemui.biometrics.plugins.AuthContextPlugins
15 import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
16 import com.android.systemui.biometrics.ui.binder.Spaghetti
17 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
18 import com.android.systemui.res.R
19
20 /** PIN or password credential view for BiometricPrompt. */
21 class CredentialPasswordView(context: Context, attrs: AttributeSet?) :
22 LinearLayout(context, attrs), CredentialView, View.OnApplyWindowInsetsListener {
23
24 private var bottomInset: Int = 0
25
<lambda>null26 private val accessibilityManager by lazy {
27 context.getSystemService(AccessibilityManager::class.java)
28 }
29
30 /** Initializes the view. */
initnull31 override fun init(
32 viewModel: CredentialViewModel,
33 host: CredentialView.Host,
34 panelViewController: AuthPanelController,
35 animatePanel: Boolean,
36 legacyCallback: Spaghetti.Callback,
37 plugins: AuthContextPlugins?,
38 ) {
39 CredentialViewBinder.bind(
40 this,
41 host,
42 viewModel,
43 panelViewController,
44 animatePanel,
45 legacyCallback,
46 plugins,
47 )
48 }
49
onFinishInflatenull50 override fun onFinishInflate() {
51 super.onFinishInflate()
52 setOnApplyWindowInsetsListener(this)
53 }
54
onApplyWindowInsetsnull55 override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
56 val statusBarInsets: Insets = insets.getInsets(WindowInsets.Type.statusBars())
57 val keyboardInsets: Insets = insets.getInsets(WindowInsets.Type.ime())
58 val navigationInsets: Insets = insets.getInsets(WindowInsets.Type.navigationBars())
59 val imeBottomInset = keyboardInsets.bottom
60 if (bottomInset != imeBottomInset) {
61 val titleView: TextView? = findViewById(R.id.title)
62 if (titleView != null) {
63 if (
64 bottomInset > 0 && resources.configuration.orientation == ORIENTATION_LANDSCAPE
65 ) {
66 titleView.isSingleLine = true
67 titleView.ellipsize = TextUtils.TruncateAt.MARQUEE
68 titleView.marqueeRepeatLimit = -1
69 // select to enable marquee unless a screen reader is enabled
70 titleView.isSelected = accessibilityManager?.shouldMarquee() ?: false
71 } else {
72 titleView.isSingleLine = false
73 titleView.ellipsize = null
74 // select to enable marquee unless a screen reader is enabled
75 titleView.isSelected = false
76 }
77 }
78 }
79
80 setPadding(
81 0,
82 statusBarInsets.top,
83 0,
84 if (keyboardInsets.bottom == 0) navigationInsets.bottom else keyboardInsets.bottom,
85 )
86 return WindowInsets.CONSUMED
87 }
88 }
89
AccessibilityManagernull90 private fun AccessibilityManager.shouldMarquee(): Boolean = !isEnabled || !isTouchExplorationEnabled
91