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