• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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.content.ContentResolver
20 import android.database.ContentObserver
21 import android.hardware.biometrics.BiometricFaceConstants
22 import android.net.Uri
23 import android.os.Handler
24 import android.os.PowerManager
25 import android.os.PowerManager.WAKE_REASON_BIOMETRIC
26 import android.os.UserHandle
27 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL
28 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
29 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
30 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
31 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY
32 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
33 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
34 import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
35 import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
36 import androidx.test.filters.SmallTest
37 import com.android.systemui.SysuiTestCase
38 import com.android.systemui.dump.DumpManager
39 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
40 import com.android.systemui.util.mockito.capture
41 import com.android.systemui.util.mockito.eq
42 import com.android.systemui.util.mockito.whenever
43 import com.android.systemui.util.settings.FakeSettings
44 import dagger.Lazy
45 import java.io.PrintWriter
46 import org.junit.Assert.assertFalse
47 import org.junit.Assert.assertTrue
48 import org.junit.Before
49 import org.junit.Test
50 import org.mockito.ArgumentCaptor
51 import org.mockito.Captor
52 import org.mockito.Mock
53 import org.mockito.Mockito.verify
54 import org.mockito.Mockito.`when`
55 import org.mockito.MockitoAnnotations
56 
57 @SmallTest
58 class ActiveUnlockConfigTest : SysuiTestCase() {
59     private lateinit var secureSettings: FakeSettings
60     @Mock private lateinit var contentResolver: ContentResolver
61     @Mock private lateinit var handler: Handler
62     @Mock private lateinit var dumpManager: DumpManager
63     @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
64     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
65     @Mock private lateinit var lazyKeyguardUpdateMonitor: Lazy<KeyguardUpdateMonitor>
66     @Mock private lateinit var mockPrintWriter: PrintWriter
67 
68     @Captor private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
69 
70     private lateinit var activeUnlockConfig: ActiveUnlockConfig
71     private var currentUser: Int = 0
72 
73     @Before
setUpnull74     fun setUp() {
75         MockitoAnnotations.initMocks(this)
76 
77         whenever(selectedUserInteractor.getSelectedUserId()).thenReturn(currentUser)
78         whenever(lazyKeyguardUpdateMonitor.get()).thenReturn(keyguardUpdateMonitor)
79         secureSettings = FakeSettings()
80         activeUnlockConfig =
81             ActiveUnlockConfig(
82                 handler,
83                 secureSettings,
84                 contentResolver,
85                 selectedUserInteractor,
86                 lazyKeyguardUpdateMonitor,
87                 dumpManager
88             )
89     }
90 
91     @Test
registersForSettingsChangesnull92     fun registersForSettingsChanges() {
93         verifyRegisterSettingObserver()
94     }
95 
96     @Test
onWakeupSettingChangednull97     fun onWakeupSettingChanged() {
98         // GIVEN no active unlock settings enabled
99         assertFalse(
100             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
101                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
102             )
103         )
104 
105         // WHEN unlock on wake is allowed
106         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_WAKE, 1, currentUser)
107         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE))
108 
109         // THEN active unlock triggers allowed on: wake, unlock-intent, and biometric failure
110         assertTrue(
111             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
112                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
113             )
114         )
115         assertFalse(
116                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
117                         ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
118                 )
119         )
120         assertTrue(
121             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
122                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
123             )
124         )
125         assertTrue(
126             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
127                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
128             )
129         )
130     }
131 
132     @Test
onUnlockIntentLegacySettingChangednull133     fun onUnlockIntentLegacySettingChanged() {
134         // GIVEN no active unlock settings enabled
135         assertFalse(
136             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
137                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
138             )
139         )
140 
141         // WHEN unlock on unlock intent legacy is allowed
142         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY, 1, currentUser)
143         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY))
144 
145         // THEN active unlock triggers allowed on unlock_intent_legacy, unlock_intent,
146         // AND biometric fail
147         assertFalse(
148             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
149                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
150             )
151         )
152         assertTrue(
153             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
154                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
155             )
156         )
157         assertTrue(
158             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
159                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
160             )
161         )
162         assertTrue(
163             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
164                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
165             )
166         )
167     }
168 
169     @Test
onUnlockIntentSettingChangednull170     fun onUnlockIntentSettingChanged() {
171         // GIVEN no active unlock settings enabled
172         assertFalse(
173             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
174                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
175             )
176         )
177 
178         // WHEN unlock on unlock intent is allowed
179         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 1, currentUser)
180         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT))
181 
182         // THEN active unlock triggers allowed on: unlock intent AND biometric failure
183         assertFalse(
184             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
185                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
186             )
187         )
188         assertFalse(
189             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
190                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
191             )
192         )
193         assertTrue(
194             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
195                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
196             )
197         )
198         assertTrue(
199             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
200                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
201             )
202         )
203     }
204 
205     @Test
onBioFailSettingChangednull206     fun onBioFailSettingChanged() {
207         // GIVEN no active unlock settings enabled and triggering unlock intent on biometric
208         // enrollment setting is disabled (empty string is disabled, null would use the default)
209         secureSettings.putStringForUser(
210             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
211             "",
212             currentUser
213         )
214         updateSetting(
215             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
216         )
217         assertFalse(
218             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
219                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
220             )
221         )
222 
223         // WHEN unlock on biometric failed is allowed
224         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser)
225         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
226 
227         // THEN active unlock triggers allowed on: biometric failure ONLY
228         assertFalse(
229             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
230                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
231             )
232         )
233         assertFalse(
234             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
235                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
236             )
237         )
238         assertFalse(
239             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
240                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
241             )
242         )
243         assertTrue(
244             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
245                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
246             )
247         )
248     }
249 
250     @Test
faceErrorSettingsChangednull251     fun faceErrorSettingsChanged() {
252         // GIVEN unlock on biometric fail
253         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser)
254         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
255 
256         // WHEN face error timeout (3), allow trigger active unlock
257         secureSettings.putStringForUser(ACTIVE_UNLOCK_ON_FACE_ERRORS, "3", currentUser)
258         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS))
259 
260         // THEN active unlock triggers allowed on error TIMEOUT
261         assertTrue(
262             activeUnlockConfig.shouldRequestActiveUnlockOnFaceError(
263                 BiometricFaceConstants.FACE_ERROR_TIMEOUT
264             )
265         )
266 
267         assertFalse(
268             activeUnlockConfig.shouldRequestActiveUnlockOnFaceError(
269                 BiometricFaceConstants.FACE_ERROR_CANCELED
270             )
271         )
272     }
273 
274     @Test
faceAcquiredSettingsChangednull275     fun faceAcquiredSettingsChanged() {
276         // GIVEN unlock on biometric fail
277         secureSettings.putStringForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, "1", currentUser)
278         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
279 
280         // WHEN face acquiredMsg DARK_GLASSESand MOUTH_COVERING are allowed to trigger
281         secureSettings.putStringForUser(
282             ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
283             "${BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED}" +
284                 "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}",
285             currentUser
286         )
287         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO))
288 
289         // THEN active unlock triggers allowed on acquired messages DARK_GLASSES & MOUTH_COVERING
290         assertTrue(
291             activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
292                 BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED
293             )
294         )
295         assertTrue(
296             activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
297                 BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED
298             )
299         )
300 
301         assertFalse(
302             activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
303                 BiometricFaceConstants.FACE_ACQUIRED_GOOD
304             )
305         )
306         assertFalse(
307             activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
308                 BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED
309             )
310         )
311     }
312 
313     @Test
triggerOnUnlockIntentWhenBiometricEnrolledNonenull314     fun triggerOnUnlockIntentWhenBiometricEnrolledNone() {
315         // GIVEN unlock on biometric fail
316         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser)
317         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
318 
319         // GIVEN fingerprint and face are NOT enrolled
320         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(false)
321         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(false)
322 
323         // WHEN unlock intent is allowed when NO biometrics are enrolled (0)
324 
325         secureSettings.putStringForUser(
326             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
327             "${ActiveUnlockConfig.BiometricType.NONE.intValue}",
328             currentUser
329         )
330         updateSetting(
331             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
332         )
333 
334         // THEN active unlock triggers allowed on unlock intent
335         assertTrue(
336             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
337                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
338             )
339         )
340     }
341 
342     @Test
triggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnlynull343     fun triggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnly() {
344         // GIVEN unlock on biometric fail
345         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 1, currentUser)
346         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
347 
348         // GIVEN fingerprint and face are both enrolled
349         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(true)
350         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(true)
351 
352         // WHEN unlock intent is allowed when ONLY fingerprint is enrolled or NO biometircs
353         // are enrolled
354         secureSettings.putStringForUser(
355             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
356             "${ActiveUnlockConfig.BiometricType.ANY_FACE.intValue}" +
357                 "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}",
358             currentUser
359         )
360         updateSetting(
361             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
362         )
363 
364         // THEN active unlock triggers NOT allowed on unlock intent
365         assertFalse(
366             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
367                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
368             )
369         )
370 
371         // WHEN fingerprint ONLY enrolled
372         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(false)
373         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(true)
374 
375         // THEN active unlock triggers allowed on unlock intent
376         assertTrue(
377             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
378                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
379             )
380         )
381 
382         // WHEN face ONLY enrolled
383         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(true)
384         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(false)
385 
386         // THEN active unlock triggers allowed on unlock intent
387         assertTrue(
388             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
389                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
390             )
391         )
392     }
393 
394     @Test
isWakeupConsideredUnlockIntent_singleValuenull395     fun isWakeupConsideredUnlockIntent_singleValue() {
396         // GIVEN lift is considered an unlock intent
397         secureSettings.putIntForUser(
398             ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
399             PowerManager.WAKE_REASON_LIFT,
400             currentUser
401         )
402         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
403 
404         // THEN only WAKE_REASON_LIFT is considered an unlock intent
405         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
406             if (wakeReason == PowerManager.WAKE_REASON_LIFT) {
407                 assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
408             } else {
409                 assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
410             }
411         }
412     }
413 
414     @Test
isWakeupConsideredUnlockIntent_multiValuenull415     fun isWakeupConsideredUnlockIntent_multiValue() {
416         // GIVEN lift and tap are considered an unlock intent
417         secureSettings.putStringForUser(
418             ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
419             PowerManager.WAKE_REASON_LIFT.toString() +
420                 "|" +
421                 PowerManager.WAKE_REASON_TAP.toString(),
422             currentUser
423         )
424         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
425 
426         // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent
427         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
428             if (
429                 wakeReason == PowerManager.WAKE_REASON_LIFT ||
430                     wakeReason == PowerManager.WAKE_REASON_TAP
431             ) {
432                 assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
433             } else {
434                 assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
435             }
436         }
437         assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_LIFT))
438         assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
439         assertFalse(
440             activeUnlockConfig.isWakeupConsideredUnlockIntent(
441                 PowerManager.WAKE_REASON_UNFOLD_DEVICE
442             )
443         )
444     }
445 
446     @Test
isWakeupConsideredUnlockIntent_emptyValuesnull447     fun isWakeupConsideredUnlockIntent_emptyValues() {
448         // GIVEN lift and tap are considered an unlock intent
449         secureSettings.putStringForUser(
450             ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
451             " ",
452             currentUser
453         )
454         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
455 
456         // THEN no wake up gestures are considered an unlock intent
457         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
458             assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
459         }
460         assertFalse(
461             activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_LIFT)
462         )
463         assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
464         assertFalse(
465             activeUnlockConfig.isWakeupConsideredUnlockIntent(
466                 PowerManager.WAKE_REASON_UNFOLD_DEVICE
467             )
468         )
469     }
470 
471     @Test
isWakeupForceDismissKeyguard_singleValuenull472     fun isWakeupForceDismissKeyguard_singleValue() {
473         verifyRegisterSettingObserver()
474 
475         // GIVEN lift is considered an unlock intent
476         secureSettings.putStringForUser(
477             ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
478             PowerManager.WAKE_REASON_LIFT.toString(),
479             currentUser
480         )
481         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
482 
483         // THEN only WAKE_REASON_LIFT is considered an unlock intent
484         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
485             if (wakeReason == PowerManager.WAKE_REASON_LIFT) {
486                 assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
487             } else {
488                 assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
489             }
490         }
491     }
492 
493     @Test
isWakeupForceDismissKeyguard_emptyValuesnull494     fun isWakeupForceDismissKeyguard_emptyValues() {
495         verifyRegisterSettingObserver()
496 
497         // GIVEN lift and tap are considered an unlock intent
498         secureSettings.putStringForUser(
499             ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
500             " ",
501             currentUser
502         )
503         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
504 
505         // THEN no wake up gestures are considered an unlock intent
506         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
507             assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
508         }
509     }
510 
511     @Test
isWakeupForceDismissKeyguard_multiValuenull512     fun isWakeupForceDismissKeyguard_multiValue() {
513         verifyRegisterSettingObserver()
514 
515         // GIVEN lift and tap are considered an unlock intent
516         secureSettings.putStringForUser(
517             ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
518             PowerManager.WAKE_REASON_LIFT.toString() +
519                 "|" +
520                 PowerManager.WAKE_REASON_TAP.toString(),
521             currentUser
522         )
523         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
524 
525         // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent
526         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
527             if (
528                 wakeReason == PowerManager.WAKE_REASON_LIFT ||
529                     wakeReason == PowerManager.WAKE_REASON_TAP
530             ) {
531                 assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
532             } else {
533                 assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
534             }
535         }
536     }
537 
538     @Test
dump_onUnlockIntentWhenBiometricEnrolled_invalidNum_noArrayOutOfBoundsExceptionnull539     fun dump_onUnlockIntentWhenBiometricEnrolled_invalidNum_noArrayOutOfBoundsException() {
540         // GIVEN an invalid input (-1)
541         secureSettings.putStringForUser(
542             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
543             "-1",
544             currentUser
545         )
546 
547         // WHEN the setting updates
548         updateSetting(
549             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
550         )
551 
552         // THEN no exception thrown
553         activeUnlockConfig.dump(mockPrintWriter, emptyArray())
554     }
555 
updateSettingnull556     private fun updateSetting(uri: Uri) {
557         verifyRegisterSettingObserver()
558         settingsObserverCaptor.value.onChange(false, listOf(uri), 0, 0 /* flags */)
559     }
560 
verifyRegisterSettingObservernull561     private fun verifyRegisterSettingObserver() {
562         verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE))
563         verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT))
564         verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
565         verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS))
566         verifyRegisterSettingObserver(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO))
567         verifyRegisterSettingObserver(
568             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
569         )
570         verifyRegisterSettingObserver(
571             secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)
572         )
573     }
574 
verifyRegisterSettingObservernull575     private fun verifyRegisterSettingObserver(uri: Uri) {
576         verify(contentResolver)
577             .registerContentObserver(
578                 eq(uri),
579                 eq(false),
580                 capture(settingsObserverCaptor),
581                 eq(UserHandle.USER_ALL)
582             )
583     }
584 }
585