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.systemui.statusbar; 18 19 import static junit.framework.Assert.assertFalse; 20 import static junit.framework.Assert.assertTrue; 21 22 import static org.mockito.Mockito.clearInvocations; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.never; 25 import static org.mockito.Mockito.times; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.app.ActivityManager; 30 import android.app.KeyguardManager; 31 import android.app.Notification; 32 import android.app.admin.DevicePolicyManager; 33 import android.content.BroadcastReceiver; 34 import android.content.Context; 35 import android.content.pm.UserInfo; 36 import android.database.ContentObserver; 37 import android.os.Handler; 38 import android.os.Looper; 39 import android.os.UserHandle; 40 import android.os.UserManager; 41 import android.provider.Settings; 42 import android.testing.AndroidTestingRunner; 43 import android.testing.TestableLooper; 44 45 import androidx.test.filters.SmallTest; 46 47 import com.android.internal.widget.LockPatternUtils; 48 import com.android.systemui.Dependency; 49 import com.android.systemui.SysuiTestCase; 50 import com.android.systemui.broadcast.BroadcastDispatcher; 51 import com.android.systemui.dump.DumpManager; 52 import com.android.systemui.flags.FakeFeatureFlags; 53 import com.android.systemui.flags.Flags; 54 import com.android.systemui.plugins.statusbar.StatusBarStateController; 55 import com.android.systemui.recents.OverviewProxyService; 56 import com.android.systemui.settings.UserTracker; 57 import com.android.systemui.statusbar.NotificationLockscreenUserManager.NotificationStateChangedListener; 58 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 59 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; 60 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; 61 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; 62 import com.android.systemui.statusbar.policy.DeviceProvisionedController; 63 import com.android.systemui.statusbar.policy.KeyguardStateController; 64 import com.android.systemui.util.settings.FakeSettings; 65 66 import com.google.android.collect.Lists; 67 68 import org.junit.Before; 69 import org.junit.Test; 70 import org.junit.runner.RunWith; 71 import org.mockito.Mock; 72 import org.mockito.MockitoAnnotations; 73 74 @SmallTest 75 @RunWith(AndroidTestingRunner.class) 76 @TestableLooper.RunWithLooper 77 public class NotificationLockscreenUserManagerTest extends SysuiTestCase { 78 @Mock 79 private NotificationPresenter mPresenter; 80 @Mock 81 private UserManager mUserManager; 82 @Mock 83 private UserTracker mUserTracker; 84 85 // Dependency mocks: 86 @Mock 87 private NotificationVisibilityProvider mVisibilityProvider; 88 @Mock 89 private CommonNotifCollection mNotifCollection; 90 @Mock 91 private DevicePolicyManager mDevicePolicyManager; 92 @Mock 93 private NotificationClickNotifier mClickNotifier; 94 @Mock 95 private OverviewProxyService mOverviewProxyService; 96 @Mock 97 private KeyguardManager mKeyguardManager; 98 @Mock 99 private DeviceProvisionedController mDeviceProvisionedController; 100 @Mock 101 private StatusBarStateController mStatusBarStateController; 102 @Mock 103 private BroadcastDispatcher mBroadcastDispatcher; 104 @Mock 105 private KeyguardStateController mKeyguardStateController; 106 107 private UserInfo mCurrentUser; 108 private UserInfo mSecondaryUser; 109 private UserInfo mWorkUser; 110 private FakeSettings mSettings; 111 private TestNotificationLockscreenUserManager mLockscreenUserManager; 112 private NotificationEntry mCurrentUserNotif; 113 private NotificationEntry mSecondaryUserNotif; 114 private NotificationEntry mWorkProfileNotif; 115 private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags(); 116 117 @Before setUp()118 public void setUp() { 119 MockitoAnnotations.initMocks(this); 120 121 int currentUserId = ActivityManager.getCurrentUser(); 122 when(mUserTracker.getUserId()).thenReturn(currentUserId); 123 mSettings = new FakeSettings(); 124 mSettings.setUserId(ActivityManager.getCurrentUser()); 125 mCurrentUser = new UserInfo(currentUserId, "", 0); 126 mSecondaryUser = new UserInfo(currentUserId + 1, "", 0); 127 mWorkUser = new UserInfo(currentUserId + 2, "" /* name */, null /* iconPath */, 0, 128 UserManager.USER_TYPE_PROFILE_MANAGED); 129 130 when(mUserManager.getProfiles(currentUserId)).thenReturn(Lists.newArrayList( 131 mCurrentUser, mSecondaryUser, mWorkUser)); 132 mDependency.injectTestDependency(Dependency.MAIN_HANDLER, 133 Handler.createAsync(Looper.myLooper())); 134 135 Notification notifWithPrivateVisibility = new Notification(); 136 notifWithPrivateVisibility.visibility = Notification.VISIBILITY_PRIVATE; 137 mCurrentUserNotif = new NotificationEntryBuilder() 138 .setNotification(notifWithPrivateVisibility) 139 .setUser(new UserHandle(mCurrentUser.id)) 140 .build(); 141 mSecondaryUserNotif = new NotificationEntryBuilder() 142 .setNotification(notifWithPrivateVisibility) 143 .setUser(new UserHandle(mSecondaryUser.id)) 144 .build(); 145 mWorkProfileNotif = new NotificationEntryBuilder() 146 .setNotification(notifWithPrivateVisibility) 147 .setUser(new UserHandle(mWorkUser.id)) 148 .build(); 149 150 mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); 151 mLockscreenUserManager.setUpWithPresenter(mPresenter); 152 } 153 154 @Test testLockScreenShowNotificationsFalse()155 public void testLockScreenShowNotificationsFalse() { 156 mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0); 157 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 158 assertFalse(mLockscreenUserManager.shouldShowLockscreenNotifications()); 159 } 160 161 @Test testLockScreenShowNotificationsTrue()162 public void testLockScreenShowNotificationsTrue() { 163 mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); 164 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 165 assertTrue(mLockscreenUserManager.shouldShowLockscreenNotifications()); 166 } 167 168 @Test testLockScreenAllowPrivateNotificationsTrue()169 public void testLockScreenAllowPrivateNotificationsTrue() { 170 mSettings.putInt(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); 171 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 172 assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); 173 } 174 175 @Test testLockScreenAllowPrivateNotificationsFalse()176 public void testLockScreenAllowPrivateNotificationsFalse() { 177 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 178 mCurrentUser.id); 179 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 180 assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); 181 } 182 183 @Test testLockScreenAllowsWorkPrivateNotificationsFalse()184 public void testLockScreenAllowsWorkPrivateNotificationsFalse() { 185 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 186 mWorkUser.id); 187 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 188 assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); 189 } 190 191 @Test testLockScreenAllowsWorkPrivateNotificationsTrue()192 public void testLockScreenAllowsWorkPrivateNotificationsTrue() { 193 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 194 mWorkUser.id); 195 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 196 assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); 197 } 198 199 @Test testCurrentUserPrivateNotificationsNotRedacted()200 public void testCurrentUserPrivateNotificationsNotRedacted() { 201 // GIVEN current user doesn't allow private notifications to show 202 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 203 mCurrentUser.id); 204 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 205 206 // THEN current user's notification is redacted 207 assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); 208 } 209 210 @Test testCurrentUserPrivateNotificationsRedacted()211 public void testCurrentUserPrivateNotificationsRedacted() { 212 // GIVEN current user allows private notifications to show 213 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 214 mCurrentUser.id); 215 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 216 217 // THEN current user's notification isn't redacted 218 assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); 219 } 220 221 @Test testWorkPrivateNotificationsRedacted()222 public void testWorkPrivateNotificationsRedacted() { 223 // GIVEN work profile doesn't private notifications to show 224 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 225 mWorkUser.id); 226 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 227 228 // THEN work profile notification is redacted 229 assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); 230 } 231 232 @Test testWorkPrivateNotificationsNotRedacted()233 public void testWorkPrivateNotificationsNotRedacted() { 234 // GIVEN work profile allows private notifications to show 235 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 236 mWorkUser.id); 237 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 238 239 // THEN work profile notification isn't redacted 240 assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); 241 } 242 243 @Test testWorkPrivateNotificationsNotRedacted_otherUsersRedacted()244 public void testWorkPrivateNotificationsNotRedacted_otherUsersRedacted() { 245 // GIVEN work profile allows private notifications to show but the other users don't 246 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 247 mWorkUser.id); 248 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 249 mCurrentUser.id); 250 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 251 mSecondaryUser.id); 252 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 253 254 // THEN the work profile notification doesn't need to be redacted 255 assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); 256 257 // THEN the current user and secondary user notifications do need to be redacted 258 assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); 259 assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); 260 } 261 262 @Test testWorkProfileRedacted_otherUsersNotRedacted()263 public void testWorkProfileRedacted_otherUsersNotRedacted() { 264 // GIVEN work profile doesn't allow private notifications to show but the other users do 265 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 266 mWorkUser.id); 267 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 268 mCurrentUser.id); 269 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 270 mSecondaryUser.id); 271 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 272 273 // THEN the work profile notification needs to be redacted 274 assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); 275 276 // THEN the current user and secondary user notifications don't need to be redacted 277 assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); 278 assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); 279 } 280 281 @Test testSecondaryUserNotRedacted_currentUserRedacted()282 public void testSecondaryUserNotRedacted_currentUserRedacted() { 283 // GIVEN secondary profile allows private notifications to show but the current user 284 // doesn't allow private notifications to show 285 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, 286 mCurrentUser.id); 287 mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, 288 mSecondaryUser.id); 289 mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); 290 291 // THEN the secondary profile notification still needs to be redacted because the current 292 // user's setting takes precedence 293 assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); 294 } 295 296 @Test testUserSwitchedCallsOnUserSwitching()297 public void testUserSwitchedCallsOnUserSwitching() { 298 mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, true); 299 mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanging(mSecondaryUser.id, 300 mContext); 301 verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id); 302 } 303 304 @Test testUserSwitchedCallsOnUserSwitched()305 public void testUserSwitchedCallsOnUserSwitched() { 306 mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, false); 307 mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanged(mSecondaryUser.id, 308 mContext); 309 verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id); 310 } 311 312 @Test testIsLockscreenPublicMode()313 public void testIsLockscreenPublicMode() { 314 assertFalse(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUser.id)); 315 mLockscreenUserManager.setLockscreenPublicMode(true, mCurrentUser.id); 316 assertTrue(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUser.id)); 317 } 318 319 @Test testUpdateIsPublicMode()320 public void testUpdateIsPublicMode() { 321 when(mKeyguardStateController.isMethodSecure()).thenReturn(true); 322 323 NotificationStateChangedListener listener = mock(NotificationStateChangedListener.class); 324 mLockscreenUserManager.addNotificationStateChangedListener(listener); 325 mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); 326 327 // first call explicitly sets user 0 to not public; notifies 328 mLockscreenUserManager.updatePublicMode(); 329 assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0)); 330 verify(listener).onNotificationStateChanged(); 331 clearInvocations(listener); 332 333 // calling again has no changes; does not notify 334 mLockscreenUserManager.updatePublicMode(); 335 assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0)); 336 verify(listener, never()).onNotificationStateChanged(); 337 338 // Calling again with keyguard now showing makes user 0 public; notifies 339 when(mKeyguardStateController.isShowing()).thenReturn(true); 340 mLockscreenUserManager.updatePublicMode(); 341 assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0)); 342 verify(listener).onNotificationStateChanged(); 343 clearInvocations(listener); 344 345 // calling again has no changes; does not notify 346 mLockscreenUserManager.updatePublicMode(); 347 assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0)); 348 verify(listener, never()).onNotificationStateChanged(); 349 } 350 351 private class TestNotificationLockscreenUserManager 352 extends NotificationLockscreenUserManagerImpl { TestNotificationLockscreenUserManager(Context context)353 public TestNotificationLockscreenUserManager(Context context) { 354 super( 355 context, 356 mBroadcastDispatcher, 357 mDevicePolicyManager, 358 mUserManager, 359 mUserTracker, 360 (() -> mVisibilityProvider), 361 (() -> mNotifCollection), 362 mClickNotifier, 363 (() -> mOverviewProxyService), 364 NotificationLockscreenUserManagerTest.this.mKeyguardManager, 365 mStatusBarStateController, 366 Handler.createAsync(Looper.myLooper()), 367 mDeviceProvisionedController, 368 mKeyguardStateController, 369 mSettings, 370 mock(DumpManager.class), 371 mock(LockPatternUtils.class), 372 mFakeFeatureFlags); 373 } 374 getBaseBroadcastReceiverForTest()375 public BroadcastReceiver getBaseBroadcastReceiverForTest() { 376 return mBaseBroadcastReceiver; 377 } 378 getUserTrackerCallbackForTest()379 public UserTracker.Callback getUserTrackerCallbackForTest() { 380 return mUserChangedCallback; 381 } 382 getLockscreenSettingsObserverForTest()383 public ContentObserver getLockscreenSettingsObserverForTest() { 384 return mLockscreenSettingsObserver; 385 } 386 getSettingsObserverForTest()387 public ContentObserver getSettingsObserverForTest() { 388 return mSettingsObserver; 389 } 390 } 391 } 392