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 package com.android.systemui.smartspace
17 
18 import android.app.smartspace.SmartspaceTarget
19 import android.content.ContentResolver
20 import android.database.ContentObserver
21 import android.net.Uri
22 import android.os.Handler
23 import android.os.UserHandle
24 import android.provider.Settings
25 import android.testing.AndroidTestingRunner
26 import android.testing.TestableLooper
27 import androidx.test.filters.SmallTest
28 import com.android.systemui.SysuiTestCase
29 import com.android.systemui.settings.UserTracker
30 import com.android.systemui.smartspace.filters.LockscreenAndDreamTargetFilter
31 import com.android.systemui.util.concurrency.Execution
32 import com.android.systemui.util.mockito.any
33 import com.android.systemui.util.mockito.eq
34 import com.android.systemui.util.mockito.withArgCaptor
35 import com.android.systemui.util.settings.SecureSettings
36 import com.google.common.truth.Truth.assertThat
37 import java.util.concurrent.Executor
38 import org.junit.Before
39 import org.junit.Test
40 import org.junit.runner.RunWith
41 import org.mockito.ArgumentCaptor
42 import org.mockito.ArgumentMatchers.anyBoolean
43 import org.mockito.ArgumentMatchers.anyInt
44 import org.mockito.Mock
45 import org.mockito.Mockito.atLeast
46 import org.mockito.Mockito.clearInvocations
47 import org.mockito.Mockito.mock
48 import org.mockito.Mockito.verify
49 import org.mockito.Mockito.`when`
50 import org.mockito.MockitoAnnotations
51 
52 @SmallTest
53 @TestableLooper.RunWithLooper
54 @RunWith(AndroidTestingRunner::class)
55 class LockscreenAndDreamTargetFilterTest : SysuiTestCase() {
56     @Mock
57     private lateinit var secureSettings: SecureSettings
58 
59     @Mock
60     private lateinit var userTracker: UserTracker
61 
62     @Mock
63     private lateinit var execution: Execution
64 
65     @Mock
66     private lateinit var handler: Handler
67 
68     @Mock
69     private lateinit var contentResolver: ContentResolver
70 
71     @Mock
72     private lateinit var uiExecution: Executor
73 
74     @Mock
75     private lateinit var userHandle: UserHandle
76 
77     @Mock
78     private lateinit var listener: SmartspaceTargetFilter.Listener
79 
80     @Mock
81     private lateinit var lockScreenAllowPrivateNotificationsUri: Uri
82 
83     @Before
84     fun setup() {
85         MockitoAnnotations.initMocks(this)
86         `when`(userTracker.userHandle).thenReturn(userHandle)
87         `when`(secureSettings
88                 .getUriFor(eq(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS)))
89                 .thenReturn(lockScreenAllowPrivateNotificationsUri)
90     }
91 
92     /**
93      * Ensures {@link Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS} is
94      * tracked.
95      */
96     @Test
97     fun testLockscreenAllowPrivateNotifications() {
98         var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
99         `when`(secureSettings
100                 .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
101                 .thenReturn(0)
102         var filter = LockscreenAndDreamTargetFilter(secureSettings, userTracker, execution, handler,
103                 contentResolver, uiExecution)
104 
105         filter.addListener(listener)
106         var smartspaceTarget = mock(SmartspaceTarget::class.java)
107         `when`(smartspaceTarget.userHandle).thenReturn(userHandle)
108         `when`(smartspaceTarget.isSensitive).thenReturn(true)
109         assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isFalse()
110 
111         var settingCaptor = ArgumentCaptor.forClass(ContentObserver::class.java)
112 
113         verify(contentResolver).registerContentObserver(eq(lockScreenAllowPrivateNotificationsUri),
114                 anyBoolean(), settingCaptor.capture(), anyInt())
115 
116         `when`(secureSettings
117                 .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
118                 .thenReturn(1)
119 
120         clearInvocations(listener)
121         settingCaptor.value.onChange(false, mock(Uri::class.java))
122         verify(listener, atLeast(1)).onCriteriaChanged()
123         assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isTrue()
124     }
125 
126     /**
127      * Ensures user switches are tracked.
128      */
129     @Test
130     fun testUserSwitchCallback() {
131         var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
132         `when`(secureSettings
133                 .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
134                 .thenReturn(0)
135         var filter = LockscreenAndDreamTargetFilter(secureSettings, userTracker, execution, handler,
136                 contentResolver, uiExecution)
137 
138         filter.addListener(listener)
139 
140         var userTrackerCallback = withArgCaptor<UserTracker.Callback> {
141             verify(userTracker).addCallback(capture(), any())
142         }
143 
144         clearInvocations(listener)
145         userTrackerCallback.onUserChanged(0, context)
146 
147         verify(listener).onCriteriaChanged()
148     }
149 }
150