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 17package com.android.settings.notification; 18 19import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; 20import static android.app.NotificationManager.IMPORTANCE_DEFAULT; 21import static android.app.NotificationManager.IMPORTANCE_HIGH; 22import static android.app.NotificationManager.IMPORTANCE_LOW; 23import static junit.framework.Assert.assertFalse; 24import static junit.framework.Assert.assertTrue; 25import static org.mockito.ArgumentMatchers.any; 26import static org.mockito.ArgumentMatchers.anyInt; 27import static org.mockito.Mockito.mock; 28import static org.mockito.Mockito.spy; 29import static org.mockito.Mockito.times; 30import static org.mockito.Mockito.verify; 31import static org.mockito.Mockito.when; 32 33import android.app.NotificationChannel; 34import android.app.NotificationManager; 35import android.content.Context; 36import android.os.UserManager; 37import android.os.Vibrator; 38import android.support.v7.preference.Preference; 39import android.support.v7.preference.PreferenceScreen; 40 41import com.android.settings.testutils.SettingsRobolectricTestRunner; 42import com.android.settingslib.RestrictedLockUtils; 43import com.android.settingslib.RestrictedSwitchPreference; 44 45import org.junit.Before; 46import org.junit.Test; 47import org.junit.runner.RunWith; 48import org.mockito.Answers; 49import org.mockito.Mock; 50import org.mockito.MockitoAnnotations; 51import org.robolectric.RuntimeEnvironment; 52import org.robolectric.shadows.ShadowApplication; 53 54@RunWith(SettingsRobolectricTestRunner.class) 55public class VibrationPreferenceControllerTest { 56 57 private Context mContext; 58 @Mock 59 private NotificationBackend mBackend; 60 @Mock 61 private NotificationManager mNm; 62 @Mock 63 private Vibrator mVibrator; 64 @Mock 65 private UserManager mUm; 66 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 67 private PreferenceScreen mScreen; 68 69 private VibrationPreferenceController mController; 70 71 @Before 72 public void setUp() { 73 MockitoAnnotations.initMocks(this); 74 ShadowApplication shadowApplication = ShadowApplication.getInstance(); 75 shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm); 76 shadowApplication.setSystemService(Context.USER_SERVICE, mUm); 77 shadowApplication.setSystemService(Context.VIBRATOR_SERVICE, mVibrator); 78 mContext = RuntimeEnvironment.application; 79 mController = spy(new VibrationPreferenceController(mContext, mBackend)); 80 81 // by default allow vibration 82 when(mVibrator.hasVibrator()).thenReturn(true); 83 } 84 85 @Test 86 public void testNoCrashIfNoOnResume() { 87 mController.isAvailable(); 88 mController.updateState(mock(RestrictedSwitchPreference.class)); 89 mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true); 90 } 91 92 @Test 93 public void testIsAvailable_notSystemDoesNotHave() { 94 when(mVibrator.hasVibrator()).thenReturn(false); 95 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 96 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT); 97 mController.onResume(appRow, channel, null, null); 98 assertFalse(mController.isAvailable()); 99 } 100 101 @Test 102 public void testIsAvailable_notIfNotImportant() { 103 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 104 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW); 105 mController.onResume(appRow, channel, null, null); 106 assertFalse(mController.isAvailable()); 107 } 108 109 @Test 110 public void testIsAvailable_notIfDefaultChannel() { 111 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 112 NotificationChannel channel = 113 new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT); 114 mController.onResume(appRow, channel, null, null); 115 assertFalse(mController.isAvailable()); 116 } 117 118 @Test 119 public void testIsAvailable() { 120 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 121 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT); 122 mController.onResume(appRow, channel, null, null); 123 assertTrue(mController.isAvailable()); 124 } 125 126 @Test 127 public void testUpdateState_disabledByAdmin() { 128 NotificationChannel channel = mock(NotificationChannel.class); 129 when(channel.getId()).thenReturn("something"); 130 mController.onResume(new NotificationBackend.AppRow(), channel, null, mock( 131 RestrictedLockUtils.EnforcedAdmin.class)); 132 133 Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application); 134 mController.updateState(pref); 135 136 assertFalse(pref.isEnabled()); 137 } 138 139 @Test 140 public void testUpdateState_notConfigurable() { 141 String lockedId = "locked"; 142 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 143 appRow.lockedChannelId = lockedId; 144 NotificationChannel channel = mock(NotificationChannel.class); 145 when(channel.getId()).thenReturn(lockedId); 146 mController.onResume(appRow, channel, null, null); 147 148 Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application); 149 mController.updateState(pref); 150 151 assertFalse(pref.isEnabled()); 152 } 153 154 @Test 155 public void testUpdateState_configurable() { 156 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 157 NotificationChannel channel = mock(NotificationChannel.class); 158 when(channel.getId()).thenReturn("something"); 159 mController.onResume(appRow, channel, null, null); 160 161 Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application); 162 mController.updateState(pref); 163 164 assertTrue(pref.isEnabled()); 165 } 166 167 @Test 168 public void testUpdateState_vibrateOn() { 169 NotificationChannel channel = mock(NotificationChannel.class); 170 when(channel.shouldVibrate()).thenReturn(true); 171 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 172 173 RestrictedSwitchPreference pref = 174 new RestrictedSwitchPreference(RuntimeEnvironment.application); 175 mController.updateState(pref); 176 assertTrue(pref.isChecked()); 177 } 178 179 @Test 180 public void testUpdateState_vibrateOff() { 181 NotificationChannel channel = mock(NotificationChannel.class); 182 when(channel.shouldVibrate()).thenReturn(false); 183 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 184 185 RestrictedSwitchPreference pref = 186 new RestrictedSwitchPreference(RuntimeEnvironment.application); 187 mController.updateState(pref); 188 assertFalse(pref.isChecked()); 189 } 190 191 @Test 192 public void testOnPreferenceChange_on() { 193 NotificationChannel channel = 194 new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT); 195 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 196 197 RestrictedSwitchPreference pref = 198 new RestrictedSwitchPreference(RuntimeEnvironment.application); 199 mController.updateState(pref); 200 201 mController.onPreferenceChange(pref, true); 202 203 assertTrue(channel.shouldVibrate()); 204 verify(mBackend, times(1)).updateChannel(any(), anyInt(), any()); 205 } 206 207 @Test 208 public void testOnPreferenceChange_off() { 209 NotificationChannel channel = 210 new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH); 211 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 212 213 RestrictedSwitchPreference pref = 214 new RestrictedSwitchPreference(RuntimeEnvironment.application); 215 when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); 216 mController.displayPreference(mScreen); 217 mController.updateState(pref); 218 219 mController.onPreferenceChange(pref, false); 220 221 assertFalse(channel.shouldVibrate()); 222 verify(mBackend, times(1)).updateChannel(any(), anyInt(), any()); 223 } 224} 225