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.when;
28 import static org.robolectric.Shadows.shadowOf;
29 
30 import android.content.Context;
31 import android.os.Bundle;
32 import android.os.Parcelable;
33 import android.widget.SeekBar;
34 
35 import androidx.preference.PreferenceFragmentCompat;
36 
37 import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
38 
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.MockitoAnnotations;
43 import org.robolectric.RobolectricTestRunner;
44 import org.robolectric.RuntimeEnvironment;
45 import org.robolectric.annotation.Config;
46 import org.robolectric.shadows.androidx.fragment.FragmentController;
47 
48 @RunWith(RobolectricTestRunner.class)
49 @Config(shadows = ShadowRestrictedLockUtilsInternal.class)
50 public class SeekBarPreferenceTest {
51 
52     private static final int MAX = 75;
53     private static final int MIN = 5;
54     private static final int PROGRESS = 16;
55     private static final int NEW_PROGRESS = 17;
56 
57     private Context mContext;
58     private SeekBarPreference mSeekBarPreference;
59     private SeekBar mSeekBar;
60 
61     @Before
setUp()62     public void setUp() {
63         MockitoAnnotations.initMocks(this);
64         mContext = RuntimeEnvironment.application;
65 
66         mSeekBarPreference = spy(new SeekBarPreference(mContext));
67         mSeekBarPreference.setMax(MAX);
68         mSeekBarPreference.setMin(MIN);
69         mSeekBarPreference.setProgress(PROGRESS);
70         mSeekBarPreference.setPersistent(false);
71         mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_NONE);
72 
73         mSeekBar = new SeekBar(mContext);
74         mSeekBar.setMax(MAX);
75         mSeekBar.setMin(MIN);
76     }
77 
78     @Test
testSaveAndRestoreInstanceState()79     public void testSaveAndRestoreInstanceState() {
80         final Parcelable parcelable = mSeekBarPreference.onSaveInstanceState();
81 
82         final SeekBarPreference preference = new SeekBarPreference(mContext);
83         preference.onRestoreInstanceState(parcelable);
84 
85         assertThat(preference.getMax()).isEqualTo(MAX);
86         assertThat(preference.getMin()).isEqualTo(MIN);
87         assertThat(preference.getProgress()).isEqualTo(PROGRESS);
88     }
89 
90     @Test
isSelectable_disabledByAdmin_returnTrue()91     public void isSelectable_disabledByAdmin_returnTrue() {
92         when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(true);
93 
94         assertThat(mSeekBarPreference.isSelectable()).isTrue();
95     }
96 
97     @Test
98     @Config(qualifiers = "mcc998")
isSelectable_default_returnFalse()99     public void isSelectable_default_returnFalse() {
100         final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(),
101                 new Bundle())
102                 .create()
103                 .start()
104                 .resume()
105                 .get();
106 
107         final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar");
108 
109         assertThat(seekBarPreference.isSelectable()).isFalse();
110     }
111 
112     @Test
113     @Config(qualifiers = "mcc999")
isSelectable_selectableInXml_returnTrue()114     public void isSelectable_selectableInXml_returnTrue() {
115         final PreferenceFragmentCompat fragment = FragmentController.of(new TestFragment(),
116                 new Bundle())
117                 .create()
118                 .start()
119                 .resume()
120                 .get();
121 
122         final SeekBarPreference seekBarPreference = fragment.findPreference("seek_bar");
123 
124         assertThat(seekBarPreference.isSelectable()).isTrue();
125     }
126 
127     @Test
testSetSeekBarStateDescription()128     public void testSetSeekBarStateDescription() {
129         mSeekBarPreference.setSeekBarStateDescription("test");
130 
131         verify(mSeekBarPreference).setSeekBarStateDescription("test");
132     }
133 
134     @Test
onProgressChanged_hapticFeedbackModeNone_clockTickFeedbackNotPerformed()135     public void onProgressChanged_hapticFeedbackModeNone_clockTickFeedbackNotPerformed() {
136         mSeekBar.setProgress(NEW_PROGRESS);
137         when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
138         mSeekBar.performHapticFeedback(CONTEXT_CLICK);
139 
140         mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
141 
142         assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK);
143     }
144 
145     @Test
onProgressChanged_hapticFeedbackModeOnTicks_clockTickFeedbackPerformed()146     public void onProgressChanged_hapticFeedbackModeOnTicks_clockTickFeedbackPerformed() {
147         mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_TICKS);
148         mSeekBar.setProgress(NEW_PROGRESS);
149         when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
150         mSeekBar.performHapticFeedback(CONTEXT_CLICK);
151 
152         mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
153 
154         assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
155     }
156 
157     @Test
onProgressChanged_hapticFeedbackModeOnEnds_clockTickFeedbackNotPerformed()158     public void onProgressChanged_hapticFeedbackModeOnEnds_clockTickFeedbackNotPerformed() {
159         mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS);
160         mSeekBar.setProgress(NEW_PROGRESS);
161         when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
162         mSeekBar.performHapticFeedback(CONTEXT_CLICK);
163 
164         mSeekBarPreference.onProgressChanged(mSeekBar, NEW_PROGRESS, true);
165 
166         assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isNotEqualTo(CLOCK_TICK);
167     }
168 
169     @Test
onProgressChanged_hapticFeedbackModeOnEndsAndMinValue_clockTickFeedbackPerformed()170     public void onProgressChanged_hapticFeedbackModeOnEndsAndMinValue_clockTickFeedbackPerformed() {
171         mSeekBarPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS);
172         mSeekBar.setProgress(MIN);
173         when(mSeekBarPreference.callChangeListener(anyInt())).thenReturn(true);
174         mSeekBar.performHapticFeedback(CONTEXT_CLICK);
175 
176         mSeekBarPreference.onProgressChanged(mSeekBar, MIN, true);
177 
178         assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
179     }
180 
181     public static class TestFragment extends PreferenceFragmentCompat {
182         @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)183         public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
184             addPreferencesFromResource(com.android.settings.R.xml.seekbar_preference);
185         }
186     }
187 }
188