Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -4700,6 +4700,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading @@ -4711,6 +4712,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading @@ -4723,6 +4725,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -327,6 +327,7 @@ public class NotificationStackScrollLayoutController { mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(), mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(), mLockscreenUserManager.isAnyProfilePublicMode()); mLockscreenUserManager.isAnyProfilePublicMode()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); updateImportantForAccessibility(); } } }; }; Loading Loading @@ -1205,6 +1206,7 @@ public class NotificationStackScrollLayoutController { if (mView.getVisibility() == View.VISIBLE) { if (mView.getVisibility() == View.VISIBLE) { // Synchronize EmptyShadeView visibility with the parent container. // Synchronize EmptyShadeView visibility with the parent container. updateShowEmptyShadeView(); updateShowEmptyShadeView(); updateImportantForAccessibility(); } } } } Loading @@ -1231,6 +1233,22 @@ public class NotificationStackScrollLayoutController { Trace.endSection(); Trace.endSection(); } } /** * Update the importantForAccessibility of NotificationStackScrollLayout. * <p> * 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 * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD * and false otherwise. * and false otherwise. Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +79 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.content.res.Resources; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner; import android.view.View; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; Loading Loading @@ -430,6 +431,84 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { verify(mNotificationStackScrollLayout).setStatusBarState(KEYGUARD); 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) { private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); return argThat(new LogMatcher(category, type)); } } Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -4700,6 +4700,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading @@ -4711,6 +4712,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading @@ -4723,6 +4725,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { mController.updateShowEmptyShadeView(); mController.updateShowEmptyShadeView(); updateFooter(); updateFooter(); mController.updateImportantForAccessibility(); } } updateSpeedBumpIndex(); updateSpeedBumpIndex(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -327,6 +327,7 @@ public class NotificationStackScrollLayoutController { mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(), mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(), mLockscreenUserManager.isAnyProfilePublicMode()); mLockscreenUserManager.isAnyProfilePublicMode()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); updateImportantForAccessibility(); } } }; }; Loading Loading @@ -1205,6 +1206,7 @@ public class NotificationStackScrollLayoutController { if (mView.getVisibility() == View.VISIBLE) { if (mView.getVisibility() == View.VISIBLE) { // Synchronize EmptyShadeView visibility with the parent container. // Synchronize EmptyShadeView visibility with the parent container. updateShowEmptyShadeView(); updateShowEmptyShadeView(); updateImportantForAccessibility(); } } } } Loading @@ -1231,6 +1233,22 @@ public class NotificationStackScrollLayoutController { Trace.endSection(); Trace.endSection(); } } /** * Update the importantForAccessibility of NotificationStackScrollLayout. * <p> * 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 * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD * and false otherwise. * and false otherwise. Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +79 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.content.res.Resources; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner; import android.view.View; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; Loading Loading @@ -430,6 +431,84 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { verify(mNotificationStackScrollLayout).setStatusBarState(KEYGUARD); 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) { private LogMaker logMatcher(int category, int type) { return argThat(new LogMatcher(category, type)); return argThat(new LogMatcher(category, type)); } } Loading