Commit 2600935c authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Avoid superfluous screen reader announcement in device chooser

The USB/Bluetooth device chooser was announcing "No devices available"
even though devices were available. The message also sometimes briefly flashed.

To fix this, wait until data is initialized or initial focus occurs before
showing the message.

This is one part of ongoing work to improve accessibility of this dialog.

Bug: 820351
Change-Id: Ia295b7514725512cf0de539d238402a51e220055
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1970260Reviewed-by: default avatarVincent Scheib <scheib@chromium.org>
Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarOvidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728560}
parent a781dde1
...@@ -217,11 +217,13 @@ gfx::ImageSkia DeviceChooserContentView::GetIcon(int row) { ...@@ -217,11 +217,13 @@ gfx::ImageSkia DeviceChooserContentView::GetIcon(int row) {
} }
void DeviceChooserContentView::OnOptionsInitialized() { void DeviceChooserContentView::OnOptionsInitialized() {
is_initialized_ = true;
table_view_->OnModelChanged(); table_view_->OnModelChanged();
UpdateTableView(); UpdateTableView();
} }
void DeviceChooserContentView::OnOptionAdded(size_t index) { void DeviceChooserContentView::OnOptionAdded(size_t index) {
is_initialized_ = true;
table_view_->OnItemsAdded(base::checked_cast<int>(index), 1); table_view_->OnItemsAdded(base::checked_cast<int>(index), 1);
UpdateTableView(); UpdateTableView();
} }
...@@ -353,10 +355,17 @@ void DeviceChooserContentView::Close() { ...@@ -353,10 +355,17 @@ void DeviceChooserContentView::Close() {
void DeviceChooserContentView::UpdateTableView() { void DeviceChooserContentView::UpdateTableView() {
bool has_options = adapter_enabled_ && RowCount() > 0; bool has_options = adapter_enabled_ && RowCount() > 0;
if (!is_initialized_ && GetWidget() &&
GetWidget()->GetFocusManager()->GetFocusedView()) {
is_initialized_ = true; // Can show no_options_view_ after initial focus.
}
table_parent_->SetVisible(has_options); table_parent_->SetVisible(has_options);
table_view_->SetEnabled(has_options && table_view_->SetEnabled(has_options &&
!chooser_controller_->TableViewAlwaysDisabled()); !chooser_controller_->TableViewAlwaysDisabled());
no_options_view_->SetVisible(!has_options && adapter_enabled_); // Do not set to visible until initialization is complete, in order to prevent
// message from briefly flashing and being read by screen reader.
no_options_view_->SetVisible(!has_options && adapter_enabled_ &&
is_initialized_);
adapter_off_view_->SetVisible(!adapter_enabled_); adapter_off_view_->SetVisible(!adapter_enabled_);
} }
......
...@@ -90,6 +90,8 @@ class DeviceChooserContentView : public views::View, ...@@ -90,6 +90,8 @@ class DeviceChooserContentView : public views::View,
views::View* adapter_off_view_ = nullptr; views::View* adapter_off_view_ = nullptr;
BluetoothStatusContainer* bluetooth_status_container_ = nullptr; BluetoothStatusContainer* bluetooth_status_container_ = nullptr;
bool is_initialized_ = false;
DISALLOW_COPY_AND_ASSIGN(DeviceChooserContentView); DISALLOW_COPY_AND_ASSIGN(DeviceChooserContentView);
}; };
......
...@@ -104,13 +104,21 @@ class DeviceChooserContentViewTest : public ChromeViewsTestBase { ...@@ -104,13 +104,21 @@ class DeviceChooserContentViewTest : public ChromeViewsTestBase {
bool IsDeviceSelected() { return !table_view()->selection_model().empty(); } bool IsDeviceSelected() { return !table_view()->selection_model().empty(); }
void ExpectNoDevices() { void ExpectNoDevices() {
EXPECT_TRUE(no_options_view()->GetVisible());
EXPECT_EQ(0, table_view()->GetRowCount()); EXPECT_EQ(0, table_view()->GetRowCount());
// The table should be disabled since there are no (real) options. // The table should be disabled since there are no (real) options.
EXPECT_FALSE(table_parent()->GetVisible()); EXPECT_FALSE(table_parent()->GetVisible());
EXPECT_FALSE(table_view()->GetEnabled()); EXPECT_FALSE(table_view()->GetEnabled());
EXPECT_FALSE(IsDeviceSelected()); EXPECT_FALSE(IsDeviceSelected());
} }
void ExpectNoDevicesWithMessageVisible() {
EXPECT_TRUE(no_options_view()->GetVisible());
ExpectNoDevices();
}
void ExpectNoDevicesWithMessageHidden() {
EXPECT_FALSE(no_options_view()->GetVisible());
ExpectNoDevices();
}
protected: protected:
std::unique_ptr<views::View> extra_views_container_; std::unique_ptr<views::View> extra_views_container_;
...@@ -125,8 +133,7 @@ class DeviceChooserContentViewTest : public ChromeViewsTestBase { ...@@ -125,8 +133,7 @@ class DeviceChooserContentViewTest : public ChromeViewsTestBase {
TEST_F(DeviceChooserContentViewTest, InitialState) { TEST_F(DeviceChooserContentViewTest, InitialState) {
EXPECT_CALL(table_observer(), OnSelectionChanged()).Times(0); EXPECT_CALL(table_observer(), OnSelectionChanged()).Times(0);
ExpectNoDevicesWithMessageHidden();
ExpectNoDevices();
EXPECT_FALSE(adapter_off_view()->GetVisible()); EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_FALSE(throbber()->GetVisible()); EXPECT_FALSE(throbber()->GetVisible());
EXPECT_FALSE(scanning_label()->GetVisible()); EXPECT_FALSE(scanning_label()->GetVisible());
...@@ -170,7 +177,7 @@ TEST_F(DeviceChooserContentViewTest, RemoveOption) { ...@@ -170,7 +177,7 @@ TEST_F(DeviceChooserContentViewTest, RemoveOption) {
controller()->RemoveDevice(1); controller()->RemoveDevice(1);
controller()->RemoveDevice(0); controller()->RemoveDevice(0);
// Should be back to the initial state. // Should be back to the initial state.
ExpectNoDevices(); ExpectNoDevicesWithMessageVisible();
} }
TEST_F(DeviceChooserContentViewTest, UpdateOption) { TEST_F(DeviceChooserContentViewTest, UpdateOption) {
...@@ -219,7 +226,7 @@ TEST_F(DeviceChooserContentViewTest, TurnBluetoothOffAndOn) { ...@@ -219,7 +226,7 @@ TEST_F(DeviceChooserContentViewTest, TurnBluetoothOffAndOn) {
controller()->RemoveDevice(0); controller()->RemoveDevice(0);
controller()->SetBluetoothStatus( controller()->SetBluetoothStatus(
FakeBluetoothChooserController::BluetoothStatus::IDLE); FakeBluetoothChooserController::BluetoothStatus::IDLE);
ExpectNoDevices(); ExpectNoDevicesWithMessageVisible();
EXPECT_FALSE(adapter_off_view()->GetVisible()); EXPECT_FALSE(adapter_off_view()->GetVisible());
EXPECT_FALSE(throbber()->GetVisible()); EXPECT_FALSE(throbber()->GetVisible());
EXPECT_FALSE(scanning_label()->GetVisible()); EXPECT_FALSE(scanning_label()->GetVisible());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment