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_HIGH; 21import static android.app.NotificationManager.IMPORTANCE_LOW; 22import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; 23import static junit.framework.Assert.assertFalse; 24import static junit.framework.Assert.assertTrue; 25import static org.junit.Assert.assertEquals; 26import static org.mockito.ArgumentMatchers.any; 27import static org.mockito.ArgumentMatchers.anyInt; 28import static org.mockito.Mockito.mock; 29import static org.mockito.Mockito.spy; 30import static org.mockito.Mockito.times; 31import static org.mockito.Mockito.verify; 32import static org.mockito.Mockito.when; 33 34import android.app.NotificationChannel; 35import android.app.NotificationManager; 36import android.content.Context; 37import android.os.UserManager; 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 AllowSoundPreferenceControllerTest { 56 57 private Context mContext; 58 @Mock 59 private NotificationBackend mBackend; 60 @Mock 61 private NotificationManager mNm; 62 @Mock 63 private UserManager mUm; 64 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 65 private PreferenceScreen mScreen; 66 67 @Mock 68 private NotificationSettingsBase.ImportanceListener mImportanceListener; 69 70 private AllowSoundPreferenceController mController; 71 72 @Before 73 public void setUp() { 74 MockitoAnnotations.initMocks(this); 75 ShadowApplication shadowApplication = ShadowApplication.getInstance(); 76 shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm); 77 shadowApplication.setSystemService(Context.USER_SERVICE, mUm); 78 mContext = RuntimeEnvironment.application; 79 mController = 80 spy(new AllowSoundPreferenceController(mContext, mImportanceListener, mBackend)); 81 } 82 83 @Test 84 public void testNoCrashIfNoOnResume() throws Exception { 85 mController.isAvailable(); 86 mController.updateState(mock(RestrictedSwitchPreference.class)); 87 mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true); 88 } 89 90 @Test 91 public void testIsAvailable_notIfNull() throws Exception { 92 mController.onResume(null, mock(NotificationChannel.class), null, null); 93 assertFalse(mController.isAvailable()); 94 95 mController.onResume(mock(NotificationBackend.AppRow.class), null, null, null); 96 assertFalse(mController.isAvailable()); 97 } 98 99 @Test 100 public void testIsAvailable_notIfAppBlocked() throws Exception { 101 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 102 appRow.banned = true; 103 mController.onResume(appRow, mock(NotificationChannel.class), null, null); 104 assertFalse(mController.isAvailable()); 105 } 106 107 @Test 108 public void testIsAvailable_notIfAppCreatedChannel() throws Exception { 109 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 110 NotificationChannel channel = mock(NotificationChannel.class); 111 when(channel.getId()).thenReturn("something new"); 112 mController.onResume(appRow, channel, null, null); 113 assertFalse(mController.isAvailable()); 114 } 115 116 @Test 117 public void testIsAvailable() throws Exception { 118 NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); 119 NotificationChannel channel = mock(NotificationChannel.class); 120 when(channel.getImportance()).thenReturn(IMPORTANCE_LOW); 121 when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID); 122 mController.onResume(appRow, channel, null, null); 123 assertTrue(mController.isAvailable()); 124 } 125 126 @Test 127 public void testUpdateState_disabledByAdmin() throws Exception { 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(mContext); 134 mController.updateState(pref); 135 136 assertFalse(pref.isEnabled()); 137 } 138 139 @Test 140 public void testUpdateState_notConfigurable() throws Exception { 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(mContext); 149 mController.updateState(pref); 150 151 assertFalse(pref.isEnabled()); 152 } 153 154 @Test 155 public void testUpdateState_configurable() throws Exception { 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(mContext); 162 mController.updateState(pref); 163 164 assertTrue(pref.isEnabled()); 165 } 166 167 @Test 168 public void testUpdateState_checkedForHighImportanceChannel() throws Exception { 169 NotificationChannel channel = mock(NotificationChannel.class); 170 when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); 171 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 172 173 RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); 174 mController.updateState(pref); 175 assertTrue(pref.isChecked()); 176 } 177 178 @Test 179 public void testUpdateState_checkedForUnspecifiedImportanceChannel() throws Exception { 180 NotificationChannel channel = mock(NotificationChannel.class); 181 when(channel.getImportance()).thenReturn(IMPORTANCE_UNSPECIFIED); 182 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 183 184 RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); 185 mController.updateState(pref); 186 assertTrue(pref.isChecked()); 187 } 188 189 @Test 190 public void testUpdateState_notCheckedForLowImportanceChannel() throws Exception { 191 NotificationChannel channel = mock(NotificationChannel.class); 192 when(channel.getImportance()).thenReturn(IMPORTANCE_LOW); 193 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 194 195 RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); 196 mController.updateState(pref); 197 assertFalse(pref.isChecked()); 198 } 199 200 @Test 201 public void testOnPreferenceChange_on() { 202 NotificationChannel channel = 203 new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW); 204 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 205 206 RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); 207 when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); 208 mController.displayPreference(mScreen); 209 mController.updateState(pref); 210 pref.setChecked(true); 211 mController.onPreferenceChange(pref, true); 212 213 assertEquals(IMPORTANCE_UNSPECIFIED, mController.mChannel.getImportance()); 214 verify(mImportanceListener, times(1)).onImportanceChanged(); 215 } 216 217 @Test 218 public void testOnPreferenceChange_off() { 219 NotificationChannel channel = 220 new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH); 221 mController.onResume(new NotificationBackend.AppRow(), channel, null, null); 222 223 RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); 224 when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); 225 mController.displayPreference(mScreen); 226 mController.updateState(pref); 227 228 pref.setChecked(false); 229 mController.onPreferenceChange(pref, false); 230 231 verify(mBackend, times(1)).updateChannel(any(), anyInt(), any()); 232 assertEquals(IMPORTANCE_LOW, mController.mChannel.getImportance()); 233 verify(mImportanceListener, times(1)).onImportanceChanged(); 234 } 235} 236