1 /* 2 * Copyright (C) 2017 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.development; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.mockito.Mockito.doReturn; 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.content.Context; 27 import android.os.UserManager; 28 import android.provider.SearchIndexableResource; 29 import android.provider.Settings; 30 31 import com.android.internal.logging.nano.MetricsProto; 32 import com.android.settings.R; 33 import com.android.settings.testutils.SettingsRobolectricTestRunner; 34 import com.android.settings.testutils.shadow.SettingsShadowResources; 35 import com.android.settings.widget.SwitchBar; 36 import com.android.settings.widget.ToggleSwitch; 37 import com.android.settingslib.development.AbstractEnableAdbPreferenceController; 38 import com.android.settingslib.development.DevelopmentSettingsEnabler; 39 40 import org.junit.After; 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.mockito.MockitoAnnotations; 45 import org.robolectric.RuntimeEnvironment; 46 import org.robolectric.Shadows; 47 import org.robolectric.annotation.Config; 48 import org.robolectric.annotation.Implementation; 49 import org.robolectric.annotation.Implements; 50 import org.robolectric.shadows.ShadowUserManager; 51 import org.robolectric.util.ReflectionHelpers; 52 53 import java.util.List; 54 55 @RunWith(SettingsRobolectricTestRunner.class) 56 public class DevelopmentSettingsDashboardFragmentTest { 57 58 private ToggleSwitch mSwitch; 59 private Context mContext; 60 private ShadowUserManager mShadowUserManager; 61 private DevelopmentSettingsDashboardFragment mDashboard; 62 63 @Before setUp()64 public void setUp() { 65 MockitoAnnotations.initMocks(this); 66 mContext = RuntimeEnvironment.application; 67 SwitchBar switchBar = new SwitchBar(mContext); 68 mSwitch = switchBar.getSwitch(); 69 mDashboard = spy(new DevelopmentSettingsDashboardFragment()); 70 ReflectionHelpers.setField(mDashboard, "mSwitchBar", switchBar); 71 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 72 mShadowUserManager = Shadows.shadowOf(userManager); 73 mShadowUserManager.setIsAdminUser(true); 74 } 75 76 @After tearDown()77 public void tearDown() { 78 ShadowEnableDevelopmentSettingWarningDialog.reset(); 79 } 80 81 @Test shouldNotHaveHelpResource()82 public void shouldNotHaveHelpResource() { 83 assertThat(mDashboard.getHelpResource()).isEqualTo(0); 84 } 85 86 @Test shouldLogAsFeatureFlagPage()87 public void shouldLogAsFeatureFlagPage() { 88 assertThat(mDashboard.getMetricsCategory()) 89 .isEqualTo(MetricsProto.MetricsEvent.DEVELOPMENT); 90 } 91 92 @Test searchIndex_shouldIndexFromPrefXml()93 public void searchIndex_shouldIndexFromPrefXml() { 94 final List<SearchIndexableResource> index = 95 DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER 96 .getXmlResourcesToIndex(RuntimeEnvironment.application, true); 97 98 assertThat(index.size()).isEqualTo(1); 99 assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_settings); 100 } 101 102 @Test 103 @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class) searchIndex_pageDisabledBySetting_shouldAddAllKeysToNonIndexable()104 public void searchIndex_pageDisabledBySetting_shouldAddAllKeysToNonIndexable() { 105 final Context appContext = RuntimeEnvironment.application; 106 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, false); 107 108 final List<String> nonIndexableKeys = 109 DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER 110 .getNonIndexableKeys(appContext); 111 112 assertThat(nonIndexableKeys).contains("enable_adb"); 113 } 114 115 @Test 116 @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class) searchIndex_pageDisabledForNonAdmin_shouldAddAllKeysToNonIndexable()117 public void searchIndex_pageDisabledForNonAdmin_shouldAddAllKeysToNonIndexable() { 118 final Context appContext = RuntimeEnvironment.application; 119 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, true); 120 mShadowUserManager.setIsAdminUser(false); 121 mShadowUserManager.setIsDemoUser(false); 122 123 final List<String> nonIndexableKeys = 124 DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER 125 .getNonIndexableKeys(appContext); 126 127 assertThat(nonIndexableKeys).contains("enable_adb"); 128 } 129 130 @Test 131 @Config(shadows = { 132 ShadowPictureColorModePreferenceController.class, 133 ShadowAdbPreferenceController.class, 134 ShadowClearAdbKeysPreferenceController.class 135 }) searchIndex_pageEnabled_shouldNotAddKeysToNonIndexable()136 public void searchIndex_pageEnabled_shouldNotAddKeysToNonIndexable() { 137 final Context appContext = RuntimeEnvironment.application; 138 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, true); 139 140 final List<String> nonIndexableKeys = 141 DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER 142 .getNonIndexableKeys(appContext); 143 144 assertThat(nonIndexableKeys).doesNotContain("development_prefs_screen"); 145 } 146 147 @Test 148 @Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class) onSwitchChanged_sameState_shouldDoNothing()149 public void onSwitchChanged_sameState_shouldDoNothing() { 150 when(mDashboard.getContext()).thenReturn(mContext); 151 Settings.Global.putInt(mContext.getContentResolver(), 152 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); 153 154 mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); 155 assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); 156 } 157 158 @Test 159 @Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class) onSwitchChanged_turnOn_shouldShowWarningDialog()160 public void onSwitchChanged_turnOn_shouldShowWarningDialog() { 161 when(mDashboard.getContext()).thenReturn(mContext); 162 Settings.Global.putInt(mContext.getContentResolver(), 163 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); 164 165 mDashboard.onSwitchChanged(mSwitch, true /* isChecked */); 166 assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue(); 167 } 168 169 @Test 170 @Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class) onSwitchChanged_turnOff_shouldTurnOff()171 public void onSwitchChanged_turnOff_shouldTurnOff() { 172 when(mDashboard.getContext()).thenReturn(mContext); 173 Settings.Global.putInt(mContext.getContentResolver(), 174 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); 175 176 mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); 177 178 assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); 179 assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse(); 180 } 181 182 @Test onOemUnlockDialogConfirmed_shouldCallControllerOemConfirmed()183 public void onOemUnlockDialogConfirmed_shouldCallControllerOemConfirmed() { 184 final OemUnlockPreferenceController controller = mock(OemUnlockPreferenceController.class); 185 doReturn(controller).when(mDashboard) 186 .getDevelopmentOptionsController(OemUnlockPreferenceController.class); 187 mDashboard.onOemUnlockDialogConfirmed(); 188 verify(controller).onOemUnlockConfirmed(); 189 } 190 191 @Test onOemUnlockDialogConfirmed_shouldCallControllerOemDismissed()192 public void onOemUnlockDialogConfirmed_shouldCallControllerOemDismissed() { 193 final OemUnlockPreferenceController controller = mock(OemUnlockPreferenceController.class); 194 doReturn(controller).when(mDashboard) 195 .getDevelopmentOptionsController(OemUnlockPreferenceController.class); 196 mDashboard.onOemUnlockDialogDismissed(); 197 verify(controller).onOemUnlockDismissed(); 198 } 199 200 @Test onAdbDialogConfirmed_shouldCallControllerDialogConfirmed()201 public void onAdbDialogConfirmed_shouldCallControllerDialogConfirmed() { 202 final AdbPreferenceController controller = mock(AdbPreferenceController.class); 203 doReturn(controller).when(mDashboard) 204 .getDevelopmentOptionsController(AdbPreferenceController.class); 205 mDashboard.onEnableAdbDialogConfirmed(); 206 207 verify(controller).onAdbDialogConfirmed(); 208 } 209 210 @Test onAdbDialogDismissed_shouldCallControllerOemDismissed()211 public void onAdbDialogDismissed_shouldCallControllerOemDismissed() { 212 final AdbPreferenceController controller = mock(AdbPreferenceController.class); 213 doReturn(controller).when(mDashboard) 214 .getDevelopmentOptionsController(AdbPreferenceController.class); 215 mDashboard.onEnableAdbDialogDismissed(); 216 217 verify(controller).onAdbDialogDismissed(); 218 } 219 220 @Test onAdbClearKeysDialogConfirmed_shouldCallControllerDialogConfirmed()221 public void onAdbClearKeysDialogConfirmed_shouldCallControllerDialogConfirmed() { 222 final ClearAdbKeysPreferenceController controller = 223 mock(ClearAdbKeysPreferenceController.class); 224 doReturn(controller).when(mDashboard) 225 .getDevelopmentOptionsController(ClearAdbKeysPreferenceController.class); 226 mDashboard.onAdbClearKeysDialogConfirmed(); 227 228 verify(controller).onClearAdbKeysConfirmed(); 229 } 230 231 @Test onDisableLogPersistDialogConfirmed_shouldCallControllerDialogConfirmed()232 public void onDisableLogPersistDialogConfirmed_shouldCallControllerDialogConfirmed() { 233 final LogPersistPreferenceController controller = 234 mock(LogPersistPreferenceController.class); 235 doReturn(controller).when(mDashboard) 236 .getDevelopmentOptionsController(LogPersistPreferenceController.class); 237 mDashboard.onDisableLogPersistDialogConfirmed(); 238 239 verify(controller).onDisableLogPersistDialogConfirmed(); 240 } 241 242 @Test onDisableLogPersistDialogRejected_shouldCallControllerDialogRejected()243 public void onDisableLogPersistDialogRejected_shouldCallControllerDialogRejected() { 244 final LogPersistPreferenceController controller = 245 mock(LogPersistPreferenceController.class); 246 doReturn(controller).when(mDashboard) 247 .getDevelopmentOptionsController(LogPersistPreferenceController.class); 248 mDashboard.onDisableLogPersistDialogRejected(); 249 250 verify(controller).onDisableLogPersistDialogRejected(); 251 } 252 253 @Implements(EnableDevelopmentSettingWarningDialog.class) 254 public static class ShadowEnableDevelopmentSettingWarningDialog { 255 256 static boolean mShown; 257 reset()258 public static void reset() { 259 mShown = false; 260 } 261 262 @Implementation show(DevelopmentSettingsDashboardFragment host)263 public static void show(DevelopmentSettingsDashboardFragment host) { 264 mShown = true; 265 } 266 } 267 268 @Implements(PictureColorModePreferenceController.class) 269 public static class ShadowPictureColorModePreferenceController { 270 @Implementation isAvailable()271 public boolean isAvailable() { 272 return true; 273 } 274 } 275 276 @Implements(AbstractEnableAdbPreferenceController.class) 277 public static class ShadowAdbPreferenceController { 278 @Implementation isAvailable()279 public boolean isAvailable() { 280 return true; 281 } 282 } 283 284 @Implements(ClearAdbKeysPreferenceController.class) 285 public static class ShadowClearAdbKeysPreferenceController { 286 287 @Implementation isAvailable()288 public boolean isAvailable() { 289 return true; 290 } 291 } 292 } 293