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.trust.TrustManager
20 import android.content.Context
21 import android.util.Log
22 import android.view.WindowManagerGlobal
23 import androidx.test.core.app.ApplicationProvider.getApplicationContext
24 import org.junit.rules.TestRule
25 import org.junit.runner.Description
26 import org.junit.runners.model.Statement
27 
28 /**
29  * Rule for tracking the lock state of the device based on events emitted to [TrustListener].
30  */
31 class LockStateTrackingRule : TestRule {
32     private val context: Context = getApplicationContext()
33     private val windowManager = WindowManagerGlobal.getWindowManagerService()
34 
35     @Volatile lateinit var lockState: LockState
36         private set
37 
38     override fun apply(base: Statement, description: Description) = object : Statement() {
39         override fun evaluate() {
40             lockState = LockState(locked = windowManager.isKeyguardLocked)
41             val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
42             val listener = Listener()
43 
44             trustManager.registerTrustListener(listener)
45             try {
46                 base.evaluate()
47             } finally {
48                 trustManager.unregisterTrustListener(listener)
49             }
50         }
51     }
52 
53     fun assertLocked() {
54         wait("un-locked per TrustListener") { lockState.locked == true }
55         wait("keyguard lock") { windowManager.isKeyguardLocked }
56     }
57 
58     fun assertUnlocked() {
59         wait("locked per TrustListener") { lockState.locked == false }
60     }
61 
62     inner class Listener : TestTrustListener() {
63         override fun onTrustChanged(
64             enabled: Boolean,
65             newlyUnlocked: Boolean,
66             userId: Int,
67             flags: Int,
68             trustGrantedMessages: MutableList<String>
69         ) {
70             Log.d(TAG, "Device became trusted=$enabled")
71             lockState = lockState.copy(locked = !enabled)
72         }
73     }
74 
75     data class LockState(
76         val locked: Boolean? = null
77     )
78 
79     companion object {
80         private const val TAG = "LockStateTrackingRule"
81     }
82 }
83