Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java +53 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; Loading @@ -37,12 +38,15 @@ import android.util.SparseBooleanArray; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.OverviewProxyService; import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import java.io.FileDescriptor; Loading @@ -52,7 +56,7 @@ import java.io.PrintWriter; * Handles keeping track of the current user, profiles, and various things related to hiding * contents, redacting notifications, and the lockscreen. */ public class NotificationLockscreenUserManager implements Dumpable { public class NotificationLockscreenUserManager implements Dumpable, StateListener { private static final String TAG = "LockscreenUserManager"; private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false; public static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; Loading @@ -67,9 +71,13 @@ public class NotificationLockscreenUserManager implements Dumpable { Dependency.get(DeviceProvisionedController.class); private final UserManager mUserManager; private final IStatusBarService mBarService; private final LockPatternUtils mLockPatternUtils; private final KeyguardManager mKeyguardManager; private StatusBarKeyguardViewManager mKeyguardViewManager; private boolean mShowLockscreenNotifications; private boolean mAllowLockscreenRemoteInput; private int mState = StatusBarState.SHADE; protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() { @Override Loading @@ -84,7 +92,9 @@ public class NotificationLockscreenUserManager implements Dumpable { mEntryManager.updateNotifications(); } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) { if (userId != mCurrentUserId && isCurrentProfile(userId)) { updatePublicMode(); mPresenter.onWorkChallengeChanged(); mEntryManager.updateNotifications(); } } } Loading @@ -100,8 +110,9 @@ public class NotificationLockscreenUserManager implements Dumpable { Log.v(TAG, "userId " + mCurrentUserId + " is in the house"); updateLockscreenNotificationSetting(); updatePublicMode(); mPresenter.onUserSwitched(mCurrentUserId); mEntryManager.getNotificationData().filterAndSort(); } else if (Intent.ACTION_USER_ADDED.equals(action)) { updateCurrentProfilesCache(); } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { Loading Loading @@ -150,6 +161,9 @@ public class NotificationLockscreenUserManager implements Dumpable { mCurrentUserId = ActivityManager.getCurrentUser(); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mLockPatternUtils = new LockPatternUtils(mContext); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); Dependency.get(StatusBarStateController.class).addListener(this); } public void setUpWithPresenter(NotificationPresenter presenter, Loading Loading @@ -239,6 +253,43 @@ public class NotificationLockscreenUserManager implements Dumpable { } } public void setKeyguardViewManager(StatusBarKeyguardViewManager sbkvm) { mKeyguardViewManager = sbkvm; } @Override public void onStateChanged(int newState) { mState = newState; updatePublicMode(); } public void updatePublicMode() { //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns // false when it should be true. Therefore, if we are not on the SHADE, don't even bother // asking if the keyguard is showing. We still need to check it though because showing the // camera on the keyguard has a state of SHADE but the keyguard is still showing. boolean showingKeyguard = mState != StatusBarState.SHADE || mKeyguardViewManager.isShowing(); boolean devicePublic = showingKeyguard && mKeyguardViewManager.isSecure(getCurrentUserId()); SparseArray<UserInfo> currentProfiles = getCurrentProfiles(); for (int i = currentProfiles.size() - 1; i >= 0; i--) { final int userId = currentProfiles.valueAt(i).id; boolean isProfilePublic = devicePublic; if (!devicePublic && userId != mCurrentUserId) { // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge // due to a race condition where this code could be called before // TrustManagerService updates its internal records, resulting in an incorrect // state being cached in mLockscreenPublicMode. (b/35951989) if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) && mKeyguardViewManager.isSecure(userId)) { isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } setLockscreenPublicMode(isProfilePublic, userId); } } /** * Returns true if notifications are temporarily disabled for this user for security reasons, * regardless of the normal settings for that user. Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +3 −35 Original line number Diff line number Diff line Loading @@ -1167,6 +1167,8 @@ public class StatusBar extends SystemUI implements DemoMode, mScrimController, this, UnlockMethodCache.getInstance(mContext)); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, getBouncerContainer(), mNotificationPanel, mBiometricUnlockController); //TODO: Can we put the keyguard view manager in Dependency? mLockscreenUserManager.setKeyguardViewManager(mStatusBarKeyguardViewManager); mKeyguardIndicationController .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); Loading Loading @@ -2946,8 +2948,6 @@ public class StatusBar extends SystemUI implements DemoMode, // End old BaseStatusBar.userSwitched if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); animateCollapsePanels(); updatePublicMode(); mEntryManager.getNotificationData().filterAndSort(); if (mReinflateNotificationsOnUserSwitched) { mEntryManager.updateNotificationsOnDensityOrFontScaleChanged(); mReinflateNotificationsOnUserSwitched = false; Loading Loading @@ -3493,7 +3493,7 @@ public class StatusBar extends SystemUI implements DemoMode, // notify listeners. // If the state didn't change, we may still need to update public mode updatePublicMode(); mLockscreenUserManager.updatePublicMode(); mEntryManager.updateNotifications(); } View viewToClick = null; Loading Loading @@ -3581,34 +3581,6 @@ public class StatusBar extends SystemUI implements DemoMode, mScrimController.setExpansionAffectsAlpha(true); } // TODO: Move this to NotificationLockscreenUserManager. private void updatePublicMode() { final boolean showingKeyguard = mStatusBarKeyguardViewManager.isShowing(); final boolean devicePublic = showingKeyguard && mStatusBarKeyguardViewManager.isSecure( mLockscreenUserManager.getCurrentUserId()); // Look for public mode users. Users are considered public in either case of: // - device keyguard is shown in secure mode; // - profile is locked with a work challenge. SparseArray<UserInfo> currentProfiles = mLockscreenUserManager.getCurrentProfiles(); for (int i = currentProfiles.size() - 1; i >= 0; i--) { final int userId = currentProfiles.valueAt(i).id; boolean isProfilePublic = devicePublic; if (!devicePublic && userId != mLockscreenUserManager.getCurrentUserId()) { // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge // due to a race condition where this code could be called before // TrustManagerService updates its internal records, resulting in an incorrect // state being cached in mLockscreenPublicMode. (b/35951989) if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) && mStatusBarKeyguardViewManager.isSecure(userId)) { isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } mLockscreenUserManager.setLockscreenPublicMode(isProfilePublic, userId); } } /** * Switches theme from light to dark and vice-versa. */ Loading Loading @@ -3799,8 +3771,6 @@ public class StatusBar extends SystemUI implements DemoMode, } } updateDozingState(); updatePublicMode(); mEntryManager.updateNotifications(); checkBarModes(); updateScrimController(); updateMediaMetaData(false, mState != StatusBarState.KEYGUARD); Loading Loading @@ -4053,8 +4023,6 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onWorkChallengeChanged() { updatePublicMode(); mEntryManager.updateNotifications(); if (mPendingWorkRemoteInputView != null && !mLockscreenUserManager.isAnyProfilePublicMode()) { // Expand notification panel and the notification row, then click on remote input view Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +7 −0 Original line number Diff line number Diff line Loading @@ -40,8 +40,11 @@ import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Log; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.google.android.collect.Lists; Loading @@ -61,7 +64,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { // Dependency mocks: @Mock private NotificationEntryManager mEntryManager; @Mock private NotificationData mNotificationData; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBarKeyguardViewManager mKeyguardViewManager; private int mCurrentUserId; private TestNotificationLockscreenUserManager mLockscreenUserManager; Loading @@ -79,9 +84,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { when(mUserManager.getProfiles(mCurrentUserId)).thenReturn(Lists.newArrayList( new UserInfo(mCurrentUserId, "", 0), new UserInfo(mCurrentUserId + 1, "", 0))); when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper())); when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); mLockscreenUserManager.setUpWithPresenter(mPresenter, mEntryManager); mLockscreenUserManager.setKeyguardViewManager(mKeyguardViewManager); } @Test Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java +53 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; Loading @@ -37,12 +38,15 @@ import android.util.SparseBooleanArray; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.OverviewProxyService; import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import java.io.FileDescriptor; Loading @@ -52,7 +56,7 @@ import java.io.PrintWriter; * Handles keeping track of the current user, profiles, and various things related to hiding * contents, redacting notifications, and the lockscreen. */ public class NotificationLockscreenUserManager implements Dumpable { public class NotificationLockscreenUserManager implements Dumpable, StateListener { private static final String TAG = "LockscreenUserManager"; private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false; public static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; Loading @@ -67,9 +71,13 @@ public class NotificationLockscreenUserManager implements Dumpable { Dependency.get(DeviceProvisionedController.class); private final UserManager mUserManager; private final IStatusBarService mBarService; private final LockPatternUtils mLockPatternUtils; private final KeyguardManager mKeyguardManager; private StatusBarKeyguardViewManager mKeyguardViewManager; private boolean mShowLockscreenNotifications; private boolean mAllowLockscreenRemoteInput; private int mState = StatusBarState.SHADE; protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() { @Override Loading @@ -84,7 +92,9 @@ public class NotificationLockscreenUserManager implements Dumpable { mEntryManager.updateNotifications(); } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) { if (userId != mCurrentUserId && isCurrentProfile(userId)) { updatePublicMode(); mPresenter.onWorkChallengeChanged(); mEntryManager.updateNotifications(); } } } Loading @@ -100,8 +110,9 @@ public class NotificationLockscreenUserManager implements Dumpable { Log.v(TAG, "userId " + mCurrentUserId + " is in the house"); updateLockscreenNotificationSetting(); updatePublicMode(); mPresenter.onUserSwitched(mCurrentUserId); mEntryManager.getNotificationData().filterAndSort(); } else if (Intent.ACTION_USER_ADDED.equals(action)) { updateCurrentProfilesCache(); } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { Loading Loading @@ -150,6 +161,9 @@ public class NotificationLockscreenUserManager implements Dumpable { mCurrentUserId = ActivityManager.getCurrentUser(); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mLockPatternUtils = new LockPatternUtils(mContext); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); Dependency.get(StatusBarStateController.class).addListener(this); } public void setUpWithPresenter(NotificationPresenter presenter, Loading Loading @@ -239,6 +253,43 @@ public class NotificationLockscreenUserManager implements Dumpable { } } public void setKeyguardViewManager(StatusBarKeyguardViewManager sbkvm) { mKeyguardViewManager = sbkvm; } @Override public void onStateChanged(int newState) { mState = newState; updatePublicMode(); } public void updatePublicMode() { //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns // false when it should be true. Therefore, if we are not on the SHADE, don't even bother // asking if the keyguard is showing. We still need to check it though because showing the // camera on the keyguard has a state of SHADE but the keyguard is still showing. boolean showingKeyguard = mState != StatusBarState.SHADE || mKeyguardViewManager.isShowing(); boolean devicePublic = showingKeyguard && mKeyguardViewManager.isSecure(getCurrentUserId()); SparseArray<UserInfo> currentProfiles = getCurrentProfiles(); for (int i = currentProfiles.size() - 1; i >= 0; i--) { final int userId = currentProfiles.valueAt(i).id; boolean isProfilePublic = devicePublic; if (!devicePublic && userId != mCurrentUserId) { // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge // due to a race condition where this code could be called before // TrustManagerService updates its internal records, resulting in an incorrect // state being cached in mLockscreenPublicMode. (b/35951989) if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) && mKeyguardViewManager.isSecure(userId)) { isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } setLockscreenPublicMode(isProfilePublic, userId); } } /** * Returns true if notifications are temporarily disabled for this user for security reasons, * regardless of the normal settings for that user. Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +3 −35 Original line number Diff line number Diff line Loading @@ -1167,6 +1167,8 @@ public class StatusBar extends SystemUI implements DemoMode, mScrimController, this, UnlockMethodCache.getInstance(mContext)); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, getBouncerContainer(), mNotificationPanel, mBiometricUnlockController); //TODO: Can we put the keyguard view manager in Dependency? mLockscreenUserManager.setKeyguardViewManager(mStatusBarKeyguardViewManager); mKeyguardIndicationController .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); Loading Loading @@ -2946,8 +2948,6 @@ public class StatusBar extends SystemUI implements DemoMode, // End old BaseStatusBar.userSwitched if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); animateCollapsePanels(); updatePublicMode(); mEntryManager.getNotificationData().filterAndSort(); if (mReinflateNotificationsOnUserSwitched) { mEntryManager.updateNotificationsOnDensityOrFontScaleChanged(); mReinflateNotificationsOnUserSwitched = false; Loading Loading @@ -3493,7 +3493,7 @@ public class StatusBar extends SystemUI implements DemoMode, // notify listeners. // If the state didn't change, we may still need to update public mode updatePublicMode(); mLockscreenUserManager.updatePublicMode(); mEntryManager.updateNotifications(); } View viewToClick = null; Loading Loading @@ -3581,34 +3581,6 @@ public class StatusBar extends SystemUI implements DemoMode, mScrimController.setExpansionAffectsAlpha(true); } // TODO: Move this to NotificationLockscreenUserManager. private void updatePublicMode() { final boolean showingKeyguard = mStatusBarKeyguardViewManager.isShowing(); final boolean devicePublic = showingKeyguard && mStatusBarKeyguardViewManager.isSecure( mLockscreenUserManager.getCurrentUserId()); // Look for public mode users. Users are considered public in either case of: // - device keyguard is shown in secure mode; // - profile is locked with a work challenge. SparseArray<UserInfo> currentProfiles = mLockscreenUserManager.getCurrentProfiles(); for (int i = currentProfiles.size() - 1; i >= 0; i--) { final int userId = currentProfiles.valueAt(i).id; boolean isProfilePublic = devicePublic; if (!devicePublic && userId != mLockscreenUserManager.getCurrentUserId()) { // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge // due to a race condition where this code could be called before // TrustManagerService updates its internal records, resulting in an incorrect // state being cached in mLockscreenPublicMode. (b/35951989) if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) && mStatusBarKeyguardViewManager.isSecure(userId)) { isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } mLockscreenUserManager.setLockscreenPublicMode(isProfilePublic, userId); } } /** * Switches theme from light to dark and vice-versa. */ Loading Loading @@ -3799,8 +3771,6 @@ public class StatusBar extends SystemUI implements DemoMode, } } updateDozingState(); updatePublicMode(); mEntryManager.updateNotifications(); checkBarModes(); updateScrimController(); updateMediaMetaData(false, mState != StatusBarState.KEYGUARD); Loading Loading @@ -4053,8 +4023,6 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onWorkChallengeChanged() { updatePublicMode(); mEntryManager.updateNotifications(); if (mPendingWorkRemoteInputView != null && !mLockscreenUserManager.isAnyProfilePublicMode()) { // Expand notification panel and the notification row, then click on remote input view Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +7 −0 Original line number Diff line number Diff line Loading @@ -40,8 +40,11 @@ import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Log; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.google.android.collect.Lists; Loading @@ -61,7 +64,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { // Dependency mocks: @Mock private NotificationEntryManager mEntryManager; @Mock private NotificationData mNotificationData; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBarKeyguardViewManager mKeyguardViewManager; private int mCurrentUserId; private TestNotificationLockscreenUserManager mLockscreenUserManager; Loading @@ -79,9 +84,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { when(mUserManager.getProfiles(mCurrentUserId)).thenReturn(Lists.newArrayList( new UserInfo(mCurrentUserId, "", 0), new UserInfo(mCurrentUserId + 1, "", 0))); when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper())); when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); mLockscreenUserManager.setUpWithPresenter(mPresenter, mEntryManager); mLockscreenUserManager.setKeyguardViewManager(mKeyguardViewManager); } @Test Loading