• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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 package android.trust.test
17 
18 import android.app.trust.TrustManager
19 import android.content.Context
20 import android.security.Flags.shouldTrustManagerListenForPrimaryAuth
21 import android.trust.BaseTrustAgentService
22 import android.trust.TrustTestActivity
23 import android.trust.test.lib.LockStateTrackingRule
24 import android.trust.test.lib.ScreenLockRule
25 import android.trust.test.lib.TestTrustListener
26 import android.trust.test.lib.TrustAgentRule
27 import android.util.Log
28 import androidx.test.core.app.ApplicationProvider.getApplicationContext
29 import androidx.test.ext.junit.rules.ActivityScenarioRule
30 import androidx.test.ext.junit.runners.AndroidJUnit4
31 import com.google.common.truth.Truth.assertThat
32 import org.junit.Before
33 import org.junit.Rule
34 import org.junit.Test
35 import org.junit.rules.RuleChain
36 import org.junit.runner.RunWith
37 
38 /**
39  * Test for the impacts of reporting unlock attempts.
40  *
41  * atest TrustTests:UnlockAttemptTest
42  */
43 @RunWith(AndroidJUnit4::class)
44 class UnlockAttemptTest {
45     private val context = getApplicationContext<Context>()
46     private val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
47     private val userId = context.userId
48     private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
49     private val screenLockRule = ScreenLockRule(requireStrongAuth = true)
50     private val lockStateTrackingRule = LockStateTrackingRule()
51     private val trustAgentRule =
52         TrustAgentRule<UnlockAttemptTrustAgent>(startUnlocked = false, startEnabled = false)
53 
54     private val trustListener = UnlockAttemptTrustListener()
55     private val agent get() = trustAgentRule.agent
56 
57     @get:Rule
58     val rule: RuleChain =
59         RuleChain.outerRule(activityScenarioRule)
60             .around(screenLockRule)
61             .around(lockStateTrackingRule)
62             .around(trustAgentRule)
63 
64     @Before
65     fun setUp() {
66         trustManager.registerTrustListener(trustListener)
67     }
68 
69     @Test
70     fun successfulUnlockAttempt_allowsTrustAgentToStart() =
71         runUnlockAttemptTest(enableAndVerifyTrustAgent = false, managingTrust = false) {
72             trustAgentRule.enableTrustAgent()
73 
74             triggerSuccessfulUnlock()
75 
76             trustAgentRule.verifyAgentIsRunning(MAX_WAIT_FOR_ENABLED_TRUST_AGENT_TO_START)
77         }
78 
79     @Test
80     fun successfulUnlockAttempt_notifiesTrustAgent() =
81         runUnlockAttemptTest(enableAndVerifyTrustAgent = true, managingTrust = true) {
82             val oldSuccessfulCount = agent.successfulUnlockCallCount
83             val oldFailedCount = agent.failedUnlockCallCount
84 
85             triggerSuccessfulUnlock()
86 
87             assertThat(agent.successfulUnlockCallCount).isEqualTo(oldSuccessfulCount + 1)
88             assertThat(agent.failedUnlockCallCount).isEqualTo(oldFailedCount)
89         }
90 
91     @Test
92     fun successfulUnlockAttempt_notifiesTrustListenerOfManagedTrust() =
93         runUnlockAttemptTest(enableAndVerifyTrustAgent = true, managingTrust = true) {
94             val oldTrustManagedChangedCount = trustListener.onTrustManagedChangedCount[userId] ?: 0
95 
96             triggerSuccessfulUnlock()
97 
98             assertThat(trustListener.onTrustManagedChangedCount[userId] ?: 0).isEqualTo(
99                 oldTrustManagedChangedCount + 1
100             )
101         }
102 
103     @Test
104     fun failedUnlockAttempt_doesNotAllowTrustAgentToStart() =
105         runUnlockAttemptTest(enableAndVerifyTrustAgent = false, managingTrust = false) {
106             trustAgentRule.enableTrustAgent()
107 
108             triggerFailedUnlock()
109 
110             trustAgentRule.ensureAgentIsNotRunning(MAX_WAIT_FOR_ENABLED_TRUST_AGENT_TO_START)
111         }
112 
113     @Test
114     fun failedUnlockAttempt_notifiesTrustAgent() =
115         runUnlockAttemptTest(enableAndVerifyTrustAgent = true, managingTrust = true) {
116             val oldSuccessfulCount = agent.successfulUnlockCallCount
117             val oldFailedCount = agent.failedUnlockCallCount
118 
119             triggerFailedUnlock()
120 
121             assertThat(agent.successfulUnlockCallCount).isEqualTo(oldSuccessfulCount)
122             assertThat(agent.failedUnlockCallCount).isEqualTo(oldFailedCount + 1)
123         }
124 
125     @Test
126     fun failedUnlockAttempt_doesNotNotifyTrustListenerOfManagedTrust() =
127         runUnlockAttemptTest(enableAndVerifyTrustAgent = true, managingTrust = true) {
128             val oldTrustManagedChangedCount = trustListener.onTrustManagedChangedCount[userId] ?: 0
129 
130             triggerFailedUnlock()
131 
132             assertThat(trustListener.onTrustManagedChangedCount[userId] ?: 0).isEqualTo(
133                 oldTrustManagedChangedCount
134             )
135         }
136 
137     private fun runUnlockAttemptTest(
138         enableAndVerifyTrustAgent: Boolean,
139         managingTrust: Boolean,
140         testBlock: () -> Unit,
141     ) {
142         if (enableAndVerifyTrustAgent) {
143             Log.i(TAG, "Triggering successful unlock")
144             triggerSuccessfulUnlock()
145             Log.i(TAG, "Enabling and waiting for trust agent")
146             trustAgentRule.enableAndVerifyTrustAgentIsRunning(
147                 MAX_WAIT_FOR_ENABLED_TRUST_AGENT_TO_START
148             )
149             Log.i(TAG, "Managing trust: $managingTrust")
150             agent.setManagingTrust(managingTrust)
151             await()
152         }
153         testBlock()
154     }
155 
156     private fun triggerSuccessfulUnlock() {
157         screenLockRule.successfulScreenLockAttempt()
158         if (!shouldTrustManagerListenForPrimaryAuth()) {
159             trustAgentRule.reportSuccessfulUnlock()
160         }
161         await()
162     }
163 
164     private fun triggerFailedUnlock() {
165         screenLockRule.failedScreenLockAttempt()
166         if (!shouldTrustManagerListenForPrimaryAuth()) {
167             trustAgentRule.reportFailedUnlock()
168         }
169         await()
170     }
171 
172     companion object {
173         private const val TAG = "UnlockAttemptTest"
174         private fun await(millis: Long = 500) = Thread.sleep(millis)
175         private const val MAX_WAIT_FOR_ENABLED_TRUST_AGENT_TO_START = 10000L
176     }
177 }
178 
179 class UnlockAttemptTrustAgent : BaseTrustAgentService() {
180     var successfulUnlockCallCount: Long = 0
181         private set
182     var failedUnlockCallCount: Long = 0
183         private set
184 
onUnlockAttemptnull185     override fun onUnlockAttempt(successful: Boolean) {
186         super.onUnlockAttempt(successful)
187         if (successful) {
188             successfulUnlockCallCount++
189         } else {
190             failedUnlockCallCount++
191         }
192     }
193 }
194 
195 private class UnlockAttemptTrustListener : TestTrustListener() {
196     var enabledTrustAgentsChangedCount = mutableMapOf<Int, Int>()
197     var onTrustManagedChangedCount = mutableMapOf<Int, Int>()
198 
onEnabledTrustAgentsChangednull199     override fun onEnabledTrustAgentsChanged(userId: Int) {
200         enabledTrustAgentsChangedCount.compute(userId) { _: Int, curr: Int? ->
201             if (curr == null) 0 else curr + 1
202         }
203     }
204 
205     data class TrustChangedParams(
206         val enabled: Boolean,
207         val newlyUnlocked: Boolean,
208         val userId: Int,
209         val flags: Int,
210         val trustGrantedMessages: MutableList<String>?
211     )
212 
213     val onTrustChangedCalls = mutableListOf<TrustChangedParams>()
214 
onTrustChangednull215     override fun onTrustChanged(
216         enabled: Boolean,
217         newlyUnlocked: Boolean,
218         userId: Int,
219         flags: Int,
220         trustGrantedMessages: MutableList<String>
221     ) {
222         onTrustChangedCalls += TrustChangedParams(
223             enabled, newlyUnlocked, userId, flags, trustGrantedMessages
224         )
225     }
226 
onTrustManagedChangednull227     override fun onTrustManagedChanged(enabled: Boolean, userId: Int) {
228         onTrustManagedChangedCount.compute(userId) { _: Int, curr: Int? ->
229             if (curr == null) 0 else curr + 1
230         }
231     }
232 }
233