diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index b81cb2be1c4d6..3619915433789 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -4688,6 +4688,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); updateFooter(); + mController.updateImportantForAccessibility(); } updateSpeedBumpIndex(); @@ -4699,6 +4700,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); updateFooter(); + mController.updateImportantForAccessibility(); } updateSpeedBumpIndex(); @@ -4711,6 +4713,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); updateFooter(); + mController.updateImportantForAccessibility(); } updateSpeedBumpIndex(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 7b046d6c92565..9272c376d4feb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -327,6 +327,7 @@ public class NotificationStackScrollLayoutController { mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(), mLockscreenUserManager.isAnyProfilePublicMode()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); + updateImportantForAccessibility(); } }; @@ -1205,6 +1206,7 @@ public class NotificationStackScrollLayoutController { if (mView.getVisibility() == View.VISIBLE) { // Synchronize EmptyShadeView visibility with the parent container. updateShowEmptyShadeView(); + updateImportantForAccessibility(); } } @@ -1231,6 +1233,22 @@ public class NotificationStackScrollLayoutController { Trace.endSection(); } + /** + * Update the importantForAccessibility of NotificationStackScrollLayout. + *

+ * We want the NSSL to be unimportant for accessibility when there's no + * notifications in it while the device is on lock screen, to avoid unlablel NSSL view. + * Otherwise, we want it to be important for accessibility to enable accessibility + * auto-scrolling in NSSL. + */ + public void updateImportantForAccessibility() { + if (getVisibleNotificationCount() == 0 && mView.onKeyguard()) { + mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } else { + mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); + } + } + /** * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD * and false otherwise. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java index 6a0e3c6d51eb0..02666e40b98d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java @@ -35,6 +35,7 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; +import android.view.View; import androidx.test.filters.SmallTest; @@ -430,6 +431,84 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { verify(mNotificationStackScrollLayout).setStatusBarState(KEYGUARD); } + @Test + public void updateImportantForAccessibility_noChild_onKeyGuard_notImportantForA11y() { + // GIVEN: Controller is attached, active notifications is empty, + // and mNotificationStackScrollLayout.onKeyguard() is true + initController(/* viewIsAttached= */ true); + when(mNotificationStackScrollLayout.onKeyguard()).thenReturn(true); + mController.getNotifStackController().setNotifStats(NotifStats.getEmpty()); + + // WHEN: call updateImportantForAccessibility + mController.updateImportantForAccessibility(); + + // THEN: mNotificationStackScrollLayout should not be important for A11y + verify(mNotificationStackScrollLayout) + .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } + + @Test + public void updateImportantForAccessibility_hasChild_onKeyGuard_importantForA11y() { + // GIVEN: Controller is attached, active notifications is not empty, + // and mNotificationStackScrollLayout.onKeyguard() is true + initController(/* viewIsAttached= */ true); + when(mNotificationStackScrollLayout.onKeyguard()).thenReturn(true); + mController.getNotifStackController().setNotifStats( + new NotifStats( + /* numActiveNotifs = */ 1, + /* hasNonClearableAlertingNotifs = */ false, + /* hasClearableAlertingNotifs = */ false, + /* hasNonClearableSilentNotifs = */ false, + /* hasClearableSilentNotifs = */ false) + ); + + // WHEN: call updateImportantForAccessibility + mController.updateImportantForAccessibility(); + + // THEN: mNotificationStackScrollLayout should be important for A11y + verify(mNotificationStackScrollLayout) + .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); + } + + @Test + public void updateImportantForAccessibility_hasChild_notOnKeyGuard_importantForA11y() { + // GIVEN: Controller is attached, active notifications is not empty, + // and mNotificationStackScrollLayout.onKeyguard() is false + initController(/* viewIsAttached= */ true); + when(mNotificationStackScrollLayout.onKeyguard()).thenReturn(false); + mController.getNotifStackController().setNotifStats( + new NotifStats( + /* numActiveNotifs = */ 1, + /* hasNonClearableAlertingNotifs = */ false, + /* hasClearableAlertingNotifs = */ false, + /* hasNonClearableSilentNotifs = */ false, + /* hasClearableSilentNotifs = */ false) + ); + + // WHEN: call updateImportantForAccessibility + mController.updateImportantForAccessibility(); + + // THEN: mNotificationStackScrollLayout should be important for A11y + verify(mNotificationStackScrollLayout) + .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); + } + + @Test + public void updateImportantForAccessibility_noChild_notOnKeyGuard_importantForA11y() { + // GIVEN: Controller is attached, active notifications is empty, + // and mNotificationStackScrollLayout.onKeyguard() is false + initController(/* viewIsAttached= */ true); + when(mNotificationStackScrollLayout.onKeyguard()).thenReturn(false); + mController.getNotifStackController().setNotifStats(NotifStats.getEmpty()); + + // WHEN: call updateImportantForAccessibility + mController.updateImportantForAccessibility(); + + // THEN: mNotificationStackScrollLayout should be important for A11y + verify(mNotificationStackScrollLayout) + .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); + } + private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); }