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 android.trust.test.lib
18 
19 import android.app.KeyguardManager
20 import android.app.trust.TrustManager
21 import android.content.Context
22 import android.util.Log
23 import android.view.WindowManagerGlobal
24 import androidx.test.core.app.ApplicationProvider.getApplicationContext
25 import org.junit.rules.TestRule
26 import org.junit.runner.Description
27 import org.junit.runners.model.Statement
28 
29 /**
30  * Rule for tracking the trusted state of the device based on events emitted to
31  * [TrustListener].  Provides helper methods for verifying that the trusted
32  * state has a particular value and is consistent with (a) the keyguard "locked"
33  * (i.e. showing) value when applicable, and (b) the device locked value that is
34  * tracked by TrustManagerService and is queryable via KeyguardManager.
35  */
36 class LockStateTrackingRule : TestRule {
37     private val context: Context = getApplicationContext()
38     private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService())
39     private val keyguardManager =
40             context.getSystemService(KeyguardManager::class.java) as KeyguardManager
41 
42     @Volatile lateinit var trustState: TrustState
43         private set
44 
applynull45     override fun apply(base: Statement, description: Description) = object : Statement() {
46         override fun evaluate() {
47             trustState = TrustState()
48             val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
49             val listener = Listener()
50 
51             trustManager.registerTrustListener(listener)
52             try {
53                 base.evaluate()
54             } finally {
55                 trustManager.unregisterTrustListener(listener)
56             }
57         }
58     }
59 
assertLockednull60     fun assertLocked() {
61         wait("device locked") { keyguardManager.isDeviceLocked }
62         // isDeviceLocked implies isKeyguardLocked && !trusted.
63         wait("keyguard locked") { windowManager.isKeyguardLocked }
64         wait("not trusted") { trustState.trusted == false }
65     }
66 
67     // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2
assertUnlockedButNotReallynull68     fun assertUnlockedButNotReally() {
69         wait("device unlocked") { !keyguardManager.isDeviceLocked }
70         wait("not trusted") { trustState.trusted == false }
71         wait("keyguard locked") { windowManager.isKeyguardLocked }
72     }
73 
assertUnlockedAndTrustednull74     fun assertUnlockedAndTrusted() {
75         wait("device unlocked") { !keyguardManager.isDeviceLocked }
76         wait("trusted") { trustState.trusted == true }
77         // Can't check for !isKeyguardLocked here, since isKeyguardLocked
78         // returns true in the case where the keyguard is dismissible with
79         // swipe, which is considered "device unlocked"!
80     }
81 
82     inner class Listener : TestTrustListener() {
onTrustChangednull83         override fun onTrustChanged(
84             enabled: Boolean,
85             newlyUnlocked: Boolean,
86             userId: Int,
87             flags: Int,
88             trustGrantedMessages: MutableList<String>
89         ) {
90             Log.d(TAG, "Device became trusted=$enabled")
91             trustState = trustState.copy(trusted = enabled)
92         }
93     }
94 
95     data class TrustState(
96         val trusted: Boolean? = null
97     )
98 
99     companion object {
100         private const val TAG = "LockStateTrackingRule"
101     }
102 }
103