1 /* 2 * Copyright (C) 2018 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 package com.android.systemui.statusbar; 17 18 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; 19 20 import android.app.ActivityManager; 21 import android.app.KeyguardManager; 22 import android.app.Notification; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.IntentSender; 29 import android.content.pm.UserInfo; 30 import android.database.ContentObserver; 31 import android.os.RemoteException; 32 import android.os.ServiceManager; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.provider.Settings; 36 import android.util.Log; 37 import android.util.SparseArray; 38 import android.util.SparseBooleanArray; 39 40 import com.android.internal.statusbar.IStatusBarService; 41 import com.android.internal.statusbar.NotificationVisibility; 42 import com.android.internal.widget.LockPatternUtils; 43 import com.android.keyguard.KeyguardUpdateMonitor; 44 import com.android.systemui.Dependency; 45 import com.android.systemui.Dumpable; 46 import com.android.systemui.plugins.statusbar.StatusBarStateController; 47 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; 48 import com.android.systemui.recents.OverviewProxyService; 49 import com.android.systemui.statusbar.notification.NotificationEntryManager; 50 import com.android.systemui.statusbar.notification.NotificationUtils; 51 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 52 import com.android.systemui.statusbar.notification.logging.NotificationLogger; 53 import com.android.systemui.statusbar.policy.DeviceProvisionedController; 54 import com.android.systemui.statusbar.policy.KeyguardMonitor; 55 56 import java.io.FileDescriptor; 57 import java.io.PrintWriter; 58 import java.util.ArrayList; 59 import java.util.List; 60 61 import javax.inject.Inject; 62 import javax.inject.Singleton; 63 64 /** 65 * Handles keeping track of the current user, profiles, and various things related to hiding 66 * contents, redacting notifications, and the lockscreen. 67 */ 68 @Singleton 69 public class NotificationLockscreenUserManagerImpl implements 70 Dumpable, NotificationLockscreenUserManager, StateListener { 71 private static final String TAG = "LockscreenUserManager"; 72 private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false; 73 74 private final DeviceProvisionedController mDeviceProvisionedController = 75 Dependency.get(DeviceProvisionedController.class); 76 private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); 77 78 // Lazy 79 private NotificationEntryManager mEntryManager; 80 81 private final DevicePolicyManager mDevicePolicyManager; 82 private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray(); 83 private final SparseBooleanArray mUsersWithSeperateWorkChallenge = new SparseBooleanArray(); 84 private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray(); 85 private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray(); 86 private final UserManager mUserManager; 87 private final IStatusBarService mBarService; 88 private final List<UserChangedListener> mListeners = new ArrayList<>(); 89 90 private boolean mShowLockscreenNotifications; 91 private boolean mAllowLockscreenRemoteInput; 92 private LockPatternUtils mLockPatternUtils; 93 protected KeyguardManager mKeyguardManager; 94 private int mState = StatusBarState.SHADE; 95 96 protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() { 97 @Override 98 public void onReceive(Context context, Intent intent) { 99 final String action = intent.getAction(); 100 101 if (ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) && 102 isCurrentProfile(getSendingUserId())) { 103 mUsersAllowingPrivateNotifications.clear(); 104 updateLockscreenNotificationSetting(); 105 getEntryManager().updateNotifications(); 106 } 107 } 108 }; 109 110 protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() { 111 @Override 112 public void onReceive(Context context, Intent intent) { 113 String action = intent.getAction(); 114 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 115 mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 116 updateCurrentProfilesCache(); 117 Log.v(TAG, "userId " + mCurrentUserId + " is in the house"); 118 119 updateLockscreenNotificationSetting(); 120 updatePublicMode(); 121 // The filtering needs to happen before the update call below in order to make sure 122 // the presenter has the updated notifications from the new user 123 getEntryManager().getNotificationData().filterAndSort(); 124 mPresenter.onUserSwitched(mCurrentUserId); 125 126 for (UserChangedListener listener : mListeners) { 127 listener.onUserChanged(mCurrentUserId); 128 } 129 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 130 updateCurrentProfilesCache(); 131 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { 132 // Start the overview connection to the launcher service 133 Dependency.get(OverviewProxyService.class).startConnectionToCurrentUser(); 134 } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) { 135 final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT); 136 final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX); 137 if (intentSender != null) { 138 try { 139 mContext.startIntentSender(intentSender, null, 0, 0, 0); 140 } catch (IntentSender.SendIntentException e) { 141 /* ignore */ 142 } 143 } 144 if (notificationKey != null) { 145 final int count = 146 getEntryManager().getNotificationData().getActiveNotifications().size(); 147 final int rank = getEntryManager().getNotificationData().getRank(notificationKey); 148 NotificationVisibility.NotificationLocation location = 149 NotificationLogger.getNotificationLocation( 150 getEntryManager().getNotificationData().get(notificationKey)); 151 final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, 152 rank, count, true, location); 153 try { 154 mBarService.onNotificationClick(notificationKey, nv); 155 } catch (RemoteException e) { 156 /* ignore */ 157 } 158 } 159 } 160 } 161 }; 162 163 protected final Context mContext; 164 protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); 165 166 protected int mCurrentUserId = 0; 167 protected NotificationPresenter mPresenter; 168 protected ContentObserver mLockscreenSettingsObserver; 169 protected ContentObserver mSettingsObserver; 170 getEntryManager()171 private NotificationEntryManager getEntryManager() { 172 if (mEntryManager == null) { 173 mEntryManager = Dependency.get(NotificationEntryManager.class); 174 } 175 return mEntryManager; 176 } 177 178 @Inject NotificationLockscreenUserManagerImpl(Context context)179 public NotificationLockscreenUserManagerImpl(Context context) { 180 mContext = context; 181 mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService( 182 Context.DEVICE_POLICY_SERVICE); 183 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 184 mCurrentUserId = ActivityManager.getCurrentUser(); 185 mBarService = IStatusBarService.Stub.asInterface( 186 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 187 Dependency.get(StatusBarStateController.class).addCallback(this); 188 mLockPatternUtils = new LockPatternUtils(context); 189 mKeyguardManager = context.getSystemService(KeyguardManager.class); 190 } 191 setUpWithPresenter(NotificationPresenter presenter)192 public void setUpWithPresenter(NotificationPresenter presenter) { 193 mPresenter = presenter; 194 195 mLockscreenSettingsObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) { 196 @Override 197 public void onChange(boolean selfChange) { 198 // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or 199 // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ... 200 mUsersAllowingPrivateNotifications.clear(); 201 mUsersAllowingNotifications.clear(); 202 // ... and refresh all the notifications 203 updateLockscreenNotificationSetting(); 204 getEntryManager().updateNotifications(); 205 } 206 }; 207 208 mSettingsObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) { 209 @Override 210 public void onChange(boolean selfChange) { 211 updateLockscreenNotificationSetting(); 212 if (mDeviceProvisionedController.isDeviceProvisioned()) { 213 getEntryManager().updateNotifications(); 214 } 215 } 216 }; 217 218 mContext.getContentResolver().registerContentObserver( 219 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false, 220 mLockscreenSettingsObserver, 221 UserHandle.USER_ALL); 222 223 mContext.getContentResolver().registerContentObserver( 224 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS), 225 true, 226 mLockscreenSettingsObserver, 227 UserHandle.USER_ALL); 228 229 mContext.getContentResolver().registerContentObserver( 230 Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false, 231 mSettingsObserver); 232 233 if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) { 234 mContext.getContentResolver().registerContentObserver( 235 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT), 236 false, 237 mSettingsObserver, 238 UserHandle.USER_ALL); 239 } 240 241 mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, 242 new IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 243 null, null); 244 245 IntentFilter filter = new IntentFilter(); 246 filter.addAction(Intent.ACTION_USER_SWITCHED); 247 filter.addAction(Intent.ACTION_USER_ADDED); 248 filter.addAction(Intent.ACTION_USER_UNLOCKED); 249 mContext.registerReceiver(mBaseBroadcastReceiver, filter); 250 251 IntentFilter internalFilter = new IntentFilter(); 252 internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION); 253 mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null); 254 255 updateCurrentProfilesCache(); 256 257 mSettingsObserver.onChange(false); // set up 258 } 259 shouldShowLockscreenNotifications()260 public boolean shouldShowLockscreenNotifications() { 261 return mShowLockscreenNotifications; 262 } 263 shouldAllowLockscreenRemoteInput()264 public boolean shouldAllowLockscreenRemoteInput() { 265 return mAllowLockscreenRemoteInput; 266 } 267 isCurrentProfile(int userId)268 public boolean isCurrentProfile(int userId) { 269 synchronized (mCurrentProfiles) { 270 return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null; 271 } 272 } 273 274 /** 275 * Returns true if notifications are temporarily disabled for this user for security reasons, 276 * regardless of the normal settings for that user. 277 */ shouldTemporarilyHideNotifications(int userId)278 private boolean shouldTemporarilyHideNotifications(int userId) { 279 if (userId == UserHandle.USER_ALL) { 280 userId = mCurrentUserId; 281 } 282 return KeyguardUpdateMonitor.getInstance(mContext).isUserInLockdown(userId); 283 } 284 285 /** 286 * Returns true if we're on a secure lockscreen and the user wants to hide notification data. 287 * If so, notifications should be hidden. 288 */ shouldHideNotifications(int userId)289 public boolean shouldHideNotifications(int userId) { 290 return isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId) 291 || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId)) 292 || shouldTemporarilyHideNotifications(userId); 293 } 294 295 /** 296 * Returns true if we're on a secure lockscreen and the user wants to hide notifications via 297 * package-specific override. 298 */ shouldHideNotifications(String key)299 public boolean shouldHideNotifications(String key) { 300 if (getEntryManager() == null) { 301 Log.wtf(TAG, "mEntryManager was null!", new Throwable()); 302 return true; 303 } 304 return isLockscreenPublicMode(mCurrentUserId) 305 && getEntryManager().getNotificationData().getVisibilityOverride(key) == 306 Notification.VISIBILITY_SECRET; 307 } 308 shouldShowOnKeyguard(NotificationEntry entry)309 public boolean shouldShowOnKeyguard(NotificationEntry entry) { 310 if (getEntryManager() == null) { 311 Log.wtf(TAG, "mEntryManager was null!", new Throwable()); 312 return false; 313 } 314 boolean exceedsPriorityThreshold; 315 if (NotificationUtils.useNewInterruptionModel(mContext) 316 && hideSilentNotificationsOnLockscreen()) { 317 exceedsPriorityThreshold = entry.isTopBucket(); 318 } else { 319 exceedsPriorityThreshold = 320 !getEntryManager().getNotificationData().isAmbient(entry.key); 321 } 322 return mShowLockscreenNotifications && exceedsPriorityThreshold; 323 } 324 hideSilentNotificationsOnLockscreen()325 private boolean hideSilentNotificationsOnLockscreen() { 326 return Settings.Secure.getInt(mContext.getContentResolver(), 327 Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0; 328 } 329 setShowLockscreenNotifications(boolean show)330 private void setShowLockscreenNotifications(boolean show) { 331 mShowLockscreenNotifications = show; 332 } 333 setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput)334 private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) { 335 mAllowLockscreenRemoteInput = allowLockscreenRemoteInput; 336 } 337 updateLockscreenNotificationSetting()338 protected void updateLockscreenNotificationSetting() { 339 final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(), 340 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 341 1, 342 mCurrentUserId) != 0; 343 final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures( 344 null /* admin */, mCurrentUserId); 345 final boolean allowedByDpm = (dpmFlags 346 & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0; 347 348 setShowLockscreenNotifications(show && allowedByDpm); 349 350 if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) { 351 final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(), 352 Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, 353 0, 354 mCurrentUserId) != 0; 355 final boolean remoteInputDpm = 356 (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0; 357 358 setLockscreenAllowRemoteInput(remoteInput && remoteInputDpm); 359 } else { 360 setLockscreenAllowRemoteInput(false); 361 } 362 } 363 364 /** 365 * Has the given user chosen to allow their private (full) notifications to be shown even 366 * when the lockscreen is in "public" (secure & locked) mode? 367 */ userAllowsPrivateNotificationsInPublic(int userHandle)368 public boolean userAllowsPrivateNotificationsInPublic(int userHandle) { 369 if (userHandle == UserHandle.USER_ALL) { 370 return true; 371 } 372 373 if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) { 374 final boolean allowedByUser = 0 != Settings.Secure.getIntForUser( 375 mContext.getContentResolver(), 376 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle); 377 final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle, 378 DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 379 final boolean allowed = allowedByUser && allowedByDpm; 380 mUsersAllowingPrivateNotifications.append(userHandle, allowed); 381 return allowed; 382 } 383 384 return mUsersAllowingPrivateNotifications.get(userHandle); 385 } 386 adminAllowsKeyguardFeature(int userHandle, int feature)387 private boolean adminAllowsKeyguardFeature(int userHandle, int feature) { 388 if (userHandle == UserHandle.USER_ALL) { 389 return true; 390 } 391 final int dpmFlags = 392 mDevicePolicyManager.getKeyguardDisabledFeatures(null /* admin */, userHandle); 393 return (dpmFlags & feature) == 0; 394 } 395 396 /** 397 * Save the current "public" (locked and secure) state of the lockscreen. 398 */ setLockscreenPublicMode(boolean publicMode, int userId)399 public void setLockscreenPublicMode(boolean publicMode, int userId) { 400 mLockscreenPublicMode.put(userId, publicMode); 401 } 402 isLockscreenPublicMode(int userId)403 public boolean isLockscreenPublicMode(int userId) { 404 if (userId == UserHandle.USER_ALL) { 405 return mLockscreenPublicMode.get(mCurrentUserId, false); 406 } 407 return mLockscreenPublicMode.get(userId, false); 408 } 409 410 @Override needsSeparateWorkChallenge(int userId)411 public boolean needsSeparateWorkChallenge(int userId) { 412 return mUsersWithSeperateWorkChallenge.get(userId, false); 413 } 414 415 /** 416 * Has the given user chosen to allow notifications to be shown even when the lockscreen is in 417 * "public" (secure & locked) mode? 418 */ userAllowsNotificationsInPublic(int userHandle)419 private boolean userAllowsNotificationsInPublic(int userHandle) { 420 if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) { 421 return true; 422 } 423 424 if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) { 425 final boolean allowedByUser = 0 != Settings.Secure.getIntForUser( 426 mContext.getContentResolver(), 427 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle); 428 final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle, 429 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 430 final boolean allowedBySystem = mKeyguardManager.getPrivateNotificationsAllowed(); 431 final boolean allowed = allowedByUser && allowedByDpm && allowedBySystem; 432 mUsersAllowingNotifications.append(userHandle, allowed); 433 return allowed; 434 } 435 436 return mUsersAllowingNotifications.get(userHandle); 437 } 438 439 /** @return true if the entry needs redaction when on the lockscreen. */ needsRedaction(NotificationEntry ent)440 public boolean needsRedaction(NotificationEntry ent) { 441 int userId = ent.notification.getUserId(); 442 443 boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId); 444 boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId); 445 boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction; 446 447 boolean notificationRequestsRedaction = 448 ent.notification.getNotification().visibility == Notification.VISIBILITY_PRIVATE; 449 boolean userForcesRedaction = packageHasVisibilityOverride(ent.notification.getKey()); 450 451 return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen; 452 } 453 packageHasVisibilityOverride(String key)454 private boolean packageHasVisibilityOverride(String key) { 455 if (getEntryManager() == null) { 456 Log.wtf(TAG, "mEntryManager was null!", new Throwable()); 457 return true; 458 } 459 return getEntryManager().getNotificationData().getVisibilityOverride(key) == 460 Notification.VISIBILITY_PRIVATE; 461 } 462 updateCurrentProfilesCache()463 private void updateCurrentProfilesCache() { 464 synchronized (mCurrentProfiles) { 465 mCurrentProfiles.clear(); 466 if (mUserManager != null) { 467 for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) { 468 mCurrentProfiles.put(user.id, user); 469 } 470 } 471 } 472 } 473 isAnyProfilePublicMode()474 public boolean isAnyProfilePublicMode() { 475 for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { 476 if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) { 477 return true; 478 } 479 } 480 return false; 481 } 482 483 /** 484 * Returns the current user id. This can change if the user is switched. 485 */ getCurrentUserId()486 public int getCurrentUserId() { 487 return mCurrentUserId; 488 } 489 getCurrentProfiles()490 public SparseArray<UserInfo> getCurrentProfiles() { 491 return mCurrentProfiles; 492 } 493 494 @Override onStateChanged(int newState)495 public void onStateChanged(int newState) { 496 mState = newState; 497 updatePublicMode(); 498 } 499 updatePublicMode()500 public void updatePublicMode() { 501 //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns 502 // false when it should be true. Therefore, if we are not on the SHADE, don't even bother 503 // asking if the keyguard is showing. We still need to check it though because showing the 504 // camera on the keyguard has a state of SHADE but the keyguard is still showing. 505 final boolean showingKeyguard = mState != StatusBarState.SHADE 506 || mKeyguardMonitor.isShowing(); 507 final boolean devicePublic = showingKeyguard && isSecure(getCurrentUserId()); 508 509 510 // Look for public mode users. Users are considered public in either case of: 511 // - device keyguard is shown in secure mode; 512 // - profile is locked with a work challenge. 513 SparseArray<UserInfo> currentProfiles = getCurrentProfiles(); 514 mUsersWithSeperateWorkChallenge.clear(); 515 for (int i = currentProfiles.size() - 1; i >= 0; i--) { 516 final int userId = currentProfiles.valueAt(i).id; 517 boolean isProfilePublic = devicePublic; 518 boolean needsSeparateChallenge = mLockPatternUtils.isSeparateProfileChallengeEnabled( 519 userId); 520 if (!devicePublic && userId != getCurrentUserId() 521 && needsSeparateChallenge && isSecure(userId)) { 522 // Keyguard.isDeviceLocked is updated asynchronously, assume that all profiles 523 // with separate challenge are locked when keyguard is visible to avoid race. 524 isProfilePublic = showingKeyguard || mKeyguardManager.isDeviceLocked(userId); 525 } 526 setLockscreenPublicMode(isProfilePublic, userId); 527 mUsersWithSeperateWorkChallenge.put(userId, needsSeparateChallenge); 528 } 529 getEntryManager().updateNotifications(); 530 } 531 532 @Override addUserChangedListener(UserChangedListener listener)533 public void addUserChangedListener(UserChangedListener listener) { 534 mListeners.add(listener); 535 } 536 537 // public void updatePublicMode() { 538 // //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns 539 // // false when it should be true. Therefore, if we are not on the SHADE, don't even bother 540 // // asking if the keyguard is showing. We still need to check it though because showing the 541 // // camera on the keyguard has a state of SHADE but the keyguard is still showing. 542 // final boolean showingKeyguard = mState != StatusBarState.SHADE 543 // || mKeyguardMonitor.isShowing(); 544 // final boolean devicePublic = showingKeyguard && isSecure(getCurrentUserId()); 545 // 546 // 547 // // Look for public mode users. Users are considered public in either case of: 548 // // - device keyguard is shown in secure mode; 549 // // - profile is locked with a work challenge. 550 // SparseArray<UserInfo> currentProfiles = getCurrentProfiles(); 551 // for (int i = currentProfiles.size() - 1; i >= 0; i--) { 552 // final int userId = currentProfiles.valueAt(i).id; 553 // boolean isProfilePublic = devicePublic; 554 // if (!devicePublic && userId != getCurrentUserId()) { 555 // // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge 556 // // due to a race condition where this code could be called before 557 // // TrustManagerService updates its internal records, resulting in an incorrect 558 // // state being cached in mLockscreenPublicMode. (b/35951989) 559 // if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) 560 // && isSecure(userId)) { 561 // isProfilePublic = mKeyguardManager.isDeviceLocked(userId); 562 // } 563 // } 564 // setLockscreenPublicMode(isProfilePublic, userId); 565 // } 566 // } 567 isSecure(int userId)568 private boolean isSecure(int userId) { 569 return mKeyguardMonitor.isSecure() || mLockPatternUtils.isSecure(userId); 570 } 571 572 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)573 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 574 pw.println("NotificationLockscreenUserManager state:"); 575 pw.print(" mCurrentUserId="); 576 pw.println(mCurrentUserId); 577 pw.print(" mShowLockscreenNotifications="); 578 pw.println(mShowLockscreenNotifications); 579 pw.print(" mAllowLockscreenRemoteInput="); 580 pw.println(mAllowLockscreenRemoteInput); 581 pw.print(" mCurrentProfiles="); 582 for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { 583 final int userId = mCurrentProfiles.valueAt(i).id; 584 pw.print("" + userId + " "); 585 } 586 pw.println(); 587 } 588 } 589