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.dream; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.anyString; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import android.content.Context; 28 import android.os.Bundle; 29 import android.service.dreams.DreamService; 30 31 import androidx.preference.Preference; 32 import androidx.preference.PreferenceManager; 33 import androidx.preference.PreferenceScreen; 34 import androidx.test.core.app.ApplicationProvider; 35 36 import com.android.settings.R; 37 import com.android.settings.testutils.shadow.ShadowFragment; 38 import com.android.settingslib.dream.DreamBackend; 39 import com.android.settingslib.dream.DreamBackend.WhenToDream; 40 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 import org.mockito.ArgumentCaptor; 44 import org.mockito.Captor; 45 import org.mockito.Mock; 46 import org.mockito.MockitoAnnotations; 47 import org.robolectric.RobolectricTestRunner; 48 import org.robolectric.annotation.Config; 49 50 import java.util.Arrays; 51 import java.util.HashMap; 52 import java.util.List; 53 54 @Config(shadows = ShadowFragment.class) 55 @RunWith(RobolectricTestRunner.class) 56 public class DreamSettingsTest { 57 58 private static final List<String> KEYS = Arrays.asList( 59 DreamSettings.WHILE_CHARGING_ONLY, 60 DreamSettings.WHILE_DOCKED_ONLY, 61 DreamSettings.EITHER_CHARGING_OR_DOCKED, 62 DreamSettings.NEVER_DREAM 63 ); 64 65 @WhenToDream 66 private static final int[] SETTINGS = { 67 DreamBackend.WHILE_CHARGING, 68 DreamBackend.WHILE_DOCKED, 69 DreamBackend.EITHER, 70 DreamBackend.NEVER, 71 }; 72 73 private static final int[] RES_IDS = { 74 R.string.screensaver_settings_summary_sleep, 75 R.string.screensaver_settings_summary_dock, 76 R.string.screensaver_settings_summary_either_long, 77 R.string.screensaver_settings_summary_never 78 }; 79 80 private static final int[] RES_IDS_NO_BATTERY = { 81 R.string.screensaver_settings_summary_sleep, 82 R.string.screensaver_settings_summary_dock_and_charging, 83 R.string.screensaver_settings_summary_either_long, 84 R.string.screensaver_settings_summary_never 85 }; 86 87 @Mock 88 private Preference mDreamPickerPref; 89 @Mock 90 private Preference mComplicationsTogglePref; 91 @Mock 92 private Preference mHomeControllerTogglePref; 93 @Mock 94 private DreamPickerController mDreamPickerController; 95 @Mock 96 private DreamHomeControlsPreferenceController mDreamHomeControlsPreferenceController; 97 @Captor 98 private ArgumentCaptor<DreamPickerController.Callback> mDreamPickerCallbackCaptor; 99 100 @Test getSettingFromPrefKey()101 public void getSettingFromPrefKey() { 102 for (int i = 0; i < KEYS.size(); i++) { 103 assertThat(DreamSettings.getSettingFromPrefKey(KEYS.get(i))).isEqualTo(SETTINGS[i]); 104 } 105 // Default case 106 assertThat(DreamSettings.getSettingFromPrefKey("garbage value")) 107 .isEqualTo(DreamBackend.NEVER); 108 } 109 110 @Test getKeyFromSetting()111 public void getKeyFromSetting() { 112 for (int i = 0; i < SETTINGS.length; i++) { 113 assertThat(DreamSettings.getKeyFromSetting(SETTINGS[i])).isEqualTo(KEYS.get(i)); 114 } 115 // Default 116 assertThat(DreamSettings.getKeyFromSetting(-1)) 117 .isEqualTo(DreamSettings.NEVER_DREAM); 118 } 119 120 @Test getDreamSettingDescriptionResId()121 public void getDreamSettingDescriptionResId() { 122 for (int i = 0; i < SETTINGS.length; i++) { 123 assertThat(DreamSettings.getDreamSettingDescriptionResId( 124 SETTINGS[i], /* enabledOnBattery= */ false)) 125 .isEqualTo(RES_IDS_NO_BATTERY[i]); 126 assertThat(DreamSettings.getDreamSettingDescriptionResId( 127 SETTINGS[i], /* enabledOnBattery= */ true)) 128 .isEqualTo(RES_IDS[i]); 129 } 130 // Default 131 assertThat(DreamSettings.getDreamSettingDescriptionResId(-1, /* enabledOnBattery= */ false)) 132 .isEqualTo(R.string.screensaver_settings_summary_never); 133 assertThat(DreamSettings.getDreamSettingDescriptionResId(-1, /* enabledOnBattery= */ true)) 134 .isEqualTo(R.string.screensaver_settings_summary_never); 135 } 136 137 @Test summaryText_whenDreamsAreOff()138 public void summaryText_whenDreamsAreOff() { 139 final String fakeSummaryOff = "test dream off"; 140 final DreamBackend mockBackend = mock(DreamBackend.class); 141 final Context mockContext = mock(Context.class); 142 when(mockBackend.isEnabled()).thenReturn(false); 143 when(mockContext.getString(R.string.screensaver_settings_summary_off)).thenReturn( 144 fakeSummaryOff); 145 146 assertThat(DreamSettings.getSummaryTextFromBackend(mockBackend, mockContext)).isEqualTo( 147 fakeSummaryOff); 148 } 149 150 @Test summaryTest_WhenDreamsAreOn()151 public void summaryTest_WhenDreamsAreOn() { 152 final String fakeName = "test_name"; 153 final DreamBackend mockBackend = mock(DreamBackend.class); 154 final Context mockContext = mock(Context.class); 155 when(mockBackend.isEnabled()).thenReturn(true); 156 when(mockBackend.getActiveDreamName()).thenReturn(fakeName); 157 when(mockContext.getString(eq(R.string.screensaver_settings_summary_on), anyString())) 158 .thenAnswer(i -> i.getArgument(1) + " test dream is on"); 159 160 assertThat(DreamSettings.getSummaryTextFromBackend(mockBackend, mockContext)).isEqualTo( 161 fakeName + " test dream is on"); 162 } 163 164 @Test complicationsToggle_addAndRemoveActiveDreamChangeCallback()165 public void complicationsToggle_addAndRemoveActiveDreamChangeCallback() { 166 MockitoAnnotations.initMocks(this); 167 168 final Context context = ApplicationProvider.getApplicationContext(); 169 final DreamSettings dreamSettings = prepareDreamSettings(context); 170 171 dreamSettings.onAttach(context); 172 dreamSettings.onCreate(Bundle.EMPTY); 173 verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); 174 175 dreamSettings.onDestroy(); 176 verify(mDreamPickerController).removeCallback(mDreamPickerCallbackCaptor.getValue()); 177 } 178 179 @Test complicationsToggle_showWhenDreamSupportsComplications()180 public void complicationsToggle_showWhenDreamSupportsComplications() { 181 MockitoAnnotations.initMocks(this); 182 183 final Context context = ApplicationProvider.getApplicationContext(); 184 final DreamSettings dreamSettings = prepareDreamSettings(context); 185 186 // Active dream supports complications 187 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 188 activeDream.supportsComplications = true; 189 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 190 191 dreamSettings.onAttach(context); 192 dreamSettings.onCreate(Bundle.EMPTY); 193 194 // Verify dream complications toggle is visible 195 verify(mComplicationsTogglePref).setVisible(true); 196 } 197 198 @Test complicationsToggle_hideWhenDreamDoesNotSupportComplications()199 public void complicationsToggle_hideWhenDreamDoesNotSupportComplications() { 200 MockitoAnnotations.initMocks(this); 201 202 final Context context = ApplicationProvider.getApplicationContext(); 203 final DreamSettings dreamSettings = prepareDreamSettings(context); 204 205 // Active dream does not support complications 206 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 207 activeDream.supportsComplications = false; 208 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 209 210 dreamSettings.onAttach(context); 211 dreamSettings.onCreate(Bundle.EMPTY); 212 213 // Verify dream complications toggle is hidden 214 verify(mComplicationsTogglePref).setVisible(false); 215 } 216 217 @Test complicationsToggle_showWhenSwitchToDreamSupportsComplications()218 public void complicationsToggle_showWhenSwitchToDreamSupportsComplications() { 219 MockitoAnnotations.initMocks(this); 220 221 final Context context = ApplicationProvider.getApplicationContext(); 222 final DreamSettings dreamSettings = prepareDreamSettings(context); 223 224 // Active dream does not support complications 225 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 226 activeDream.supportsComplications = false; 227 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 228 229 dreamSettings.onAttach(context); 230 dreamSettings.onCreate(Bundle.EMPTY); 231 232 // Verify dream complications toggle is hidden 233 verify(mComplicationsTogglePref).setVisible(false); 234 verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); 235 236 // Active dream changes to one that supports complications 237 activeDream.supportsComplications = true; 238 mDreamPickerCallbackCaptor.getValue().onActiveDreamChanged(); 239 240 // Verify dream complications toggle is shown 241 verify(mComplicationsTogglePref).setVisible(true); 242 } 243 244 @Test homeControlToggle_enableWhenDreamCategoryIsDefault()245 public void homeControlToggle_enableWhenDreamCategoryIsDefault() { 246 MockitoAnnotations.initMocks(this); 247 248 final Context context = ApplicationProvider.getApplicationContext(); 249 final DreamSettings dreamSettings = prepareDreamSettings(context); 250 251 // Active dream does not support complications 252 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 253 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_DEFAULT; 254 255 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 256 257 dreamSettings.onAttach(context); 258 dreamSettings.onCreate(Bundle.EMPTY); 259 260 verify(mHomeControllerTogglePref).setEnabled(true); 261 } 262 263 @Test homePanelToggle_disableWhenDreamCategoryIsHomePanel()264 public void homePanelToggle_disableWhenDreamCategoryIsHomePanel() { 265 MockitoAnnotations.initMocks(this); 266 267 final Context context = ApplicationProvider.getApplicationContext(); 268 final DreamSettings dreamSettings = prepareDreamSettings(context); 269 270 // Active dream does not support complications 271 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 272 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_HOME_PANEL; 273 274 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 275 276 dreamSettings.onAttach(context); 277 dreamSettings.onCreate(Bundle.EMPTY); 278 279 verify(mHomeControllerTogglePref).setEnabled(false); 280 } 281 282 @Test homePanelToggle_disableWhenSwitchingFromDefaultToHomePanel()283 public void homePanelToggle_disableWhenSwitchingFromDefaultToHomePanel() { 284 MockitoAnnotations.initMocks(this); 285 286 final Context context = ApplicationProvider.getApplicationContext(); 287 final DreamSettings dreamSettings = prepareDreamSettings(context); 288 289 290 // Active dream does not support complications 291 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 292 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_DEFAULT; 293 294 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 295 296 dreamSettings.onAttach(context); 297 dreamSettings.onCreate(Bundle.EMPTY); 298 299 verify(mHomeControllerTogglePref).setEnabled(true); 300 verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); 301 302 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_HOME_PANEL; 303 mDreamPickerCallbackCaptor.getValue().onActiveDreamChanged(); 304 verify(mHomeControllerTogglePref).setEnabled(false); 305 } 306 307 @Test homePanelToggle_showWhenSwitchingFromHomePanelToDefault()308 public void homePanelToggle_showWhenSwitchingFromHomePanelToDefault() { 309 MockitoAnnotations.initMocks(this); 310 311 final Context context = ApplicationProvider.getApplicationContext(); 312 final DreamSettings dreamSettings = prepareDreamSettings(context); 313 314 315 // Active dream does not support complications 316 final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); 317 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_HOME_PANEL; 318 319 when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); 320 321 dreamSettings.onAttach(context); 322 dreamSettings.onCreate(Bundle.EMPTY); 323 324 verify(mHomeControllerTogglePref).setEnabled(false); 325 verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); 326 327 activeDream.dreamCategory = DreamService.DREAM_CATEGORY_DEFAULT; 328 mDreamPickerCallbackCaptor.getValue().onActiveDreamChanged(); 329 verify(mHomeControllerTogglePref).setEnabled(true); 330 } 331 prepareDreamSettings(Context context)332 private DreamSettings prepareDreamSettings(Context context) { 333 final TestDreamSettings dreamSettings = new TestDreamSettings(context); 334 when(mDreamPickerController.getPreferenceKey()).thenReturn(DreamPickerController.PREF_KEY); 335 when(mDreamHomeControlsPreferenceController.getPreferenceKey()) 336 .thenReturn(DreamHomeControlsPreferenceController.PREF_KEY); 337 when(mDreamPickerPref.getExtras()).thenReturn(new Bundle()); 338 when(mDreamPickerPref.getKey()).thenReturn(DreamPickerController.PREF_KEY); 339 when(mComplicationsTogglePref.getKey()).thenReturn( 340 DreamComplicationPreferenceController.PREF_KEY); 341 when(mHomeControllerTogglePref.getExtras()).thenReturn(new Bundle()); 342 when(mHomeControllerTogglePref.getKey()).thenReturn( 343 DreamHomeControlsPreferenceController.PREF_KEY); 344 when(mDreamHomeControlsPreferenceController.getAvailabilityStatus()) 345 .thenReturn(mDreamHomeControlsPreferenceController.AVAILABLE); 346 dreamSettings.addPreference(DreamPickerController.PREF_KEY, mDreamPickerPref); 347 dreamSettings.addPreference(DreamComplicationPreferenceController.PREF_KEY, 348 mComplicationsTogglePref); 349 dreamSettings.addPreference(DreamHomeControlsPreferenceController.PREF_KEY, 350 mHomeControllerTogglePref); 351 dreamSettings.setDreamPickerController(mDreamPickerController); 352 dreamSettings 353 .setDreamHomeControlsPreferenceController(mDreamHomeControlsPreferenceController); 354 355 return dreamSettings; 356 } 357 358 private static class TestDreamSettings extends DreamSettings { 359 360 private final Context mContext; 361 private final PreferenceManager mPreferenceManager; 362 363 private final HashMap<String, Preference> mPreferences = new HashMap<>(); 364 TestDreamSettings(Context context)365 TestDreamSettings(Context context) { 366 super(); 367 mContext = context; 368 mPreferenceManager = new PreferenceManager(context); 369 mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context)); 370 } 371 372 @Override getPreferenceScreenResId()373 public int getPreferenceScreenResId() { 374 return R.xml.placeholder_prefs; 375 } 376 377 @Override getPreferenceScreen()378 public PreferenceScreen getPreferenceScreen() { 379 return mPreferenceManager.getPreferenceScreen(); 380 } 381 382 @Override getPreferenceManager()383 public PreferenceManager getPreferenceManager() { 384 return mPreferenceManager; 385 } 386 387 @Override getContext()388 public Context getContext() { 389 return mContext; 390 } 391 392 @Override findPreference(CharSequence key)393 public <T extends Preference> T findPreference(CharSequence key) { 394 return (T) mPreferences.get(key); 395 } 396 addPreference(String key, Preference preference)397 void addPreference(String key, Preference preference) { 398 mPreferences.put(key, preference); 399 } 400 } 401 } 402