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