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