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.accessibility;
18 
19 import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_HIGH;
20 import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
21 import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
22 import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
23 import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_ON;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.Context;
31 import android.content.res.Resources;
32 import android.os.UserManager;
33 import android.os.Vibrator;
34 import android.provider.Settings;
35 
36 import com.android.settings.R;
37 import com.android.settings.accessibility.VibrationPreferenceFragment
38         .VibrationIntensityCandidateInfo;
39 import com.android.settings.testutils.FakeFeatureFactory;
40 import com.android.settingslib.widget.CandidateInfo;
41 
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 import org.robolectric.RobolectricTestRunner;
48 import org.robolectric.RuntimeEnvironment;
49 
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 
54 @RunWith(RobolectricTestRunner.class)
55 public class VibrationPreferenceFragmentTest {
56 
57     private static final Map<Integer, String> INTENSITY_TO_KEY = new HashMap<>(4);
58     static {
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF)59         INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW)60         INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM)61         INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH)62         INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
63     }
64 
65     @Mock
66     private UserManager mUserManager;
67 
68     private Context mContext;
69     private Resources mResources;
70     private TestVibrationPreferenceFragment mFragment;
71 
72     @Before
setUp()73     public void setUp() {
74         MockitoAnnotations.initMocks(this);
75         FakeFeatureFactory.setupForTest();
76 
77         mContext = spy(RuntimeEnvironment.application);
78         mResources = spy(mContext.getResources());
79         when(mContext.getResources()).thenReturn(mResources);
80 
81         mFragment = spy(new TestVibrationPreferenceFragment());
82         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
83     }
84 
85     @Test
changeIntensitySetting_shouldResultInCorrespondingKey()86     public void changeIntensitySetting_shouldResultInCorrespondingKey() {
87         setSupportsMultipleIntensities(true);
88         mFragment.onAttach(mContext);
89         for (Map.Entry<Integer, String> entry : INTENSITY_TO_KEY.entrySet()) {
90             Settings.System.putInt(mContext.getContentResolver(),
91                     Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
92             assertThat(mFragment.getDefaultKey()).isEqualTo(entry.getValue());
93         }
94     }
95 
96     @Test
changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn()97     public void changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn() {
98         setSupportsMultipleIntensities(false);
99         mFragment.onAttach(mContext);
100         for (int intensity : INTENSITY_TO_KEY.keySet()) {
101             Settings.System.putInt(mContext.getContentResolver(),
102                     Settings.System.HAPTIC_FEEDBACK_INTENSITY, intensity);
103             final String expectedKey = intensity == Vibrator.VIBRATION_INTENSITY_OFF
104                     ? KEY_INTENSITY_OFF
105                     : KEY_INTENSITY_ON;
106             assertThat(mFragment.getDefaultKey()).isEqualTo(expectedKey);
107         }
108     }
109 
110     @Test
initialDefaultKey_shouldBeMedium()111     public void initialDefaultKey_shouldBeMedium() {
112         setSupportsMultipleIntensities(true);
113         mFragment.onAttach(mContext);
114         assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
115     }
116 
117     @Test
initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn()118     public void initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn() {
119         setSupportsMultipleIntensities(false);
120         mFragment.onAttach(mContext);
121         assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_ON);
122     }
123 
124     @Test
candidates_shouldBeSortedByIntensity()125     public void candidates_shouldBeSortedByIntensity() {
126         setSupportsMultipleIntensities(true);
127         mFragment.onAttach(mContext);
128         final List<? extends CandidateInfo> candidates = mFragment.getCandidates();
129         assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
130         VibrationIntensityCandidateInfo prevCandidate =
131                 (VibrationIntensityCandidateInfo) candidates.get(0);
132         for (int i = 1; i < candidates.size(); i++) {
133             VibrationIntensityCandidateInfo candidate =
134                     (VibrationIntensityCandidateInfo) candidates.get(i);
135             assertThat(candidate.getIntensity()).isLessThan(prevCandidate.getIntensity());
136         }
137     }
138 
setSupportsMultipleIntensities(boolean hasSupport)139     private void setSupportsMultipleIntensities(boolean hasSupport) {
140         when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
141             .thenReturn(hasSupport);
142     }
143 
144     private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
145         @Override
getPreferenceScreenResId()146         protected int getPreferenceScreenResId() {
147             return 0;
148         }
149 
150         @Override
getMetricsCategory()151         public int getMetricsCategory() {
152             return 0;
153         }
154 
155         /**
156         * Get the setting string of the vibration intensity setting this preference is dealing with.
157         */
158         @Override
getVibrationIntensitySetting()159         protected String getVibrationIntensitySetting() {
160             return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
161         }
162 
163         @Override
getVibrationEnabledSetting()164         protected String getVibrationEnabledSetting() {
165             return "";
166         }
167 
168         @Override
getDefaultVibrationIntensity()169         protected int getDefaultVibrationIntensity() {
170             return Vibrator.VIBRATION_INTENSITY_MEDIUM;
171         }
172 
173         @Override
getContext()174         public Context getContext() {
175             return mContext;
176         }
177     }
178 }
179