1 /* 2 * Copyright (C) 2018 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.widget; 18 19 import static android.view.HapticFeedbackConstants.CLOCK_TICK; 20 import static android.view.HapticFeedbackConstants.CONTEXT_CLICK; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.Mockito.spy; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.verifyNoInteractions; 28 import static org.mockito.Mockito.when; 29 import static org.robolectric.Shadows.shadowOf; 30 31 import android.content.Context; 32 import android.os.Bundle; 33 import android.os.Parcelable; 34 import android.widget.SeekBar; 35 36 import androidx.preference.PreferenceFragmentCompat; 37 38 import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor; 39 import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; 40 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.mockito.Mock; 45 import org.mockito.MockitoAnnotations; 46 import org.robolectric.RobolectricTestRunner; 47 import org.robolectric.RuntimeEnvironment; 48 import org.robolectric.annotation.Config; 49 import org.robolectric.shadows.androidx.fragment.FragmentController; 50 51 @RunWith(RobolectricTestRunner.class) 52 @Config(shadows = {ShadowRestrictedLockUtilsInternal.class, ShadowInteractionJankMonitor.class}) 53 public class SeekBarPreferenceTest { 54 55 private static final int MAX = 75; 56 private static final int MIN = 5; 57 private static final int PROGRESS = 16; 58 private static final int NEW_PROGRESS = 17; 59 60 private Context mContext; 61 private SeekBarPreference mSeekBarPreference; 62 private SeekBar mSeekBar; 63 64 @Mock 65 SeekBar.OnSeekBarChangeListener mMockOnSeekBarChangeListener; 66 67 @Before setUp()68 public void setUp() { 69 MockitoAnnotations.initMocks(this); 70 mContext = RuntimeEnvironment.application; 71 72 mSeekBarPreference = spy(new SeekBarPreference(mContext)); 73 mSeekBarPreference.setMax(MAX); 74 mSeekBarPreference.setMin(MIN); 75 mSeekBarPreference.setProgress(PROGRESS); 76 mSeekBarPreference.setPersistent(false); 77 mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_NONE); 78 79 mSeekBar = new SeekBar(mContext); 80 mSeekBar.setMax(MAX); 81 mSeekBar.setMin(MIN); 82 } 83 84 @Test testSaveAndRestoreInstanceState()85 public void testSaveAndRestoreInstanceState() { 86 final Parcelable parcelable = mSeekBarPreference.onSaveInstanceState(); 87 88 final SeekBarPreference preference = new SeekBarPreference(mContext); 89 preference.onRestoreInstanceState(parcelable); 90 91 assertThat(preference.getMax()).isEqualTo(MAX); 92 assertThat(preference.getMin()).isEqualTo(MIN); 93 assertThat(preference.getProgress()).isEqualTo(PROGRESS); 94 } 95 96 @Test isSelectable_disabledByAdmin_returnTrue()97 public void isSelectable_disabledByAdmin_returnTrue() { 98 when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(true); 99 100 assertThat(mSeekBarPreference.isSelectable()).isTrue(); 101 } 102 103 @Test 104 @Config(qualifiers = "mcc998") isSelectable_default_returnFalse()105 public void isSelectable_default_returnFalse() { 106 final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(), 107 new Bundle()) 108 .create() 109 .start() 110 .resume() 111 .get(); 112 113 final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar"); 114 115 assertThat(seekBarPreference.isSelectable()).isFalse(); 116 } 117 118 @Test 119 @Config(qualifiers = "mcc999") isSelectable_selectableInXml_returnFalse()120 public void isSelectable_selectableInXml_returnFalse() { 121 final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(), 122 new Bundle()) 123 .create() 124 .start() 125 .resume() 126 .get(); 127 128 final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar"); 129 130 assertThat(seekBarPreference.isSelectable()).isFalse(); 131 } 132 133 @Test testSetSeekBarStateDescription()134 public void testSetSeekBarStateDescription() { 135 mSeekBarPreference.setSeekBarStateDescription("test"); 136 137 verify(mSeekBarPreference).setSeekBarStateDescription("test"); 138 } 139 140 @Test onProgressChanged_hapticFeedbackModeNone_clockTickFeedbackNotPerformed()141 public void onProgressChanged_hapticFeedbackModeNone_clockTickFeedbackNotPerformed() { 142 mSeekBar.setProgress(NEW_PROGRESS); 143 when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true); 144 mSeekBar.performHapticFeedback(CONTEXT_CLICK); 145 146 mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true); 147 148 assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK); 149 } 150 151 @Test onProgressChanged_hapticFeedbackModeOnTicks_clockTickFeedbackPerformed()152 public void onProgressChanged_hapticFeedbackModeOnTicks_clockTickFeedbackPerformed() { 153 mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_TICKS); 154 mSeekBar.setProgress(NEW_PROGRESS); 155 when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true); 156 mSeekBar.performHapticFeedback(CONTEXT_CLICK); 157 158 mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true); 159 160 assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK); 161 } 162 163 @Test onProgressChanged_hapticFeedbackModeOnEnds_clockTickFeedbackNotPerformed()164 public void onProgressChanged_hapticFeedbackModeOnEnds_clockTickFeedbackNotPerformed() { 165 mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS); 166 mSeekBar.setProgress(NEW_PROGRESS); 167 when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true); 168 mSeekBar.performHapticFeedback(CONTEXT_CLICK); 169 170 mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true); 171 172 assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK); 173 } 174 175 @Test onProgressChanged_hapticFeedbackModeOnEndsAndMinValue_clockTickFeedbackPerformed()176 public void onProgressChanged_hapticFeedbackModeOnEndsAndMinValue_clockTickFeedbackPerformed() { 177 mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS); 178 mSeekBar.setProgress(MIN); 179 when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true); 180 mSeekBar.performHapticFeedback(CONTEXT_CLICK); 181 182 mSeekBarPreference.onProgressChanged(mSeekBar, MIN, true); 183 184 assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK); 185 } 186 187 @Test onProgressChanged_hasSeekBarChangeListener_receiveCallBack()188 public void onProgressChanged_hasSeekBarChangeListener_receiveCallBack() { 189 mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); 190 191 mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); 192 193 verify(mMockOnSeekBarChangeListener).onProgressChanged(mSeekBar, PROGRESS, true); 194 } 195 196 @Test onProgressChanged_noSeekBarChangeListener_noAction()197 public void onProgressChanged_noSeekBarChangeListener_noAction() { 198 mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); 199 200 verifyNoInteractions(mMockOnSeekBarChangeListener); 201 } 202 203 @Test onStartTrackingTouch_hasSeekBarChangeListener_receiveCallBack()204 public void onStartTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { 205 mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); 206 207 mSeekBarPreference.onStartTrackingTouch(mSeekBar); 208 209 verify(mMockOnSeekBarChangeListener).onStartTrackingTouch(mSeekBar); 210 } 211 212 @Test onStartTrackingTouch_noSeekBarChangeListener_noAction()213 public void onStartTrackingTouch_noSeekBarChangeListener_noAction() { 214 mSeekBarPreference.onStartTrackingTouch(mSeekBar); 215 216 verifyNoInteractions(mMockOnSeekBarChangeListener); 217 } 218 219 @Test onStopTrackingTouch_hasSeekBarChangeListener_receiveCallBack()220 public void onStopTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { 221 mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); 222 223 mSeekBarPreference.onStopTrackingTouch(mSeekBar); 224 225 verify(mMockOnSeekBarChangeListener).onStopTrackingTouch(mSeekBar); 226 } 227 228 @Test onStopTrackingTouch_noSeekBarChangeListener_noAction()229 public void onStopTrackingTouch_noSeekBarChangeListener_noAction() { 230 mSeekBarPreference.onStopTrackingTouch(mSeekBar); 231 232 verifyNoInteractions(mMockOnSeekBarChangeListener); 233 } 234 235 public static class TestFragment extends PreferenceFragmentCompat { 236 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)237 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 238 addPreferencesFromResource(com.android.settings.R.xml.seekbar_preference); 239 } 240 } 241 } 242