1 /*
2  * Copyright (C) 2020 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.privacy
18 
19 import android.provider.DeviceConfig
20 import androidx.test.ext.junit.runners.AndroidJUnit4
21 import androidx.test.filters.SmallTest
22 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
23 import com.android.systemui.SysuiTestCase
24 import com.android.systemui.dump.DumpManager
25 import com.android.systemui.util.DeviceConfigProxy
26 import com.android.systemui.util.DeviceConfigProxyFake
27 import com.android.systemui.util.concurrency.FakeExecutor
28 import com.android.systemui.util.time.FakeSystemClock
29 import org.junit.Assert.assertFalse
30 import org.junit.Assert.assertTrue
31 import org.junit.Before
32 import org.junit.Test
33 import org.junit.runner.RunWith
34 import org.mockito.Mock
35 import org.mockito.Mockito.atLeastOnce
36 import org.mockito.Mockito.never
37 import org.mockito.Mockito.verify
38 import org.mockito.MockitoAnnotations
39 
40 @RunWith(AndroidJUnit4::class)
41 @SmallTest
42 class PrivacyConfigFlagsTest : SysuiTestCase() {
43     companion object {
44         private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED
45         private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED
46         private const val MEDIA_PROJECTION =
47                 SystemUiDeviceConfigFlags.PROPERTY_MEDIA_PROJECTION_INDICATORS_ENABLED
48     }
49 
50     private lateinit var privacyConfig: PrivacyConfig
51 
52     @Mock
53     private lateinit var callback: PrivacyConfig.Callback
54     @Mock
55     private lateinit var dumpManager: DumpManager
56 
57     private lateinit var executor: FakeExecutor
58     private lateinit var deviceConfigProxy: DeviceConfigProxy
59 
createPrivacyConfignull60     fun createPrivacyConfig(): PrivacyConfig {
61         return PrivacyConfig(
62                 executor,
63                 deviceConfigProxy,
64                 dumpManager)
65     }
66 
67     @Before
setupnull68     fun setup() {
69         MockitoAnnotations.initMocks(this)
70         executor = FakeExecutor(FakeSystemClock())
71         deviceConfigProxy = DeviceConfigProxyFake()
72 
73         privacyConfig = createPrivacyConfig()
74         privacyConfig.addCallback(callback)
75 
76         executor.runAllReady()
77     }
78 
79     @Test
testMicCameraListeningByDefaultnull80     fun testMicCameraListeningByDefault() {
81         assertTrue(privacyConfig.micCameraAvailable)
82     }
83 
84     @Test
testMicCameraChangednull85     fun testMicCameraChanged() {
86         changeMicCamera(false) // default is true
87         executor.runAllReady()
88 
89         verify(callback).onFlagMicCameraChanged(false)
90 
91         assertFalse(privacyConfig.micCameraAvailable)
92     }
93 
94     @Test
testMediaProjectionChangednull95     fun testMediaProjectionChanged() {
96         changeMediaProjection(false) // default is true
97         executor.runAllReady()
98 
99         verify(callback).onFlagMediaProjectionChanged(false)
100 
101         assertFalse(privacyConfig.mediaProjectionAvailable)
102     }
103 
104     @Test
testLocationChangednull105     fun testLocationChanged() {
106         changeLocation(true)
107         executor.runAllReady()
108 
109         verify(callback).onFlagLocationChanged(true)
110         assertTrue(privacyConfig.locationAvailable)
111     }
112 
113     @Test
testMicCamAndLocationChangednull114     fun testMicCamAndLocationChanged() {
115         changeLocation(true)
116         changeMicCamera(false)
117         executor.runAllReady()
118 
119         verify(callback, atLeastOnce()).onFlagLocationChanged(true)
120         verify(callback, atLeastOnce()).onFlagMicCameraChanged(false)
121 
122         assertTrue(privacyConfig.locationAvailable)
123         assertFalse(privacyConfig.micCameraAvailable)
124     }
125 
126     @Test
testMicDeleted_stillAvailablenull127     fun testMicDeleted_stillAvailable() {
128         changeMicCamera(true)
129         executor.runAllReady()
130         changeMicCamera(null)
131         executor.runAllReady()
132 
133         verify(callback, never()).onFlagMicCameraChanged(false)
134         assertTrue(privacyConfig.micCameraAvailable)
135     }
136 
changeMicCameranull137     private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value)
138     private fun changeLocation(value: Boolean?) = changeProperty(LOCATION, value)
139     private fun changeMediaProjection(value: Boolean?) = changeProperty(MEDIA_PROJECTION, value)
140 
141     private fun changeProperty(name: String, value: Boolean?) {
142         deviceConfigProxy.setProperty(
143                 DeviceConfig.NAMESPACE_PRIVACY,
144                 name,
145                 value?.toString(),
146                 false
147         )
148     }
149 }
150