1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15package com.android.systemui.qs; 16 17import static junit.framework.Assert.assertEquals; 18 19import static org.mockito.ArgumentMatchers.anyInt; 20import static org.mockito.Mockito.mock; 21import static org.mockito.Mockito.when; 22 23import android.content.Context; 24import android.content.pm.UserInfo; 25import android.os.Handler; 26import android.os.Looper; 27import android.os.UserManager; 28import android.provider.Settings; 29import android.support.test.runner.AndroidJUnit4; 30import android.test.suitebuilder.annotation.SmallTest; 31import android.text.SpannableStringBuilder; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35import android.widget.TextView; 36 37import com.android.systemui.Dependency; 38import com.android.systemui.R; 39import com.android.systemui.SysuiTestCase; 40import com.android.systemui.statusbar.policy.SecurityController; 41import android.testing.LayoutInflaterBuilder; 42import android.testing.TestableImageView; 43 44import org.junit.Before; 45import org.junit.Test; 46import org.junit.runner.RunWith; 47import org.mockito.Mockito; 48 49/* 50 * Compile and run the whole SystemUI test suite: 51 runtest --path frameworks/base/packages/SystemUI/tests 52 * 53 * Compile and run just this class: 54 runtest --path \ 55 frameworks/base/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java 56*/ 57 58@SmallTest 59@RunWith(AndroidJUnit4.class) 60public class QSSecurityFooterTest extends SysuiTestCase { 61 62 private final String MANAGING_ORGANIZATION = "organization"; 63 private final String DEVICE_OWNER_PACKAGE = "TestDPC"; 64 private final String VPN_PACKAGE = "TestVPN"; 65 private final String VPN_PACKAGE_2 = "TestVPN 2"; 66 67 private ViewGroup mRootView; 68 private TextView mFooterText; 69 private TestableImageView mFooterIcon; 70 private QSSecurityFooter mFooter; 71 private SecurityController mSecurityController = mock(SecurityController.class); 72 private UserManager mUserManager; 73 74 @Before 75 public void setUp() { 76 mDependency.injectTestDependency(SecurityController.class, mSecurityController); 77 mDependency.injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper()); 78 mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, 79 new LayoutInflaterBuilder(mContext) 80 .replace("ImageView", TestableImageView.class) 81 .build()); 82 mUserManager = Mockito.mock(UserManager.class); 83 mContext.addMockSystemService(Context.USER_SERVICE, mUserManager); 84 Handler h = new Handler(Looper.getMainLooper()); 85 h.post(() -> mFooter = new QSSecurityFooter(null, mContext)); 86 waitForIdleSync(h); 87 mRootView = (ViewGroup) mFooter.getView(); 88 mFooterText = (TextView) mRootView.findViewById(R.id.footer_text); 89 mFooterIcon = (TestableImageView) mRootView.findViewById(R.id.footer_icon); 90 mFooter.setHostEnvironment(null); 91 } 92 93 @Test 94 public void testUnmanaged() { 95 when(mSecurityController.isDeviceManaged()).thenReturn(false); 96 mFooter.refreshState(); 97 98 waitForIdleSync(mFooter.mHandler); 99 assertEquals(View.GONE, mRootView.getVisibility()); 100 } 101 102 @Test 103 public void testManagedNoOwnerName() { 104 when(mSecurityController.isDeviceManaged()).thenReturn(true); 105 when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null); 106 mFooter.refreshState(); 107 108 waitForIdleSync(mFooter.mHandler); 109 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management), 110 mFooterText.getText()); 111 assertEquals(View.VISIBLE, mRootView.getVisibility()); 112 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 113 // -1 == never set. 114 assertEquals(-1, mFooterIcon.getLastImageResource()); 115 } 116 117 @Test 118 public void testManagedOwnerName() { 119 when(mSecurityController.isDeviceManaged()).thenReturn(true); 120 when(mSecurityController.getDeviceOwnerOrganizationName()) 121 .thenReturn(MANAGING_ORGANIZATION); 122 mFooter.refreshState(); 123 124 waitForIdleSync(mFooter.mHandler); 125 assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management, 126 MANAGING_ORGANIZATION), 127 mFooterText.getText()); 128 assertEquals(View.VISIBLE, mRootView.getVisibility()); 129 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 130 // -1 == never set. 131 assertEquals(-1, mFooterIcon.getLastImageResource()); 132 } 133 134 @Test 135 public void testManagedDemoMode() { 136 when(mSecurityController.isDeviceManaged()).thenReturn(true); 137 when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null); 138 final UserInfo mockUserInfo = Mockito.mock(UserInfo.class); 139 when(mockUserInfo.isDemo()).thenReturn(true); 140 when(mUserManager.getUserInfo(anyInt())).thenReturn(mockUserInfo); 141 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 1); 142 143 mFooter.refreshState(); 144 145 waitForIdleSync(mFooter.mHandler); 146 assertEquals(View.GONE, mRootView.getVisibility()); 147 } 148 149 @Test 150 public void testNetworkLoggingEnabled() { 151 when(mSecurityController.isDeviceManaged()).thenReturn(true); 152 when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); 153 mFooter.refreshState(); 154 155 waitForIdleSync(mFooter.mHandler); 156 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), 157 mFooterText.getText()); 158 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 159 // -1 == never set. 160 assertEquals(-1, mFooterIcon.getLastImageResource()); 161 162 // Same situation, but with organization name set 163 when(mSecurityController.getDeviceOwnerOrganizationName()) 164 .thenReturn(MANAGING_ORGANIZATION); 165 mFooter.refreshState(); 166 167 waitForIdleSync(mFooter.mHandler); 168 assertEquals(mContext.getString( 169 R.string.quick_settings_disclosure_named_management_monitoring, 170 MANAGING_ORGANIZATION), 171 mFooterText.getText()); 172 } 173 174 @Test 175 public void testManagedCACertsInstalled() { 176 when(mSecurityController.isDeviceManaged()).thenReturn(true); 177 when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); 178 mFooter.refreshState(); 179 180 waitForIdleSync(mFooter.mHandler); 181 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), 182 mFooterText.getText()); 183 } 184 185 @Test 186 public void testManagedOneVpnEnabled() { 187 when(mSecurityController.isDeviceManaged()).thenReturn(true); 188 when(mSecurityController.isVpnEnabled()).thenReturn(true); 189 when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); 190 mFooter.refreshState(); 191 192 waitForIdleSync(mFooter.mHandler); 193 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_named_vpn, 194 VPN_PACKAGE), 195 mFooterText.getText()); 196 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 197 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 198 199 // Same situation, but with organization name set 200 when(mSecurityController.getDeviceOwnerOrganizationName()) 201 .thenReturn(MANAGING_ORGANIZATION); 202 mFooter.refreshState(); 203 204 waitForIdleSync(mFooter.mHandler); 205 assertEquals(mContext.getString( 206 R.string.quick_settings_disclosure_named_management_named_vpn, 207 MANAGING_ORGANIZATION, VPN_PACKAGE), 208 mFooterText.getText()); 209 } 210 211 @Test 212 public void testManagedTwoVpnsEnabled() { 213 when(mSecurityController.isDeviceManaged()).thenReturn(true); 214 when(mSecurityController.isVpnEnabled()).thenReturn(true); 215 when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); 216 when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); 217 mFooter.refreshState(); 218 219 waitForIdleSync(mFooter.mHandler); 220 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_vpns), 221 mFooterText.getText()); 222 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 223 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 224 225 // Same situation, but with organization name set 226 when(mSecurityController.getDeviceOwnerOrganizationName()) 227 .thenReturn(MANAGING_ORGANIZATION); 228 mFooter.refreshState(); 229 230 waitForIdleSync(mFooter.mHandler); 231 assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management_vpns, 232 MANAGING_ORGANIZATION), 233 mFooterText.getText()); 234 } 235 236 @Test 237 public void testNetworkLoggingAndVpnEnabled() { 238 when(mSecurityController.isDeviceManaged()).thenReturn(true); 239 when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); 240 when(mSecurityController.isVpnEnabled()).thenReturn(true); 241 when(mSecurityController.getPrimaryVpnName()).thenReturn("VPN Test App"); 242 mFooter.refreshState(); 243 244 waitForIdleSync(mFooter.mHandler); 245 assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); 246 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 247 assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), 248 mFooterText.getText()); 249 } 250 251 @Test 252 public void testWorkProfileCACertsInstalled() { 253 when(mSecurityController.isDeviceManaged()).thenReturn(false); 254 when(mSecurityController.hasCACertInWorkProfile()).thenReturn(true); 255 mFooter.refreshState(); 256 257 waitForIdleSync(mFooter.mHandler); 258 // -1 == never set. 259 assertEquals(-1, mFooterIcon.getLastImageResource()); 260 assertEquals(mContext.getString( 261 R.string.quick_settings_disclosure_managed_profile_monitoring), 262 mFooterText.getText()); 263 264 // Same situation, but with organization name set 265 when(mSecurityController.getWorkProfileOrganizationName()) 266 .thenReturn(MANAGING_ORGANIZATION); 267 mFooter.refreshState(); 268 269 waitForIdleSync(mFooter.mHandler); 270 assertEquals(mContext.getString( 271 R.string.quick_settings_disclosure_named_managed_profile_monitoring, 272 MANAGING_ORGANIZATION), 273 mFooterText.getText()); 274 } 275 276 @Test 277 public void testCACertsInstalled() { 278 when(mSecurityController.isDeviceManaged()).thenReturn(false); 279 when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); 280 mFooter.refreshState(); 281 282 waitForIdleSync(mFooter.mHandler); 283 // -1 == never set. 284 assertEquals(-1, mFooterIcon.getLastImageResource()); 285 assertEquals(mContext.getString(R.string.quick_settings_disclosure_monitoring), 286 mFooterText.getText()); 287 } 288 289 @Test 290 public void testTwoVpnsEnabled() { 291 when(mSecurityController.isVpnEnabled()).thenReturn(true); 292 when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); 293 when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); 294 mFooter.refreshState(); 295 296 waitForIdleSync(mFooter.mHandler); 297 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 298 assertEquals(mContext.getString(R.string.quick_settings_disclosure_vpns), 299 mFooterText.getText()); 300 } 301 302 @Test 303 public void testWorkProfileVpnEnabled() { 304 when(mSecurityController.isVpnEnabled()).thenReturn(true); 305 when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); 306 mFooter.refreshState(); 307 308 waitForIdleSync(mFooter.mHandler); 309 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 310 assertEquals(mContext.getString( 311 R.string.quick_settings_disclosure_managed_profile_named_vpn, 312 VPN_PACKAGE_2), 313 mFooterText.getText()); 314 } 315 316 @Test 317 public void testVpnEnabled() { 318 when(mSecurityController.isVpnEnabled()).thenReturn(true); 319 when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); 320 mFooter.refreshState(); 321 322 waitForIdleSync(mFooter.mHandler); 323 assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); 324 assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_vpn, 325 VPN_PACKAGE), 326 mFooterText.getText()); 327 328 when(mSecurityController.hasWorkProfile()).thenReturn(true); 329 mFooter.refreshState(); 330 331 waitForIdleSync(mFooter.mHandler); 332 assertEquals(mContext.getString( 333 R.string.quick_settings_disclosure_personal_profile_named_vpn, 334 VPN_PACKAGE), 335 mFooterText.getText()); 336 } 337 338 @Test 339 public void testGetManagementMessage() { 340 assertEquals(null, mFooter.getManagementMessage(false, MANAGING_ORGANIZATION)); 341 assertEquals(mContext.getString(R.string.monitoring_description_named_management, 342 MANAGING_ORGANIZATION), 343 mFooter.getManagementMessage(true, MANAGING_ORGANIZATION)); 344 assertEquals(mContext.getString(R.string.monitoring_description_management), 345 mFooter.getManagementMessage(true, null)); 346 } 347 348 @Test 349 public void testGetCaCertsMessage() { 350 assertEquals(null, mFooter.getCaCertsMessage(true, false, false)); 351 assertEquals(null, mFooter.getCaCertsMessage(false, false, false)); 352 assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate), 353 mFooter.getCaCertsMessage(true, true, true)); 354 assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate), 355 mFooter.getCaCertsMessage(true, false, true)); 356 assertEquals(mContext.getString( 357 R.string.monitoring_description_managed_profile_ca_certificate), 358 mFooter.getCaCertsMessage(false, false, true)); 359 assertEquals(mContext.getString( 360 R.string.monitoring_description_ca_certificate), 361 mFooter.getCaCertsMessage(false, true, false)); 362 } 363 364 @Test 365 public void testGetNetworkLoggingMessage() { 366 assertEquals(null, mFooter.getNetworkLoggingMessage(false)); 367 assertEquals(mContext.getString(R.string.monitoring_description_management_network_logging), 368 mFooter.getNetworkLoggingMessage(true)); 369 } 370 371 @Test 372 public void testGetVpnMessage() { 373 assertEquals(null, mFooter.getVpnMessage(true, true, null, null)); 374 assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns, 375 VPN_PACKAGE, VPN_PACKAGE_2)), 376 mFooter.getVpnMessage(true, true, VPN_PACKAGE, VPN_PACKAGE_2)); 377 assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns, 378 VPN_PACKAGE, VPN_PACKAGE_2)), 379 mFooter.getVpnMessage(false, true, VPN_PACKAGE, VPN_PACKAGE_2)); 380 assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn, 381 VPN_PACKAGE)), 382 mFooter.getVpnMessage(true, false, VPN_PACKAGE, null)); 383 assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn, 384 VPN_PACKAGE)), 385 mFooter.getVpnMessage(false, false, VPN_PACKAGE, null)); 386 assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn, 387 VPN_PACKAGE_2)), 388 mFooter.getVpnMessage(true, true, null, VPN_PACKAGE_2)); 389 assertEquals(addLink(mContext.getString( 390 R.string.monitoring_description_managed_profile_named_vpn, 391 VPN_PACKAGE_2)), 392 mFooter.getVpnMessage(false, true, null, VPN_PACKAGE_2)); 393 assertEquals(addLink(mContext.getString( 394 R.string.monitoring_description_personal_profile_named_vpn, 395 VPN_PACKAGE)), 396 mFooter.getVpnMessage(false, true, VPN_PACKAGE, null)); 397 } 398 399 @Test 400 public void testConfigSubtitleVisibility() { 401 View view = LayoutInflater.from(mContext) 402 .inflate(R.layout.quick_settings_footer_dialog, null); 403 404 // Device Management subtitle should be shown when there is Device Management section only 405 // Other sections visibility will be set somewhere else so it will not be tested here 406 mFooter.configSubtitleVisibility(true, false, false, false, view); 407 assertEquals(View.VISIBLE, 408 view.findViewById(R.id.device_management_subtitle).getVisibility()); 409 410 // If there are multiple sections, all subtitles should be shown 411 mFooter.configSubtitleVisibility(true, true, false, false, view); 412 assertEquals(View.VISIBLE, 413 view.findViewById(R.id.device_management_subtitle).getVisibility()); 414 assertEquals(View.VISIBLE, 415 view.findViewById(R.id.ca_certs_subtitle).getVisibility()); 416 417 // If there are multiple sections, all subtitles should be shown 418 mFooter.configSubtitleVisibility(true, true, true, true, view); 419 assertEquals(View.VISIBLE, 420 view.findViewById(R.id.device_management_subtitle).getVisibility()); 421 assertEquals(View.VISIBLE, 422 view.findViewById(R.id.ca_certs_subtitle).getVisibility()); 423 assertEquals(View.VISIBLE, 424 view.findViewById(R.id.network_logging_subtitle).getVisibility()); 425 assertEquals(View.VISIBLE, 426 view.findViewById(R.id.vpn_subtitle).getVisibility()); 427 428 // If there are multiple sections, all subtitles should be shown, event if there is no 429 // Device Management section 430 mFooter.configSubtitleVisibility(false, true, true, true, view); 431 assertEquals(View.VISIBLE, 432 view.findViewById(R.id.ca_certs_subtitle).getVisibility()); 433 assertEquals(View.VISIBLE, 434 view.findViewById(R.id.network_logging_subtitle).getVisibility()); 435 assertEquals(View.VISIBLE, 436 view.findViewById(R.id.vpn_subtitle).getVisibility()); 437 438 // If there is only 1 section, the title should be hidden 439 mFooter.configSubtitleVisibility(false, true, false, false, view); 440 assertEquals(View.GONE, 441 view.findViewById(R.id.ca_certs_subtitle).getVisibility()); 442 mFooter.configSubtitleVisibility(false, false, true, false, view); 443 assertEquals(View.GONE, 444 view.findViewById(R.id.network_logging_subtitle).getVisibility()); 445 mFooter.configSubtitleVisibility(false, false, false, true, view); 446 assertEquals(View.GONE, 447 view.findViewById(R.id.vpn_subtitle).getVisibility()); 448 } 449 450 private CharSequence addLink(CharSequence description) { 451 final SpannableStringBuilder message = new SpannableStringBuilder(); 452 message.append(description); 453 message.append(mContext.getString(R.string.monitoring_description_vpn_settings_separator)); 454 message.append(mContext.getString(R.string.monitoring_description_vpn_settings), 455 mFooter.new VpnSpan(), 0); 456 return message; 457 } 458} 459