1 /*
2  * Copyright (C) 2022 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.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.when;
23 
24 import android.content.Context;
25 import android.media.AudioManager;
26 import android.os.VibrationAttributes;
27 import android.os.Vibrator;
28 import android.provider.Settings;
29 
30 import androidx.preference.PreferenceScreen;
31 import androidx.preference.SwitchPreference;
32 import androidx.test.core.app.ApplicationProvider;
33 
34 import com.android.settings.R;
35 import com.android.settings.core.BasePreferenceController;
36 import com.android.settingslib.core.lifecycle.Lifecycle;
37 
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 import org.robolectric.RobolectricTestRunner;
44 
45 @RunWith(RobolectricTestRunner.class)
46 public class NotificationVibrationTogglePreferenceControllerTest {
47 
48     private static final String PREFERENCE_KEY = "preference_key";
49 
50     @Mock private PreferenceScreen mScreen;
51     @Mock private AudioManager mAudioManager;
52 
53     private Lifecycle mLifecycle;
54     private Context mContext;
55     private Vibrator mVibrator;
56     private NotificationVibrationTogglePreferenceController mController;
57     private SwitchPreference mPreference;
58 
59     @Before
setUp()60     public void setUp() {
61         MockitoAnnotations.initMocks(this);
62         mLifecycle = new Lifecycle(() -> mLifecycle);
63         mContext = spy(ApplicationProvider.getApplicationContext());
64         when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
65         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
66         mVibrator = mContext.getSystemService(Vibrator.class);
67         mController = new NotificationVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
68         mLifecycle.addObserver(mController);
69         mPreference = new SwitchPreference(mContext);
70         mPreference.setSummary("Test summary");
71         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
72         mController.displayPreference(mScreen);
73     }
74 
75     @Test
verifyConstants()76     public void verifyConstants() {
77         assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
78         assertThat(mController.getAvailabilityStatus())
79                 .isEqualTo(BasePreferenceController.AVAILABLE);
80     }
81 
82     @Test
missingSetting_shouldReturnDefault()83     public void missingSetting_shouldReturnDefault() {
84         Settings.System.putString(mContext.getContentResolver(),
85                 Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
86         mController.updateState(mPreference);
87         assertThat(mPreference.isChecked()).isTrue();
88     }
89 
90     @Test
updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary()91     public void updateState_ringerModeUpdates_shouldPreserveSettingAndDisplaySummary() {
92         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
93                 Vibrator.VIBRATION_INTENSITY_LOW);
94 
95         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
96         mController.updateState(mPreference);
97         assertThat(mPreference.isChecked()).isTrue();
98         assertThat(mPreference.getSummary()).isNull();
99         assertThat(mPreference.isEnabled()).isTrue();
100 
101         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
102         mController.updateState(mPreference);
103         assertThat(mPreference.isChecked()).isFalse();
104         assertThat(mPreference.getSummary()).isNotNull();
105         assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString(
106                 R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary));
107         assertThat(mPreference.isEnabled()).isFalse();
108 
109         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
110         mController.updateState(mPreference);
111         assertThat(mPreference.isChecked()).isTrue();
112         assertThat(mPreference.getSummary()).isNull();
113         assertThat(mPreference.isEnabled()).isTrue();
114     }
115 
116     @Test
updateState_shouldDisplayOnOffState()117     public void updateState_shouldDisplayOnOffState() {
118         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
119                 Vibrator.VIBRATION_INTENSITY_HIGH);
120         mController.updateState(mPreference);
121         assertThat(mPreference.isChecked()).isTrue();
122 
123         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
124                 Vibrator.VIBRATION_INTENSITY_MEDIUM);
125         mController.updateState(mPreference);
126         assertThat(mPreference.isChecked()).isTrue();
127 
128         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
129                 Vibrator.VIBRATION_INTENSITY_LOW);
130         mController.updateState(mPreference);
131         assertThat(mPreference.isChecked()).isTrue();
132 
133         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
134                 Vibrator.VIBRATION_INTENSITY_OFF);
135         mController.updateState(mPreference);
136         assertThat(mPreference.isChecked()).isFalse();
137     }
138 
139     @Test
setChecked_updatesIntensityAndDependentSettings()140     public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
141         updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
142                 Vibrator.VIBRATION_INTENSITY_OFF);
143         mController.updateState(mPreference);
144         assertThat(mPreference.isChecked()).isFalse();
145 
146         mController.setChecked(true);
147         assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY)).isEqualTo(
148                 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
149 
150         mController.setChecked(false);
151         assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
152                 .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
153     }
154 
updateSetting(String key, int value)155     private void updateSetting(String key, int value) {
156         Settings.System.putInt(mContext.getContentResolver(), key, value);
157     }
158 
readSetting(String settingKey)159     private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
160         return Settings.System.getInt(mContext.getContentResolver(), settingKey);
161     }
162 }
163