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