1 /*
2  * Copyright (C) 2023 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.systemui.keyguard.data.repository
18 
19 import android.app.trust.TrustManager
20 import android.content.pm.UserInfo
21 import androidx.test.ext.junit.runners.AndroidJUnit4
22 import androidx.test.filters.SmallTest
23 import com.android.keyguard.logging.TrustRepositoryLogger
24 import com.android.systemui.SysuiTestCase
25 import com.android.systemui.coroutines.FlowValue
26 import com.android.systemui.coroutines.collectLastValue
27 import com.android.systemui.log.LogBuffer
28 import com.android.systemui.log.LogcatEchoTracker
29 import com.android.systemui.user.data.repository.FakeUserRepository
30 import com.android.systemui.util.mockito.whenever
31 import com.google.common.truth.Truth.assertThat
32 import kotlinx.coroutines.ExperimentalCoroutinesApi
33 import kotlinx.coroutines.test.TestScope
34 import kotlinx.coroutines.test.runCurrent
35 import kotlinx.coroutines.test.runTest
36 import org.junit.Before
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.mockito.ArgumentCaptor
40 import org.mockito.Captor
41 import org.mockito.Mock
42 import org.mockito.Mockito.mock
43 import org.mockito.Mockito.verify
44 import org.mockito.MockitoAnnotations
45 
46 @OptIn(ExperimentalCoroutinesApi::class)
47 @SmallTest
48 @RunWith(AndroidJUnit4::class)
49 @android.platform.test.annotations.EnabledOnRavenwood
50 class TrustRepositoryTest : SysuiTestCase() {
51     @Mock private lateinit var trustManager: TrustManager
52     @Captor private lateinit var listener: ArgumentCaptor<TrustManager.TrustListener>
53     private lateinit var userRepository: FakeUserRepository
54     private lateinit var testScope: TestScope
55     private val users = listOf(UserInfo(1, "user 1", 0), UserInfo(2, "user 1", 0))
56 
57     private lateinit var underTest: TrustRepository
58     private lateinit var isCurrentUserTrusted: FlowValue<Boolean?>
59     private lateinit var isCurrentUserTrustManaged: FlowValue<Boolean?>
60 
61     @Before
setUpnull62     fun setUp() {
63         MockitoAnnotations.initMocks(this)
64         testScope = TestScope()
65         userRepository = FakeUserRepository()
66         userRepository.setUserInfos(users)
67         val logger =
68             TrustRepositoryLogger(
69                 LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
70             )
71         underTest =
72             TrustRepositoryImpl(testScope.backgroundScope, userRepository, trustManager, logger)
73     }
74 
initnull75     fun TestScope.init() {
76         runCurrent()
77         verify(trustManager).registerTrustListener(listener.capture())
78         isCurrentUserTrustManaged = collectLastValue(underTest.isCurrentUserTrustManaged)
79         isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
80     }
81 
82     @Test
isCurrentUserTrustManaged_whenItChanges_emitsLatestValuenull83     fun isCurrentUserTrustManaged_whenItChanges_emitsLatestValue() =
84         testScope.runTest {
85             init()
86 
87             val currentUserId = users[0].id
88             userRepository.setSelectedUserInfo(users[0])
89 
90             listener.value.onTrustManagedChanged(true, currentUserId)
91             assertThat(isCurrentUserTrustManaged()).isTrue()
92 
93             listener.value.onTrustManagedChanged(false, currentUserId)
94 
95             assertThat(isCurrentUserTrustManaged()).isFalse()
96         }
97 
98     @Test
isCurrentUserTrustManaged_isFalse_byDefaultnull99     fun isCurrentUserTrustManaged_isFalse_byDefault() =
100         testScope.runTest {
101             runCurrent()
102 
103             assertThat(collectLastValue(underTest.isCurrentUserTrustManaged)()).isFalse()
104         }
105 
106     @Test
isCurrentUserTrustManaged_whenItChangesForDifferentUser_noopsnull107     fun isCurrentUserTrustManaged_whenItChangesForDifferentUser_noops() =
108         testScope.runTest {
109             init()
110             userRepository.setSelectedUserInfo(users[0])
111 
112             // current user's trust is managed.
113             listener.value.onTrustManagedChanged(true, users[0].id)
114             // some other user's trust is not managed.
115             listener.value.onTrustManagedChanged(false, users[1].id)
116 
117             assertThat(isCurrentUserTrustManaged()).isTrue()
118         }
119 
120     @Test
isCurrentUserTrustManaged_whenUserChangesWithoutRecentTrustChange_defaultsToFalsenull121     fun isCurrentUserTrustManaged_whenUserChangesWithoutRecentTrustChange_defaultsToFalse() =
122         testScope.runTest {
123             init()
124 
125             userRepository.setSelectedUserInfo(users[0])
126             listener.value.onTrustManagedChanged(true, users[0].id)
127 
128             userRepository.setSelectedUserInfo(users[1])
129 
130             assertThat(isCurrentUserTrustManaged()).isFalse()
131         }
132 
133     @Test
isCurrentUserTrustManaged_itChangesFirstBeforeUserInfoChanges_emitsCorrectValuenull134     fun isCurrentUserTrustManaged_itChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
135         testScope.runTest {
136             init()
137             userRepository.setSelectedUserInfo(users[1])
138 
139             listener.value.onTrustManagedChanged(true, users[0].id)
140             assertThat(isCurrentUserTrustManaged()).isFalse()
141 
142             userRepository.setSelectedUserInfo(users[0])
143 
144             assertThat(isCurrentUserTrustManaged()).isTrue()
145         }
146 
147     @Test
isCurrentUserTrusted_whenTrustChanges_emitsLatestValuenull148     fun isCurrentUserTrusted_whenTrustChanges_emitsLatestValue() =
149         testScope.runTest {
150             init()
151 
152             val currentUserId = users[0].id
153             userRepository.setSelectedUserInfo(users[0])
154 
155             listener.value.onTrustChanged(true, false, currentUserId, 0, emptyList())
156             assertThat(isCurrentUserTrusted()).isTrue()
157 
158             listener.value.onTrustChanged(false, false, currentUserId, 0, emptyList())
159 
160             assertThat(isCurrentUserTrusted()).isFalse()
161         }
162 
163     @Test
isCurrentUserTrusted_isFalse_byDefaultnull164     fun isCurrentUserTrusted_isFalse_byDefault() =
165         testScope.runTest {
166             runCurrent()
167 
168             val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
169 
170             assertThat(isCurrentUserTrusted()).isFalse()
171         }
172 
173     @Test
isCurrentUserTrusted_whenTrustChangesForDifferentUser_noopnull174     fun isCurrentUserTrusted_whenTrustChangesForDifferentUser_noop() =
175         testScope.runTest {
176             init()
177 
178             userRepository.setSelectedUserInfo(users[0])
179 
180             // current user is trusted.
181             listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
182             // some other user is not trusted.
183             listener.value.onTrustChanged(false, false, users[1].id, 0, emptyList())
184 
185             assertThat(isCurrentUserTrusted()).isTrue()
186         }
187 
188     @Test
isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValuenull189     fun isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValue() =
190         testScope.runTest {
191             init()
192             userRepository.setSelectedUserInfo(users[0])
193 
194             listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
195             assertThat(isCurrentUserTrusted()).isTrue()
196 
197             listener.value.onTrustChanged(false, true, users[0].id, 0, emptyList())
198             assertThat(isCurrentUserTrusted()).isFalse()
199         }
200 
201     @Test
isCurrentUserTrusted_whenUserChangesWithoutRecentTrustChange_defaultsToFalsenull202     fun isCurrentUserTrusted_whenUserChangesWithoutRecentTrustChange_defaultsToFalse() =
203         testScope.runTest {
204             init()
205 
206             userRepository.setSelectedUserInfo(users[0])
207             listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
208 
209             userRepository.setSelectedUserInfo(users[1])
210 
211             assertThat(isCurrentUserTrusted()).isFalse()
212         }
213 
214     @Test
isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValuenull215     fun isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
216         testScope.runTest {
217             init()
218 
219             listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
220             assertThat(isCurrentUserTrusted()).isFalse()
221 
222             userRepository.setSelectedUserInfo(users[0])
223 
224             assertThat(isCurrentUserTrusted()).isTrue()
225         }
226 
227     @Test
isCurrentUserActiveUnlockRunning_runningFirstBeforeUserInfoChanges_emitsCorrectValuenull228     fun isCurrentUserActiveUnlockRunning_runningFirstBeforeUserInfoChanges_emitsCorrectValue() =
229         testScope.runTest {
230             runCurrent()
231             verify(trustManager).registerTrustListener(listener.capture())
232             val isCurrentUserActiveUnlockRunning by
233                 collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
234             userRepository.setSelectedUserInfo(users[1])
235 
236             // active unlock running = true for users[0].id, but not the current user
237             listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
238             assertThat(isCurrentUserActiveUnlockRunning).isFalse()
239 
240             // current user is now users[0].id
241             userRepository.setSelectedUserInfo(users[0])
242             assertThat(isCurrentUserActiveUnlockRunning).isTrue()
243         }
244 
245     @Test
isCurrentUserActiveUnlockRunning_whenActiveUnlockRunningForCurrentUser_emitsNewValuenull246     fun isCurrentUserActiveUnlockRunning_whenActiveUnlockRunningForCurrentUser_emitsNewValue() =
247         testScope.runTest {
248             runCurrent()
249             verify(trustManager).registerTrustListener(listener.capture())
250             val isCurrentUserActiveUnlockRunning by
251                 collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
252             userRepository.setSelectedUserInfo(users[0])
253 
254             listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
255             assertThat(isCurrentUserActiveUnlockRunning).isTrue()
256 
257             listener.value.onIsActiveUnlockRunningChanged(false, users[0].id)
258             assertThat(isCurrentUserActiveUnlockRunning).isFalse()
259 
260             listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
261             assertThat(isCurrentUserActiveUnlockRunning).isTrue()
262         }
263 
264     @Test
isTrustUsuallyManaged_providesTheValueForCurrentUsernull265     fun isTrustUsuallyManaged_providesTheValueForCurrentUser() =
266         testScope.runTest {
267             runCurrent()
268             val trustUsuallyManaged by collectLastValue(underTest.isCurrentUserTrustUsuallyManaged)
269             whenever(trustManager.isTrustUsuallyManaged(users[0].id)).thenReturn(true)
270             whenever(trustManager.isTrustUsuallyManaged(users[1].id)).thenReturn(false)
271 
272             userRepository.setSelectedUserInfo(users[0])
273 
274             assertThat(trustUsuallyManaged).isTrue()
275             userRepository.setSelectedUserInfo(users[1])
276             assertThat(trustUsuallyManaged).isFalse()
277         }
278 }
279