1 /*
2 * Copyright (C) 2023 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.systemui.bouncer.data.factory
18
19 import android.annotation.IntDef
20 import com.android.keyguard.KeyguardSecurityModel
21 import com.android.keyguard.KeyguardSecurityModel.SecurityMode
22 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT
23 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
24 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN
25 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FACE_LOCKED_OUT
26 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FINGERPRINT_LOCKED_OUT
27 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FACE_INPUT
28 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
29 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
30 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE
31 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
32 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE
33 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT
34 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART
35 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE
36 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT
37 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED
38 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST
39 import com.android.systemui.R.string.bouncer_face_not_recognized
40 import com.android.systemui.R.string.keyguard_enter_password
41 import com.android.systemui.R.string.keyguard_enter_pattern
42 import com.android.systemui.R.string.keyguard_enter_pin
43 import com.android.systemui.R.string.kg_bio_too_many_attempts_password
44 import com.android.systemui.R.string.kg_bio_too_many_attempts_pattern
45 import com.android.systemui.R.string.kg_bio_too_many_attempts_pin
46 import com.android.systemui.R.string.kg_bio_try_again_or_password
47 import com.android.systemui.R.string.kg_bio_try_again_or_pattern
48 import com.android.systemui.R.string.kg_bio_try_again_or_pin
49 import com.android.systemui.R.string.kg_face_locked_out
50 import com.android.systemui.R.string.kg_fp_locked_out
51 import com.android.systemui.R.string.kg_fp_not_recognized
52 import com.android.systemui.R.string.kg_primary_auth_locked_out_password
53 import com.android.systemui.R.string.kg_primary_auth_locked_out_pattern
54 import com.android.systemui.R.string.kg_primary_auth_locked_out_pin
55 import com.android.systemui.R.string.kg_prompt_after_dpm_lock
56 import com.android.systemui.R.string.kg_prompt_after_update_password
57 import com.android.systemui.R.string.kg_prompt_after_update_pattern
58 import com.android.systemui.R.string.kg_prompt_after_update_pin
59 import com.android.systemui.R.string.kg_prompt_after_user_lockdown_password
60 import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pattern
61 import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin
62 import com.android.systemui.R.string.kg_prompt_auth_timeout
63 import com.android.systemui.R.string.kg_prompt_password_auth_timeout
64 import com.android.systemui.R.string.kg_prompt_pattern_auth_timeout
65 import com.android.systemui.R.string.kg_prompt_pin_auth_timeout
66 import com.android.systemui.R.string.kg_prompt_reason_restart_password
67 import com.android.systemui.R.string.kg_prompt_reason_restart_pattern
68 import com.android.systemui.R.string.kg_prompt_reason_restart_pin
69 import com.android.systemui.R.string.kg_prompt_unattended_update
70 import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown
71 import com.android.systemui.R.string.kg_trust_agent_disabled
72 import com.android.systemui.R.string.kg_unlock_with_password_or_fp
73 import com.android.systemui.R.string.kg_unlock_with_pattern_or_fp
74 import com.android.systemui.R.string.kg_unlock_with_pin_or_fp
75 import com.android.systemui.R.string.kg_wrong_input_try_fp_suggestion
76 import com.android.systemui.R.string.kg_wrong_password_try_again
77 import com.android.systemui.R.string.kg_wrong_pattern_try_again
78 import com.android.systemui.R.string.kg_wrong_pin_try_again
79 import com.android.systemui.bouncer.shared.model.BouncerMessageModel
80 import com.android.systemui.bouncer.shared.model.Message
81 import com.android.systemui.dagger.SysUISingleton
82 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
83 import javax.inject.Inject
84
85 @SysUISingleton
86 class BouncerMessageFactory
87 @Inject
88 constructor(
89 private val biometricSettingsRepository: BiometricSettingsRepository,
90 private val securityModel: KeyguardSecurityModel,
91 ) {
92
createFromPromptReasonnull93 fun createFromPromptReason(
94 @BouncerPromptReason reason: Int,
95 userId: Int,
96 secondaryMsgOverride: String? = null
97 ): BouncerMessageModel? {
98 val pair =
99 getBouncerMessage(
100 reason,
101 securityModel.getSecurityMode(userId),
102 biometricSettingsRepository.isFingerprintAuthCurrentlyAllowed.value
103 )
104 return pair?.let {
105 BouncerMessageModel(
106 message = Message(messageResId = pair.first, animate = false),
107 secondaryMessage =
108 secondaryMsgOverride?.let {
109 Message(message = secondaryMsgOverride, animate = false)
110 }
111 ?: Message(messageResId = pair.second, animate = false)
112 )
113 }
114 }
115
116 /**
117 * Helper method that provides the relevant bouncer message that should be shown for different
118 * scenarios indicated by [reason]. [securityMode] & [fpAuthIsAllowed] parameters are used to
119 * provide a more specific message.
120 */
getBouncerMessagenull121 private fun getBouncerMessage(
122 @BouncerPromptReason reason: Int,
123 securityMode: SecurityMode,
124 fpAuthIsAllowed: Boolean = false
125 ): Pair<Int, Int>? {
126 return when (reason) {
127 // Primary auth locked out
128 PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT -> primaryAuthLockedOut(securityMode)
129 // Primary auth required reasons
130 PROMPT_REASON_RESTART -> authRequiredAfterReboot(securityMode)
131 PROMPT_REASON_TIMEOUT -> authRequiredAfterPrimaryAuthTimeout(securityMode)
132 PROMPT_REASON_DEVICE_ADMIN -> authRequiredAfterAdminLockdown(securityMode)
133 PROMPT_REASON_USER_REQUEST -> authRequiredAfterUserLockdown(securityMode)
134 PROMPT_REASON_PREPARE_FOR_UPDATE -> authRequiredForUnattendedUpdate(securityMode)
135 PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE -> authRequiredForMainlineUpdate(securityMode)
136 PROMPT_REASON_FINGERPRINT_LOCKED_OUT -> fingerprintUnlockUnavailable(securityMode)
137 PROMPT_REASON_AFTER_LOCKOUT -> biometricLockout(securityMode)
138 // Non strong auth not available reasons
139 PROMPT_REASON_FACE_LOCKED_OUT ->
140 if (fpAuthIsAllowed) faceLockedOutButFingerprintAvailable(securityMode)
141 else faceLockedOut(securityMode)
142 PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT ->
143 if (fpAuthIsAllowed) nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
144 else nonStrongAuthTimeout(securityMode)
145 PROMPT_REASON_TRUSTAGENT_EXPIRED ->
146 if (fpAuthIsAllowed) trustAgentDisabledWithFingerprintAllowed(securityMode)
147 else trustAgentDisabled(securityMode)
148 // Auth incorrect input reasons.
149 PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT ->
150 if (fpAuthIsAllowed) incorrectSecurityInputWithFingerprint(securityMode)
151 else incorrectSecurityInput(securityMode)
152 PROMPT_REASON_INCORRECT_FACE_INPUT ->
153 if (fpAuthIsAllowed) incorrectFaceInputWithFingerprintAllowed(securityMode)
154 else incorrectFaceInput(securityMode)
155 PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT -> incorrectFingerprintInput(securityMode)
156 // Default message
157 PROMPT_REASON_DEFAULT ->
158 if (fpAuthIsAllowed) defaultMessageWithFingerprint(securityMode)
159 else defaultMessage(securityMode)
160 else -> null
161 }
162 }
163
emptyMessagenull164 fun emptyMessage(): BouncerMessageModel =
165 BouncerMessageModel(Message(message = ""), Message(message = ""))
166 }
167
168 @Retention(AnnotationRetention.SOURCE)
169 @IntDef(
170 PROMPT_REASON_TIMEOUT,
171 PROMPT_REASON_DEVICE_ADMIN,
172 PROMPT_REASON_USER_REQUEST,
173 PROMPT_REASON_AFTER_LOCKOUT,
174 PROMPT_REASON_PREPARE_FOR_UPDATE,
175 PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT,
176 PROMPT_REASON_TRUSTAGENT_EXPIRED,
177 PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
178 PROMPT_REASON_INCORRECT_FACE_INPUT,
179 PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT,
180 PROMPT_REASON_FACE_LOCKED_OUT,
181 PROMPT_REASON_FINGERPRINT_LOCKED_OUT,
182 PROMPT_REASON_DEFAULT,
183 PROMPT_REASON_NONE,
184 PROMPT_REASON_RESTART,
185 PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT,
186 PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE,
187 )
188 annotation class BouncerPromptReason
189
190 private fun defaultMessage(securityMode: SecurityMode): Pair<Int, Int> {
191 return when (securityMode) {
192 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, 0)
193 SecurityMode.Password -> Pair(keyguard_enter_password, 0)
194 SecurityMode.PIN -> Pair(keyguard_enter_pin, 0)
195 else -> Pair(0, 0)
196 }
197 }
198
defaultMessageWithFingerprintnull199 private fun defaultMessageWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
200 return when (securityMode) {
201 SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, 0)
202 SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, 0)
203 SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, 0)
204 else -> Pair(0, 0)
205 }
206 }
207
incorrectSecurityInputnull208 private fun incorrectSecurityInput(securityMode: SecurityMode): Pair<Int, Int> {
209 return when (securityMode) {
210 SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, 0)
211 SecurityMode.Password -> Pair(kg_wrong_password_try_again, 0)
212 SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, 0)
213 else -> Pair(0, 0)
214 }
215 }
216
incorrectSecurityInputWithFingerprintnull217 private fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
218 return when (securityMode) {
219 SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, kg_wrong_input_try_fp_suggestion)
220 SecurityMode.Password -> Pair(kg_wrong_password_try_again, kg_wrong_input_try_fp_suggestion)
221 SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, kg_wrong_input_try_fp_suggestion)
222 else -> Pair(0, 0)
223 }
224 }
225
incorrectFingerprintInputnull226 private fun incorrectFingerprintInput(securityMode: SecurityMode): Pair<Int, Int> {
227 return when (securityMode) {
228 SecurityMode.Pattern -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pattern)
229 SecurityMode.Password -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_password)
230 SecurityMode.PIN -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pin)
231 else -> Pair(0, 0)
232 }
233 }
234
incorrectFaceInputnull235 private fun incorrectFaceInput(securityMode: SecurityMode): Pair<Int, Int> {
236 return when (securityMode) {
237 SecurityMode.Pattern -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pattern)
238 SecurityMode.Password -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_password)
239 SecurityMode.PIN -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pin)
240 else -> Pair(0, 0)
241 }
242 }
243
incorrectFaceInputWithFingerprintAllowednull244 private fun incorrectFaceInputWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
245 return when (securityMode) {
246 SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, bouncer_face_not_recognized)
247 SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, bouncer_face_not_recognized)
248 SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, bouncer_face_not_recognized)
249 else -> Pair(0, 0)
250 }
251 }
252
biometricLockoutnull253 private fun biometricLockout(securityMode: SecurityMode): Pair<Int, Int> {
254 return when (securityMode) {
255 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
256 SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
257 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_bio_too_many_attempts_pin)
258 else -> Pair(0, 0)
259 }
260 }
261
authRequiredAfterRebootnull262 private fun authRequiredAfterReboot(securityMode: SecurityMode): Pair<Int, Int> {
263 return when (securityMode) {
264 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_reason_restart_pattern)
265 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_reason_restart_password)
266 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin)
267 else -> Pair(0, 0)
268 }
269 }
270
authRequiredAfterAdminLockdownnull271 private fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): Pair<Int, Int> {
272 return when (securityMode) {
273 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_dpm_lock)
274 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_dpm_lock)
275 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock)
276 else -> Pair(0, 0)
277 }
278 }
279
authRequiredAfterUserLockdownnull280 private fun authRequiredAfterUserLockdown(securityMode: SecurityMode): Pair<Int, Int> {
281 return when (securityMode) {
282 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern)
283 SecurityMode.Password ->
284 Pair(keyguard_enter_password, kg_prompt_after_user_lockdown_password)
285 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin)
286 else -> Pair(0, 0)
287 }
288 }
289
authRequiredForUnattendedUpdatenull290 private fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): Pair<Int, Int> {
291 return when (securityMode) {
292 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_unattended_update)
293 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_unattended_update)
294 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_unattended_update)
295 else -> Pair(0, 0)
296 }
297 }
298
authRequiredForMainlineUpdatenull299 private fun authRequiredForMainlineUpdate(securityMode: SecurityMode): Pair<Int, Int> {
300 return when (securityMode) {
301 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_update_pattern)
302 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_update_password)
303 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_update_pin)
304 else -> Pair(0, 0)
305 }
306 }
307
authRequiredAfterPrimaryAuthTimeoutnull308 private fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
309 return when (securityMode) {
310 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_pattern_auth_timeout)
311 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_password_auth_timeout)
312 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout)
313 else -> Pair(0, 0)
314 }
315 }
316
nonStrongAuthTimeoutnull317 private fun nonStrongAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
318 return when (securityMode) {
319 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_auth_timeout)
320 SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_auth_timeout)
321 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_auth_timeout)
322 else -> Pair(0, 0)
323 }
324 }
325
nonStrongAuthTimeoutWithFingerprintAllowednull326 private fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
327 return when (securityMode) {
328 SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_prompt_auth_timeout)
329 SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_prompt_auth_timeout)
330 SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_prompt_auth_timeout)
331 else -> Pair(0, 0)
332 }
333 }
334
faceLockedOutnull335 private fun faceLockedOut(securityMode: SecurityMode): Pair<Int, Int> {
336 return when (securityMode) {
337 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_face_locked_out)
338 SecurityMode.Password -> Pair(keyguard_enter_password, kg_face_locked_out)
339 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_face_locked_out)
340 else -> Pair(0, 0)
341 }
342 }
343
faceLockedOutButFingerprintAvailablenull344 private fun faceLockedOutButFingerprintAvailable(securityMode: SecurityMode): Pair<Int, Int> {
345 return when (securityMode) {
346 SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_face_locked_out)
347 SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_face_locked_out)
348 SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_face_locked_out)
349 else -> Pair(0, 0)
350 }
351 }
352
fingerprintUnlockUnavailablenull353 private fun fingerprintUnlockUnavailable(securityMode: SecurityMode): Pair<Int, Int> {
354 return when (securityMode) {
355 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_fp_locked_out)
356 SecurityMode.Password -> Pair(keyguard_enter_password, kg_fp_locked_out)
357 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_fp_locked_out)
358 else -> Pair(0, 0)
359 }
360 }
361
trustAgentDisablednull362 private fun trustAgentDisabled(securityMode: SecurityMode): Pair<Int, Int> {
363 return when (securityMode) {
364 SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_trust_agent_disabled)
365 SecurityMode.Password -> Pair(keyguard_enter_password, kg_trust_agent_disabled)
366 SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_trust_agent_disabled)
367 else -> Pair(0, 0)
368 }
369 }
370
trustAgentDisabledWithFingerprintAllowednull371 private fun trustAgentDisabledWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
372 return when (securityMode) {
373 SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_trust_agent_disabled)
374 SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_trust_agent_disabled)
375 SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_trust_agent_disabled)
376 else -> Pair(0, 0)
377 }
378 }
379
primaryAuthLockedOutnull380 private fun primaryAuthLockedOut(securityMode: SecurityMode): Pair<Int, Int> {
381 return when (securityMode) {
382 SecurityMode.Pattern ->
383 Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pattern)
384 SecurityMode.Password ->
385 Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_password)
386 SecurityMode.PIN ->
387 Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pin)
388 else -> Pair(0, 0)
389 }
390 }
391