1 /* 2 * Copyright (C) 2019 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.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; 20 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; 21 import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; 22 import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS; 23 24 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 25 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 26 import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; 27 28 import static com.google.common.truth.Truth.assertThat; 29 30 import static org.mockito.ArgumentMatchers.anyInt; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.Mockito.when; 33 34 import android.app.KeyguardManager; 35 import android.app.admin.DevicePolicyManager; 36 import android.content.Context; 37 import android.os.UserHandle; 38 import android.os.UserManager; 39 import android.provider.Settings; 40 41 import androidx.preference.Preference; 42 import androidx.preference.PreferenceScreen; 43 44 import com.android.internal.widget.LockPatternUtils; 45 import com.android.settings.testutils.FakeFeatureFactory; 46 import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; 47 import com.android.settings.testutils.shadow.ShadowUtils; 48 import com.android.settingslib.RestrictedSwitchPreference; 49 50 import org.junit.After; 51 import org.junit.Before; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 import org.robolectric.RobolectricTestRunner; 57 import org.robolectric.RuntimeEnvironment; 58 import org.robolectric.annotation.Config; 59 60 @RunWith(RobolectricTestRunner.class) 61 @Config(shadows = { 62 ShadowUtils.class, 63 ShadowRestrictedLockUtilsInternal.class, 64 }) 65 public class RedactNotificationPreferenceControllerTest { 66 67 @Mock 68 private DevicePolicyManager mDpm; 69 @Mock 70 UserManager mUm; 71 @Mock 72 KeyguardManager mKm; 73 @Mock 74 private PreferenceScreen mScreen; 75 @Mock 76 private LockPatternUtils mLockPatternUtils; 77 @Mock 78 private Context mMockContext; 79 80 private Context mContext; 81 private RedactNotificationPreferenceController mController; 82 private RedactNotificationPreferenceController mWorkController; 83 private RestrictedSwitchPreference mPreference; 84 private RestrictedSwitchPreference mWorkPreference; 85 86 @Before setUp()87 public void setUp() { 88 MockitoAnnotations.initMocks(this); 89 mContext = RuntimeEnvironment.application; 90 91 FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest(); 92 when(featureFactory.securityFeatureProvider.getLockPatternUtils(mMockContext)) 93 .thenReturn(mLockPatternUtils); 94 when(mMockContext.getContentResolver()).thenReturn(mContext.getContentResolver()); 95 when(mMockContext.getSystemService(UserManager.class)).thenReturn(mUm); 96 when(mMockContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDpm); 97 when(mMockContext.getSystemService(KeyguardManager.class)).thenReturn(mKm); 98 when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {0}); 99 100 mController = new RedactNotificationPreferenceController( 101 mMockContext, RedactNotificationPreferenceController.KEY_LOCKSCREEN_REDACT); 102 mPreference = new RestrictedSwitchPreference(mContext); 103 mPreference.setKey(mController.getPreferenceKey()); 104 when(mScreen.findPreference( 105 mController.getPreferenceKey())).thenReturn(mPreference); 106 assertThat(mController.mProfileUserId).isEqualTo(0); 107 108 when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {0, 10}); 109 mWorkController = new RedactNotificationPreferenceController(mMockContext, 110 RedactNotificationPreferenceController.KEY_LOCKSCREEN_WORK_PROFILE_REDACT); 111 mWorkPreference = new RestrictedSwitchPreference(mContext); 112 mWorkPreference.setKey(mWorkController.getPreferenceKey()); 113 when(mScreen.findPreference( 114 mWorkController.getPreferenceKey())).thenReturn(mWorkPreference); 115 assertThat(mWorkController.mProfileUserId).isEqualTo(10); 116 } 117 118 @After tearDown()119 public void tearDown() { 120 ShadowRestrictedLockUtilsInternal.reset(); 121 } 122 123 @Test getAvailabilityStatus_noSecureLockscreen()124 public void getAvailabilityStatus_noSecureLockscreen() { 125 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false); 126 Settings.Secure.putIntForUser(mContext.getContentResolver(), 127 LOCK_SCREEN_SHOW_NOTIFICATIONS, 128 1, 0); 129 Settings.Secure.putIntForUser(mContext.getContentResolver(), 130 LOCK_SCREEN_SHOW_NOTIFICATIONS, 131 1, 10); 132 133 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 134 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 135 } 136 137 @Test getAvailabilityStatus_noWorkProfile()138 public void getAvailabilityStatus_noWorkProfile() { 139 // reset controllers with no work profile 140 when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {UserHandle.myUserId()}); 141 mWorkController = new RedactNotificationPreferenceController(mMockContext, 142 RedactNotificationPreferenceController.KEY_LOCKSCREEN_WORK_PROFILE_REDACT); 143 mController = new RedactNotificationPreferenceController(mMockContext, 144 RedactNotificationPreferenceController.KEY_LOCKSCREEN_REDACT); 145 146 // should otherwise show 147 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 148 Settings.Secure.putIntForUser(mContext.getContentResolver(), 149 LOCK_SCREEN_SHOW_NOTIFICATIONS, 150 1, 0); 151 152 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 153 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 154 } 155 156 @Test displayPreference_adminSaysNoRedaction()157 public void displayPreference_adminSaysNoRedaction() { 158 ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures( 159 KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 160 161 mController.displayPreference(mScreen); 162 RestrictedSwitchPreference primaryPref = 163 mScreen.findPreference(mController.getPreferenceKey()); 164 assertThat(primaryPref.isDisabledByAdmin()).isTrue(); 165 mWorkController.displayPreference(mScreen); 166 RestrictedSwitchPreference workPref = 167 mScreen.findPreference(mWorkController.getPreferenceKey()); 168 assertThat(workPref.isDisabledByAdmin()).isTrue(); 169 } 170 171 @Test displayPreference_adminSaysNoSecure()172 public void displayPreference_adminSaysNoSecure() { 173 ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures( 174 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 175 176 mController.displayPreference(mScreen); 177 RestrictedSwitchPreference primaryPref = 178 mScreen.findPreference(mController.getPreferenceKey()); 179 assertThat(primaryPref.isDisabledByAdmin()).isTrue(); 180 mWorkController.displayPreference(mScreen); 181 RestrictedSwitchPreference workPref = 182 mScreen.findPreference(mWorkController.getPreferenceKey()); 183 assertThat(workPref.isDisabledByAdmin()).isTrue(); 184 } 185 186 @Test displayPreference()187 public void displayPreference() { 188 ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(0); 189 190 mController.displayPreference(mScreen); 191 RestrictedSwitchPreference primaryPref = 192 mScreen.findPreference(mController.getPreferenceKey()); 193 assertThat(primaryPref.isDisabledByAdmin()).isFalse(); 194 mWorkController.displayPreference(mScreen); 195 RestrictedSwitchPreference workPref = 196 mScreen.findPreference(mWorkController.getPreferenceKey()); 197 assertThat(workPref.isDisabledByAdmin()).isFalse(); 198 } 199 200 @Test getAvailabilityStatus_adminSaysNoNotifications()201 public void getAvailabilityStatus_adminSaysNoNotifications() { 202 when(mDpm.getKeyguardDisabledFeatures(eq(null), anyInt())).thenReturn( 203 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 204 205 // should otherwise show 206 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 207 Settings.Secure.putIntForUser(mContext.getContentResolver(), 208 LOCK_SCREEN_SHOW_NOTIFICATIONS, 209 1, 0); 210 Settings.Secure.putIntForUser(mContext.getContentResolver(), 211 LOCK_SCREEN_SHOW_NOTIFICATIONS, 212 1, 10); 213 214 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 215 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 216 } 217 218 @Test getAvailabilityStatus_noNotifications()219 public void getAvailabilityStatus_noNotifications() { 220 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 221 222 Settings.Secure.putIntForUser(mContext.getContentResolver(), 223 LOCK_SCREEN_SHOW_NOTIFICATIONS, 224 0, 0); 225 Settings.Secure.putIntForUser(mContext.getContentResolver(), 226 LOCK_SCREEN_SHOW_NOTIFICATIONS, 227 0, 10); 228 229 assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 230 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 231 } 232 233 @Test getAvailabilityStatus_workProfileLocked()234 public void getAvailabilityStatus_workProfileLocked() { 235 // should otherwise show 236 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 237 Settings.Secure.putIntForUser(mContext.getContentResolver(), 238 LOCK_SCREEN_SHOW_NOTIFICATIONS, 239 1, 0); 240 Settings.Secure.putIntForUser(mContext.getContentResolver(), 241 LOCK_SCREEN_SHOW_NOTIFICATIONS, 242 1, 10); 243 244 when(mKm.isDeviceLocked(10)).thenReturn(true); 245 246 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 247 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 248 } 249 250 @Test getAvailabilityStatus_show()251 public void getAvailabilityStatus_show() { 252 // should otherwise show 253 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 254 Settings.Secure.putIntForUser(mContext.getContentResolver(), 255 LOCK_SCREEN_SHOW_NOTIFICATIONS, 256 1, 0); 257 Settings.Secure.putIntForUser(mContext.getContentResolver(), 258 LOCK_SCREEN_SHOW_NOTIFICATIONS, 259 1, 10); 260 261 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 262 assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 263 } 264 265 @Test isChecked()266 public void isChecked() { 267 Settings.Secure.putIntForUser(mContext.getContentResolver(), 268 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 269 1, 0); 270 271 assertThat(mController.isChecked()).isTrue(); 272 273 Settings.Secure.putIntForUser(mContext.getContentResolver(), 274 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 275 0, 0); 276 277 assertThat(mController.isChecked()).isFalse(); 278 } 279 280 @Test isChecked_work()281 public void isChecked_work() { 282 Settings.Secure.putIntForUser(mContext.getContentResolver(), 283 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 284 1, 10); 285 286 assertThat(mWorkController.isChecked()).isTrue(); 287 288 Settings.Secure.putIntForUser(mContext.getContentResolver(), 289 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 290 0, 10); 291 292 assertThat(mWorkController.isChecked()).isFalse(); 293 } 294 295 @Test isChecked_admin()296 public void isChecked_admin() { 297 Settings.Secure.putIntForUser(mContext.getContentResolver(), 298 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 299 1, 0); 300 301 ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures( 302 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 303 304 assertThat(mController.isChecked()).isFalse(); 305 } 306 307 @Test setChecked_false()308 public void setChecked_false() throws Exception { 309 Settings.Secure.putIntForUser(mContext.getContentResolver(), 310 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 311 1, 0); 312 313 mController.setChecked(false); 314 assertThat(Settings.Secure.getIntForUser( 315 mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0)) 316 .isEqualTo(0); 317 } 318 319 @Test setChecked_workProfile_false()320 public void setChecked_workProfile_false() throws Exception { 321 Settings.Secure.putIntForUser(mContext.getContentResolver(), 322 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 323 1, 10); 324 325 mWorkController.setChecked(false); 326 assertThat(Settings.Secure.getIntForUser( 327 mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 10)) 328 .isEqualTo(0); 329 } 330 331 @Test setChecked_true()332 public void setChecked_true() throws Exception { 333 Settings.Secure.putIntForUser(mContext.getContentResolver(), 334 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 335 0, 0); 336 Settings.Secure.putIntForUser(mContext.getContentResolver(), 337 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 338 0, 10); 339 340 mController.setChecked(true); 341 mWorkController.setChecked(true); 342 assertThat(Settings.Secure.getIntForUser( 343 mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 10)) 344 .isEqualTo(1); 345 assertThat(Settings.Secure.getIntForUser( 346 mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0)) 347 .isEqualTo(1); 348 } 349 } 350 351