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 93 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 */ 121 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 164 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 199 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 208 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 217 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 226 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 235 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 244 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 253 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 262 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 271 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 280 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 290 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 299 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 308 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 317 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 326 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 335 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 344 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 353 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 362 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 371 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 380 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