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