Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 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 | |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 19 | import android.app.ActivityManager |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 20 | import android.app.AppOpsManager |
Fabian Kozynski | 8176539 | 2019-02-11 12:38:26 -0500 | [diff] [blame] | 21 | import android.content.Context |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 22 | import android.content.Intent |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 23 | import android.content.pm.UserInfo |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 24 | import android.os.Handler |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 25 | import android.os.UserHandle |
| 26 | import android.os.UserManager |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 27 | import android.provider.DeviceConfig |
| 28 | import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 29 | import android.testing.AndroidTestingRunner |
| 30 | import android.testing.TestableLooper |
| 31 | import android.testing.TestableLooper.RunWithLooper |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 32 | import androidx.test.filters.SmallTest |
| 33 | import com.android.internal.config.sysui.SystemUiDeviceConfigFlags |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 34 | import com.android.systemui.Dependency |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 35 | import com.android.systemui.R |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 36 | import com.android.systemui.SysuiTestCase |
| 37 | import com.android.systemui.appops.AppOpItem |
| 38 | import com.android.systemui.appops.AppOpsController |
Fabian Kozynski | 5ca7a51 | 2019-10-16 19:56:11 +0000 | [diff] [blame] | 39 | import com.android.systemui.broadcast.BroadcastDispatcher |
Fabian Kozynski | a6ff80b | 2019-02-12 11:32:44 -0500 | [diff] [blame] | 40 | import org.hamcrest.Matchers.hasItem |
| 41 | import org.hamcrest.Matchers.not |
| 42 | import org.hamcrest.Matchers.nullValue |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 43 | import org.junit.After |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 44 | import org.junit.Assert.assertEquals |
Fabian Kozynski | a6ff80b | 2019-02-12 11:32:44 -0500 | [diff] [blame] | 45 | import org.junit.Assert.assertThat |
| 46 | import org.junit.Assert.assertTrue |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 47 | import org.junit.Before |
Fabian Kozynski | cbd5895 | 2019-06-24 15:00:20 -0400 | [diff] [blame] | 48 | import org.junit.Ignore |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 49 | import org.junit.Test |
| 50 | import org.junit.runner.RunWith |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 51 | import org.mockito.ArgumentCaptor |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 52 | import org.mockito.ArgumentMatchers.any |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 53 | import org.mockito.ArgumentMatchers.anyBoolean |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 54 | import org.mockito.ArgumentMatchers.anyInt |
| 55 | import org.mockito.ArgumentMatchers.anyList |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 56 | import org.mockito.ArgumentMatchers.anyString |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 57 | import org.mockito.ArgumentMatchers.eq |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 58 | import org.mockito.Captor |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 59 | import org.mockito.Mock |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 60 | import org.mockito.Mockito.atLeastOnce |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 61 | import org.mockito.Mockito.doAnswer |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 62 | import org.mockito.Mockito.doReturn |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 63 | import org.mockito.Mockito.mock |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 64 | import org.mockito.Mockito.never |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 65 | import org.mockito.Mockito.reset |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 66 | import org.mockito.Mockito.verify |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 67 | import org.mockito.Mockito.verifyNoMoreInteractions |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 68 | import org.mockito.MockitoAnnotations |
| 69 | |
| 70 | @RunWith(AndroidTestingRunner::class) |
| 71 | @SmallTest |
| 72 | @RunWithLooper |
Fabian Kozynski | cbd5895 | 2019-06-24 15:00:20 -0400 | [diff] [blame] | 73 | @Ignore |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 74 | class PrivacyItemControllerTest : SysuiTestCase() { |
| 75 | |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 76 | companion object { |
| 77 | val CURRENT_USER_ID = ActivityManager.getCurrentUser() |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 78 | val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE |
| 79 | const val SYSTEM_UID = 1000 |
| 80 | const val TEST_PACKAGE_NAME = "test" |
| 81 | const val DEVICE_SERVICES_STRING = "Device services" |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 82 | const val TAG = "PrivacyItemControllerTest" |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 83 | fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 84 | } |
| 85 | |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 86 | @Mock |
| 87 | private lateinit var appOpsController: AppOpsController |
| 88 | @Mock |
| 89 | private lateinit var callback: PrivacyItemController.Callback |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 90 | @Mock |
| 91 | private lateinit var userManager: UserManager |
Fabian Kozynski | 5ca7a51 | 2019-10-16 19:56:11 +0000 | [diff] [blame] | 92 | @Mock |
| 93 | private lateinit var broadcastDispatcher: BroadcastDispatcher |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 94 | @Captor |
| 95 | private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>> |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 96 | @Captor |
| 97 | private lateinit var argCaptorCallback: ArgumentCaptor<AppOpsController.Callback> |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 98 | |
| 99 | private lateinit var testableLooper: TestableLooper |
| 100 | private lateinit var privacyItemController: PrivacyItemController |
Fabian Kozynski | 8176539 | 2019-02-11 12:38:26 -0500 | [diff] [blame] | 101 | private lateinit var handler: Handler |
| 102 | |
| 103 | fun PrivacyItemController(context: Context) = |
Fabian Kozynski | 5ca7a51 | 2019-10-16 19:56:11 +0000 | [diff] [blame] | 104 | PrivacyItemController(context, appOpsController, handler, handler, broadcastDispatcher) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 105 | |
| 106 | @Before |
| 107 | fun setup() { |
| 108 | MockitoAnnotations.initMocks(this) |
| 109 | testableLooper = TestableLooper.get(this) |
Fabian Kozynski | 8176539 | 2019-02-11 12:38:26 -0500 | [diff] [blame] | 110 | handler = Handler(testableLooper.looper) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 111 | |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 112 | appOpsController = mDependency.injectMockDependency(AppOpsController::class.java) |
Fabian Kozynski | 8176539 | 2019-02-11 12:38:26 -0500 | [diff] [blame] | 113 | mDependency.injectTestDependency(Dependency.BG_HANDLER, handler) |
| 114 | mDependency.injectTestDependency(Dependency.MAIN_HANDLER, handler) |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 115 | mContext.addMockSystemService(UserManager::class.java, userManager) |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 116 | mContext.getOrCreateTestableResources().addOverride(R.string.device_services, |
| 117 | DEVICE_SERVICES_STRING) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 118 | DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, |
| 119 | SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, |
| 120 | "true", false) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 121 | |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 122 | doReturn(listOf(object : UserInfo() { |
| 123 | init { |
| 124 | id = CURRENT_USER_ID |
| 125 | } |
| 126 | })).`when`(userManager).getProfiles(anyInt()) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 127 | |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 128 | privacyItemController = PrivacyItemController(mContext) |
| 129 | } |
| 130 | |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 131 | @After |
| 132 | fun tearDown() { |
| 133 | DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY) |
| 134 | } |
| 135 | |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 136 | @Test |
| 137 | fun testSetListeningTrueByAddingCallback() { |
| 138 | privacyItemController.addCallback(callback) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 139 | testableLooper.processAllMessages() |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 140 | verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), |
| 141 | any(AppOpsController.Callback::class.java)) |
| 142 | testableLooper.processAllMessages() |
| 143 | verify(callback).privacyChanged(anyList()) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 144 | } |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 145 | |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 146 | @Test |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 147 | fun testSetListeningFalseByRemovingLastCallback() { |
| 148 | privacyItemController.addCallback(callback) |
| 149 | testableLooper.processAllMessages() |
| 150 | verify(appOpsController, never()).removeCallback(any(IntArray::class.java), |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 151 | any(AppOpsController.Callback::class.java)) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 152 | privacyItemController.removeCallback(callback) |
| 153 | testableLooper.processAllMessages() |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 154 | verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS), |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 155 | any(AppOpsController.Callback::class.java)) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 156 | verify(callback).privacyChanged(emptyList()) |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | @Test |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 160 | fun testDistinctItems() { |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 161 | doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0), |
| 162 | AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1))) |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 163 | .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) |
| 164 | |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 165 | privacyItemController.addCallback(callback) |
Fabian Kozynski | 510585d | 2018-12-19 13:59:17 -0500 | [diff] [blame] | 166 | testableLooper.processAllMessages() |
| 167 | verify(callback).privacyChanged(capture(argCaptor)) |
| 168 | assertEquals(1, argCaptor.value.size) |
| 169 | } |
| 170 | |
| 171 | @Test |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 172 | fun testSystemApps() { |
| 173 | doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME, |
| 174 | 0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 175 | privacyItemController.addCallback(callback) |
Fabian Kozynski | 508422b | 2018-12-20 10:58:17 -0500 | [diff] [blame] | 176 | testableLooper.processAllMessages() |
| 177 | verify(callback).privacyChanged(capture(argCaptor)) |
| 178 | assertEquals(1, argCaptor.value.size) |
| 179 | assertEquals(context.getString(R.string.device_services), |
| 180 | argCaptor.value[0].application.applicationName) |
| 181 | } |
| 182 | |
| 183 | @Test |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 184 | fun testRegisterReceiver_allUsers() { |
Fabian Kozynski | 5ca7a51 | 2019-10-16 19:56:11 +0000 | [diff] [blame] | 185 | privacyItemController.addCallback(callback) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 186 | testableLooper.processAllMessages() |
Fabian Kozynski | 5ca7a51 | 2019-10-16 19:56:11 +0000 | [diff] [blame] | 187 | verify(broadcastDispatcher, atLeastOnce()).registerReceiver( |
| 188 | eq(privacyItemController.userSwitcherReceiver), any(), eq(null), eq(UserHandle.ALL)) |
| 189 | verify(broadcastDispatcher, never()) |
| 190 | .unregisterReceiver(eq(privacyItemController.userSwitcherReceiver)) |
Fabian Kozynski | b5625ac | 2018-11-21 08:56:55 -0500 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | @Test |
| 194 | fun testReceiver_ACTION_USER_FOREGROUND() { |
| 195 | privacyItemController.userSwitcherReceiver.onReceive(context, |
| 196 | Intent(Intent.ACTION_USER_FOREGROUND)) |
| 197 | verify(userManager).getProfiles(anyInt()) |
| 198 | } |
| 199 | |
| 200 | @Test |
| 201 | fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() { |
| 202 | privacyItemController.userSwitcherReceiver.onReceive(context, |
| 203 | Intent(Intent.ACTION_MANAGED_PROFILE_ADDED)) |
| 204 | verify(userManager).getProfiles(anyInt()) |
| 205 | } |
| 206 | |
| 207 | @Test |
| 208 | fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() { |
| 209 | privacyItemController.userSwitcherReceiver.onReceive(context, |
| 210 | Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED)) |
| 211 | verify(userManager).getProfiles(anyInt()) |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 212 | } |
Fabian Kozynski | 04f83eb | 2019-01-22 10:38:40 -0500 | [diff] [blame] | 213 | |
| 214 | @Test |
| 215 | fun testAddMultipleCallbacks() { |
| 216 | val otherCallback = mock(PrivacyItemController.Callback::class.java) |
| 217 | privacyItemController.addCallback(callback) |
| 218 | testableLooper.processAllMessages() |
| 219 | verify(callback).privacyChanged(anyList()) |
| 220 | |
| 221 | privacyItemController.addCallback(otherCallback) |
| 222 | testableLooper.processAllMessages() |
| 223 | verify(otherCallback).privacyChanged(anyList()) |
| 224 | // Adding a callback should not unnecessarily call previous ones |
| 225 | verifyNoMoreInteractions(callback) |
| 226 | } |
| 227 | |
| 228 | @Test |
| 229 | fun testMultipleCallbacksAreUpdated() { |
| 230 | doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) |
| 231 | |
| 232 | val otherCallback = mock(PrivacyItemController.Callback::class.java) |
| 233 | privacyItemController.addCallback(callback) |
| 234 | privacyItemController.addCallback(otherCallback) |
| 235 | testableLooper.processAllMessages() |
| 236 | reset(callback) |
| 237 | reset(otherCallback) |
| 238 | |
| 239 | verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback)) |
| 240 | argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) |
| 241 | testableLooper.processAllMessages() |
| 242 | verify(callback).privacyChanged(anyList()) |
| 243 | verify(otherCallback).privacyChanged(anyList()) |
| 244 | } |
| 245 | |
| 246 | @Test |
| 247 | fun testRemoveCallback() { |
| 248 | doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) |
| 249 | val otherCallback = mock(PrivacyItemController.Callback::class.java) |
| 250 | privacyItemController.addCallback(callback) |
| 251 | privacyItemController.addCallback(otherCallback) |
| 252 | testableLooper.processAllMessages() |
| 253 | reset(callback) |
| 254 | reset(otherCallback) |
| 255 | |
| 256 | verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback)) |
| 257 | privacyItemController.removeCallback(callback) |
| 258 | argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) |
| 259 | testableLooper.processAllMessages() |
| 260 | verify(callback, never()).privacyChanged(anyList()) |
| 261 | verify(otherCallback).privacyChanged(anyList()) |
| 262 | } |
Fabian Kozynski | a6ff80b | 2019-02-12 11:32:44 -0500 | [diff] [blame] | 263 | |
| 264 | @Test |
| 265 | fun testListShouldNotHaveNull() { |
| 266 | doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), |
| 267 | AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) |
| 268 | .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) |
| 269 | privacyItemController.addCallback(callback) |
| 270 | testableLooper.processAllMessages() |
| 271 | |
| 272 | verify(callback).privacyChanged(capture(argCaptor)) |
| 273 | assertEquals(1, argCaptor.value.size) |
| 274 | assertThat(argCaptor.value, not(hasItem(nullValue()))) |
| 275 | } |
| 276 | |
| 277 | @Test |
| 278 | fun testListShouldBeCopy() { |
| 279 | val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, |
| 280 | PrivacyApplication("", TEST_UID, mContext))) |
| 281 | privacyItemController.privacyList = list |
Fabian Kozynski | 7209010 | 2019-03-04 10:55:55 -0500 | [diff] [blame] | 282 | val privacyList = privacyItemController.privacyList |
| 283 | assertEquals(list, privacyList) |
| 284 | assertTrue(list !== privacyList) |
Fabian Kozynski | a6ff80b | 2019-02-12 11:32:44 -0500 | [diff] [blame] | 285 | } |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 286 | |
| 287 | @Test |
| 288 | fun testNotListeningWhenIndicatorsDisabled() { |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 289 | val properties = getProperties( |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 290 | DeviceConfig.NAMESPACE_PRIVACY, |
| 291 | SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 292 | false) |
| 293 | privacyItemController.devicePropertiesChangedListener.onPropertiesChanged(properties) |
Fabian Kozynski | 16b2699 | 2019-05-06 10:18:41 -0400 | [diff] [blame] | 294 | privacyItemController.addCallback(callback) |
| 295 | testableLooper.processAllMessages() |
| 296 | verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), |
| 297 | any(AppOpsController.Callback::class.java)) |
| 298 | } |
Matt Pape | cb88879 | 2019-05-22 15:32:32 -0700 | [diff] [blame] | 299 | |
| 300 | private fun getProperties(namespace: String, name: String, value: Boolean): |
| 301 | DeviceConfig.Properties { |
| 302 | val properties = mock<DeviceConfig.Properties>(DeviceConfig.Properties::class.java) |
| 303 | doReturn(namespace).`when`(properties).getNamespace() |
| 304 | doReturn(setOf(name)).`when`(properties).getKeyset() |
| 305 | doAnswer { |
| 306 | val key: String = it.getArgument(0) |
| 307 | val defaultValue: Boolean = it.getArgument(1) |
| 308 | if (name.equals(key, ignoreCase = true)) { |
| 309 | value |
| 310 | } else { |
| 311 | defaultValue |
| 312 | } |
| 313 | }.`when`(properties).getBoolean(anyString(), anyBoolean()) |
| 314 | return properties |
| 315 | } |
Fabian Kozynski | 8d06c71 | 2018-11-07 10:33:02 -0500 | [diff] [blame] | 316 | } |