Home | History | Annotate | Download | only in statusbar
      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 
    167     private NotificationEntryManager getEntryManager() {
    168         if (mEntryManager == null) {
    169             mEntryManager = Dependency.get(NotificationEntryManager.class);
    170         }
    171         return mEntryManager;
    172     }
    173 
    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 
    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 
    255     public boolean shouldShowLockscreenNotifications() {
    256         return mShowLockscreenNotifications;
    257     }
    258 
    259     public boolean shouldAllowLockscreenRemoteInput() {
    260         return mAllowLockscreenRemoteInput;
    261     }
    262 
    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      */
    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      */
    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      */
    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 
    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 
    320     private boolean hideSilentNotificationsOnLockscreen() {
    321         return Settings.Secure.getInt(mContext.getContentResolver(),
    322                 Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
    323     }
    324 
    325     private void setShowLockscreenNotifications(boolean show) {
    326         mShowLockscreenNotifications = show;
    327     }
    328 
    329     private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
    330         mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
    331     }
    332 
    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      */
    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 
    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      */
    394     public void setLockscreenPublicMode(boolean publicMode, int userId) {
    395         mLockscreenPublicMode.put(userId, publicMode);
    396     }
    397 
    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
    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      */
    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. */
    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 
    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 
    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 
    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      */
    481     public int getCurrentUserId() {
    482         return mCurrentUserId;
    483     }
    484 
    485     public SparseArray<UserInfo> getCurrentProfiles() {
    486         return mCurrentProfiles;
    487     }
    488 
    489     @Override
    490     public void onStateChanged(int newState) {
    491         mState = newState;
    492         updatePublicMode();
    493     }
    494 
    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
    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 
    563     private boolean isSecure(int userId) {
    564         return mKeyguardMonitor.isSecure() || mLockPatternUtils.isSecure(userId);
    565     }
    566 
    567     @Override
    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