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