1 /* 2 * Copyright (C) 2016 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.settings.enterprise; 18 19 import android.app.Application; 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.content.res.XmlResourceParser; 23 24 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 25 import com.android.settings.R; 26 import com.android.settings.SettingsRobolectricTestRunner; 27 import com.android.settings.TestConfig; 28 import com.android.settings.core.DynamicAvailabilityPreferenceController; 29 import com.android.settings.core.PreferenceController; 30 import com.android.settings.testutils.FakeFeatureFactory; 31 32 import org.junit.Before; 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 import org.mockito.Answers; 36 import org.mockito.Mock; 37 import org.mockito.MockitoAnnotations; 38 import org.robolectric.RuntimeEnvironment; 39 import org.robolectric.annotation.Config; 40 import org.robolectric.shadows.ShadowApplication; 41 import org.xmlpull.v1.XmlPullParser; 42 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.Set; 46 47 import static com.google.common.truth.Truth.assertThat; 48 import static org.mockito.Mockito.when; 49 50 /** 51 * Tests for {@link EnterprisePrivacySettings}. 52 */ 53 @RunWith(SettingsRobolectricTestRunner.class) 54 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 55 public final class EnterprisePrivacySettingsTest { 56 57 private final static String RESOURCES_NAMESPACE = "http://schemas.android.com/apk/res/android"; 58 private final static String ATTR_KEY = "key"; 59 60 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 61 private Context mContext; 62 private FakeFeatureFactory mFeatureFactory; 63 private EnterprisePrivacySettings mSettings; 64 65 @Before 66 public void setUp() { 67 MockitoAnnotations.initMocks(this); 68 FakeFeatureFactory.setupForTest(mContext); 69 mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); 70 71 mSettings = new EnterprisePrivacySettings(); 72 } 73 74 @Test 75 public void testGetMetricsCategory() { 76 assertThat(mSettings.getMetricsCategory()) 77 .isEqualTo(MetricsEvent.ENTERPRISE_PRIVACY_SETTINGS); 78 } 79 80 @Test 81 public void testGetCategoryKey() { 82 assertThat(mSettings.getCategoryKey()).isNull(); 83 } 84 85 @Test 86 public void testGetLogTag() { 87 assertThat(mSettings.getLogTag()).isEqualTo("EnterprisePrivacySettings"); 88 } 89 90 @Test 91 public void testGetPreferenceScreenResId() { 92 assertThat(mSettings.getPreferenceScreenResId()) 93 .isEqualTo(R.xml.enterprise_privacy_settings); 94 } 95 96 @Test 97 public void isPageEnabled_hasDeviceOwner_shouldReturnTrue() { 98 when(mFeatureFactory.enterprisePrivacyFeatureProvider.hasDeviceOwner()) 99 .thenReturn(true); 100 101 assertThat(EnterprisePrivacySettings.isPageEnabled(mContext)) 102 .isTrue(); 103 } 104 105 @Test 106 public void isPageEnabled_noDeviceOwner_shouldReturnFalse() { 107 when(mFeatureFactory.enterprisePrivacyFeatureProvider.hasDeviceOwner()) 108 .thenReturn(false); 109 110 assertThat(EnterprisePrivacySettings.isPageEnabled(mContext)) 111 .isFalse(); 112 } 113 114 @Test 115 public void getPreferenceControllers() throws Exception { 116 final List<PreferenceController> controllers = mSettings.getPreferenceControllers( 117 ShadowApplication.getInstance().getApplicationContext()); 118 verifyPreferenceControllers(controllers); 119 } 120 121 @Test 122 public void getSearchIndexProviderPreferenceControllers() throws Exception { 123 final List<PreferenceController> controllers 124 = EnterprisePrivacySettings.SEARCH_INDEX_DATA_PROVIDER.getPreferenceControllers( 125 ShadowApplication.getInstance().getApplicationContext()); 126 verifyPreferenceControllers(controllers); 127 } 128 129 private void verifyPreferenceControllers(List<PreferenceController> controllers) 130 throws Exception { 131 assertThat(controllers).isNotNull(); 132 assertThat(controllers.size()).isEqualTo(16); 133 int position = 0; 134 assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class); 135 assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class); 136 assertThat(controllers.get(position++)).isInstanceOf( 137 SecurityLogsPreferenceController.class); 138 assertThat(controllers.get(position++)).isInstanceOf( 139 EnterpriseInstalledPackagesPreferenceController.class); 140 assertThat(controllers.get(position++)).isInstanceOf( 141 AdminGrantedLocationPermissionsPreferenceController.class); 142 assertThat(controllers.get(position++)).isInstanceOf( 143 AdminGrantedMicrophonePermissionPreferenceController.class); 144 assertThat(controllers.get(position++)).isInstanceOf( 145 AdminGrantedCameraPermissionPreferenceController.class); 146 assertThat(controllers.get(position++)).isInstanceOf( 147 EnterpriseSetDefaultAppsPreferenceController.class); 148 assertThat(controllers.get(position++)).isInstanceOf( 149 AlwaysOnVpnCurrentUserPreferenceController.class); 150 assertThat(controllers.get(position++)).isInstanceOf( 151 AlwaysOnVpnManagedProfilePreferenceController.class); 152 assertThat(controllers.get(position++)).isInstanceOf(ImePreferenceController.class); 153 assertThat(controllers.get(position++)).isInstanceOf( 154 GlobalHttpProxyPreferenceController.class); 155 assertThat(controllers.get(position++)).isInstanceOf( 156 CaCertsPreferenceController.class); 157 final PreferenceController exposureChangesCategoryController = controllers.get(position); 158 final int exposureChangesCategoryControllerIndex = position; 159 assertThat(controllers.get(position++)).isInstanceOf( 160 ExposureChangesCategoryPreferenceController.class); 161 assertThat(controllers.get(position++)).isInstanceOf( 162 FailedPasswordWipeCurrentUserPreferenceController.class); 163 assertThat(controllers.get(position++)).isInstanceOf( 164 FailedPasswordWipeManagedProfilePreferenceController.class); 165 166 // The "Changes made by your organization's admin" category is hidden when all Preferences 167 // inside it become unavailable. To do this correctly, the category's controller must: 168 // a) Observe the availability of all Preferences in the category and 169 // b) Be listed after those Preferences' controllers, so that availability is updated in 170 // the correct order 171 172 // Find all Preferences in the category. 173 final XmlResourceParser parser = RuntimeEnvironment.application.getResources().getXml( 174 R.xml.enterprise_privacy_settings); 175 boolean done = false; 176 int type; 177 final Set<String> expectedObserved = new HashSet<>(); 178 while (!done && (type = parser.next()) != XmlPullParser.END_DOCUMENT) { 179 if (type != XmlPullParser.START_TAG || !"exposure_changes_category".equals( 180 parser.getAttributeValue(RESOURCES_NAMESPACE, ATTR_KEY))) { 181 continue; 182 } 183 int depth = 1; 184 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 185 if (type == XmlPullParser.START_TAG) { 186 final String key = parser.getAttributeValue(RESOURCES_NAMESPACE, ATTR_KEY); 187 if (key != null) { 188 expectedObserved.add(key); 189 } 190 depth++; 191 } else if (type == XmlPullParser.END_TAG) { 192 depth--; 193 if (depth == 0) { 194 done = true; 195 break; 196 } 197 } 198 } 199 } 200 201 // Find all Preferences the category's controller is observing. 202 final Set<String> actualObserved = new HashSet<>(); 203 int maxObservedIndex = -1; 204 for (int i = 0; i < controllers.size(); i++) { 205 final PreferenceController controller = controllers.get(i); 206 if (controller instanceof DynamicAvailabilityPreferenceController && 207 ((DynamicAvailabilityPreferenceController) controller).getAvailabilityObserver() 208 == exposureChangesCategoryController) { 209 actualObserved.add(controller.getPreferenceKey()); 210 maxObservedIndex = i; 211 } 212 } 213 214 // Verify that the category's controller is observing the Preferences inside it. 215 assertThat(actualObserved).isEqualTo(expectedObserved); 216 // Verify that the category's controller is listed after the Preferences' controllers. 217 assertThat(maxObservedIndex).isLessThan(exposureChangesCategoryControllerIndex); 218 } 219 } 220