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