Commit b4397b71 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Update shelf control buttons visibility for accessibility

Makes shelf control buttons (home, back, overview) show up regardless of
kHideShelfControlsInTabletMode if they're needed for accessibiltiy
reasons - i.e. if one of the accessibility features is enabled:
*   spoken feedback
*   autoclick
*   switch access

BUG=1012814

Change-Id: I83925d201e8551a694a444a8cbc1f69d71892a7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2024034
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735992}
parent c3e08a8e
......@@ -181,6 +181,8 @@ class ASH_EXPORT ShelfConfig : public TabletModeObserver,
private:
friend class ShelfConfigTest;
class ShelfAccessibilityObserver;
// Called whenever something has changed in the shelf configuration. Notifies
// all observers.
void OnShelfConfigUpdated();
......@@ -195,6 +197,9 @@ class ASH_EXPORT ShelfConfig : public TabletModeObserver,
// calculated as if is_in_app() returns false.
int GetShelfSize(bool ignore_in_app_state) const;
// Updates shelf config - called when the accessibility state changes.
void UpdateConfigForAccessibilityState();
// Whether shelf is currently standard or dense.
bool is_dense_;
......@@ -276,6 +281,10 @@ class ASH_EXPORT ShelfConfig : public TabletModeObserver,
// tablet mode.
const int app_icon_end_padding_;
// Object responsible for observing accessibility settings relevant to shelf
// config.
std::unique_ptr<ShelfAccessibilityObserver> accessibility_observer_;
base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(ShelfConfig);
......
......@@ -7,8 +7,10 @@
#include <memory>
#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/app_list/test/app_list_test_helper.h"
#include "ash/app_list/views/app_list_view.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_navigation_widget.h"
#include "ash/shelf/shelf_view.h"
......@@ -26,6 +28,8 @@
namespace ash {
namespace {
class BackButtonTest : public AshTestBase,
public testing::WithParamInterface<bool> {
public:
......@@ -76,6 +80,48 @@ class BackButtonTest : public AshTestBase,
DISALLOW_COPY_AND_ASSIGN(BackButtonTest);
};
enum class TestAccessibilityFeature {
kSpokenFeedback,
kAutoclick,
kSwitchAccess
};
// Tests back button visibility with number of accessibility setting enabled,
// with kHideControlsInTabletModeFeature.
class BackButtonVisibilityWithAccessibilityFeaturesTest
: public AshTestBase,
public ::testing::WithParamInterface<TestAccessibilityFeature> {
public:
BackButtonVisibilityWithAccessibilityFeaturesTest() {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kShelfHotseat,
features::kHideShelfControlsInTabletMode},
{});
}
~BackButtonVisibilityWithAccessibilityFeaturesTest() override = default;
void SetTestA11yFeatureEnabled(bool enabled) {
switch (GetParam()) {
case TestAccessibilityFeature::kSpokenFeedback:
Shell::Get()->accessibility_controller()->SetSpokenFeedbackEnabled(
enabled, A11Y_NOTIFICATION_NONE);
break;
case TestAccessibilityFeature::kAutoclick:
Shell::Get()->accessibility_controller()->SetAutoclickEnabled(enabled);
break;
case TestAccessibilityFeature::kSwitchAccess:
Shell::Get()->accessibility_controller()->SetSwitchAccessEnabled(
enabled);
break;
}
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
} // namespace
// The parameter indicates whether the kShelfHotseat feature is enabled.
INSTANTIATE_TEST_SUITE_P(All, BackButtonTest, testing::Bool());
......@@ -203,4 +249,49 @@ TEST_P(BackButtonTest, NoContextMenuOnBackButton) {
EXPECT_FALSE(test_api_->CloseMenu());
}
INSTANTIATE_TEST_SUITE_P(
All,
BackButtonVisibilityWithAccessibilityFeaturesTest,
::testing::Values(TestAccessibilityFeature::kSpokenFeedback,
TestAccessibilityFeature::kAutoclick,
TestAccessibilityFeature::kSwitchAccess));
TEST_P(BackButtonVisibilityWithAccessibilityFeaturesTest,
TabletModeSwitchWithA11yFeatureEnabled) {
std::unique_ptr<views::Widget> widget = CreateTestWidget();
SetTestA11yFeatureEnabled(true /*enabled*/);
ShelfNavigationWidget::TestApi test_api(
GetPrimaryShelf()->shelf_widget()->navigation_widget());
// Back button is not shown in clamshell.
EXPECT_FALSE(test_api.IsBackButtonVisible());
// Switch to tablet mode, and verify the back button is now visible.
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_TRUE(test_api.IsBackButtonVisible());
// The button should be hidden if the feature gets disabled.
SetTestA11yFeatureEnabled(false /*enabled*/);
EXPECT_FALSE(test_api.IsBackButtonVisible());
}
TEST_P(BackButtonVisibilityWithAccessibilityFeaturesTest,
FeatureEnabledWhileInTabletMode) {
std::unique_ptr<views::Widget> widget = CreateTestWidget();
ShelfNavigationWidget::TestApi test_api(
GetPrimaryShelf()->shelf_widget()->navigation_widget());
// Back button is not shown in clamshell.
EXPECT_FALSE(test_api.IsBackButtonVisible());
// Switch to tablet mode, and verify the back button is still hidden.
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_FALSE(test_api.IsBackButtonVisible());
// The button should be shown if the feature gets enabled.
SetTestA11yFeatureEnabled(true /*enabled*/);
EXPECT_TRUE(test_api.IsBackButtonVisible());
}
} // namespace ash
......@@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/app_list/test/app_list_test_helper.h"
#include "ash/app_list/views/app_list_view.h"
#include "ash/assistant/assistant_controller.h"
......@@ -41,8 +42,6 @@ ui::GestureEvent CreateGestureEvent(ui::GestureEventDetails details) {
return ui::GestureEvent(0, 0, ui::EF_NONE, base::TimeTicks(), details);
}
} // namespace
class HomeButtonTest
: public AshTestBase,
public testing::WithParamInterface<std::tuple<bool, bool>> {
......@@ -117,6 +116,48 @@ class HomeButtonTest
DISALLOW_COPY_AND_ASSIGN(HomeButtonTest);
};
enum class TestAccessibilityFeature {
kSpokenFeedback,
kAutoclick,
kSwitchAccess
};
// Tests home button visibility with number of accessibility setting enabled,
// with kHideControlsInTabletModeFeature.
class HomeButtonVisibilityWithAccessibilityFeaturesTest
: public AshTestBase,
public ::testing::WithParamInterface<TestAccessibilityFeature> {
public:
HomeButtonVisibilityWithAccessibilityFeaturesTest() {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kShelfHotseat,
features::kHideShelfControlsInTabletMode},
{});
}
~HomeButtonVisibilityWithAccessibilityFeaturesTest() override = default;
void SetTestA11yFeatureEnabled(bool enabled) {
switch (GetParam()) {
case TestAccessibilityFeature::kSpokenFeedback:
Shell::Get()->accessibility_controller()->SetSpokenFeedbackEnabled(
enabled, A11Y_NOTIFICATION_NONE);
break;
case TestAccessibilityFeature::kAutoclick:
Shell::Get()->accessibility_controller()->SetAutoclickEnabled(enabled);
break;
case TestAccessibilityFeature::kSwitchAccess:
Shell::Get()->accessibility_controller()->SetSwitchAccessEnabled(
enabled);
break;
}
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
} // namespace
// The parameters indicate whether the kShelfHotseat and
// kHideShelfControlsInTabletMode features are enabled.
INSTANTIATE_TEST_SUITE_P(All,
......@@ -531,4 +572,43 @@ TEST_P(HomeButtonTest, ClickOnCornerPixel) {
GetAppListTestHelper()->CheckVisibility(true);
}
INSTANTIATE_TEST_SUITE_P(
All,
HomeButtonVisibilityWithAccessibilityFeaturesTest,
::testing::Values(TestAccessibilityFeature::kSpokenFeedback,
TestAccessibilityFeature::kAutoclick,
TestAccessibilityFeature::kSwitchAccess));
TEST_P(HomeButtonVisibilityWithAccessibilityFeaturesTest,
TabletModeSwitchWithA11yFeatureEnabled) {
SetTestA11yFeatureEnabled(true /*enabled*/);
ShelfNavigationWidget::TestApi test_api(
GetPrimaryShelf()->shelf_widget()->navigation_widget());
EXPECT_TRUE(test_api.IsHomeButtonVisible());
// Switch to tablet mode, and verify the home button is still visible.
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_TRUE(test_api.IsHomeButtonVisible());
// The button should be hidden if the feature gets disabled.
SetTestA11yFeatureEnabled(false /*enabled*/);
EXPECT_FALSE(test_api.IsHomeButtonVisible());
}
TEST_P(HomeButtonVisibilityWithAccessibilityFeaturesTest,
FeatureEnabledWhileInTabletMode) {
ShelfNavigationWidget::TestApi test_api(
GetPrimaryShelf()->shelf_widget()->navigation_widget());
EXPECT_TRUE(test_api.IsHomeButtonVisible());
// Switch to tablet mode, and verify the home button is hidden.
Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
EXPECT_FALSE(test_api.IsHomeButtonVisible());
// The button should be shown if the feature gets enabled.
SetTestA11yFeatureEnabled(true /*enabled*/);
EXPECT_TRUE(test_api.IsHomeButtonVisible());
}
} // namespace ash
......@@ -4,6 +4,8 @@
#include "ash/public/cpp/shelf_config.h"
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/accessibility/accessibility_observer.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/session/session_controller_impl.h"
......@@ -11,6 +13,7 @@
#include "ash/style/ash_color_provider.h"
#include "ash/wallpaper/wallpaper_controller_impl.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/scoped_observer.h"
#include "chromeos/constants/chromeos_switches.h"
#include "ui/gfx/color_analysis.h"
#include "ui/gfx/color_palette.h"
......@@ -30,8 +33,46 @@ bool IsTabletMode() {
Shell::Get()->tablet_mode_controller()->InTabletMode();
}
// Whether the the shelf control buttons must be shown for accessibility
// reasons.
bool ShelfControlsForcedShownForAccessibility() {
AccessibilityControllerImpl* accessibility_controller =
Shell::Get()->accessibility_controller();
return accessibility_controller->spoken_feedback_enabled() ||
accessibility_controller->autoclick_enabled() ||
accessibility_controller->switch_access_enabled();
}
} // namespace
class ShelfConfig::ShelfAccessibilityObserver : public AccessibilityObserver {
public:
ShelfAccessibilityObserver(
const base::RepeatingClosure& accessibility_state_changed_callback)
: accessibility_state_changed_callback_(
accessibility_state_changed_callback) {
observer_.Add(Shell::Get()->accessibility_controller());
}
ShelfAccessibilityObserver(const ShelfAccessibilityObserver& other) = delete;
ShelfAccessibilityObserver& operator=(
const ShelfAccessibilityObserver& other) = delete;
~ShelfAccessibilityObserver() override = default;
// AccessibilityObserver:
void OnAccessibilityStatusChanged() override {
accessibility_state_changed_callback_.Run();
}
void OnAccessibilityControllerShutdown() override { observer_.RemoveAll(); }
private:
base::RepeatingClosure accessibility_state_changed_callback_;
ScopedObserver<AccessibilityControllerImpl, AccessibilityObserver> observer_{
this};
};
ShelfConfig::ShelfConfig()
: is_dense_(false),
shelf_controls_shown_(true),
......@@ -63,6 +104,9 @@ ShelfConfig::ShelfConfig()
mousewheel_scroll_offset_threshold_(20),
in_app_control_button_height_inset_(4),
app_icon_end_padding_(4) {
accessibility_observer_ = std::make_unique<ShelfAccessibilityObserver>(
base::BindRepeating(&ShelfConfig::UpdateConfigForAccessibilityState,
base::Unretained(this)));
UpdateConfig(is_app_list_visible_);
}
......@@ -228,7 +272,8 @@ void ShelfConfig::UpdateConfig(bool app_list_visible) {
// TODO(http::crbug.com/1008956): Add a user preference that would allow the
// user or a policy to override this behavior.
const bool new_shelf_controls_shown =
!(in_tablet_mode && features::IsHideShelfControlsInTabletModeEnabled());
!(in_tablet_mode && features::IsHideShelfControlsInTabletModeEnabled()) ||
ShelfControlsForcedShownForAccessibility();
if (new_is_dense == is_dense_ &&
shelf_controls_shown_ == new_shelf_controls_shown &&
......@@ -342,6 +387,10 @@ int ShelfConfig::GetAppIconEndPadding() const {
: 0;
}
void ShelfConfig::UpdateConfigForAccessibilityState() {
UpdateConfig(is_app_list_visible_);
}
void ShelfConfig::OnShelfConfigUpdated() {
for (auto& observer : observers_)
observer.OnShelfConfigUpdated();
......
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