#include "ash/accessibility/accessibility_controller.h"
#include <array>
#include <string>
#include <utility>
#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/accessibility/a11y_feature_type.h"
#include "ash/accessibility/accessibility_observer.h"
#include "ash/accessibility/disable_touchpad_event_rewriter.h"
#include "ash/accessibility/filter_keys_event_rewriter.h"
#include "ash/accessibility/flash_screen_controller.h"
#include "ash/accessibility/magnifier/docked_magnifier_controller.h"
#include "ash/accessibility/mouse_keys/mouse_keys_controller.h"
#include "ash/accessibility/sticky_keys/sticky_keys_controller.h"
#include "ash/accessibility/test_accessibility_controller_client.h"
#include "ash/accessibility/ui/accessibility_confirmation_dialog.h"
#include "ash/constants/ash_constants.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/display/cursor_window_controller.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/keyboard/ui/keyboard_util.h"
#include "ash/public/cpp/event_rewriter_controller.h"
#include "ash/public/cpp/test/test_system_tray_client.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/session/test_pref_service_provider.h"
#include "ash/shell.h"
#include "ash/system/toast/anchored_nudge_manager_impl.h"
#include "ash/system/toast/toast_manager_impl.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/system/unified/unified_system_tray_bubble.h"
#include "ash/test/ash_test_base.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "components/live_caption/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/aura/aura_window_properties.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/devices/device_data_manager_test_api.h"
#include "ui/events/devices/touchpad_device.h"
#include "ui/gfx/animation/animation_test_api.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/native_theme/features/native_theme_features.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/os_settings_provider.h"
using message_center::MessageCenter;
namespace ash {
namespace {
constexpr char kDictationLanguageUpgradedNudgeId[] =
"dictation_language_upgraded.nudge_id";
const std::string kAccessibilityToast = "AccessibilityToast";
const int kDialogTimeoutSeconds = 30;
const int kInternalTouchpadDeviceId = 30;
const int kUsbMouseDeviceId = 20;
ui::InputDevice GetSampleMouseUsb() {
return {kUsbMouseDeviceId, ui::INPUT_DEVICE_USB, "SampleMouseUsb"};
}
ui::TouchpadDevice GetSampleTouchpadInternal() {
return {kInternalTouchpadDeviceId, ui::INPUT_DEVICE_INTERNAL, "touchpad"};
}
void SimulateOnlyInternalTouchpadConnected() {
ui::DeviceDataManagerTestApi().SetTouchpadDevices(
{GetSampleTouchpadInternal()});
}
void SimulateExternalMouseConnected() {
ui::DeviceDataManagerTestApi().SetMouseDevices({GetSampleMouseUsb()});
SimulateOnlyInternalTouchpadConnected();
}
}
class TestAccessibilityObserver : public AccessibilityObserver {
public:
TestAccessibilityObserver() = default;
TestAccessibilityObserver(const TestAccessibilityObserver&) = delete;
TestAccessibilityObserver& operator=(const TestAccessibilityObserver&) =
delete;
~TestAccessibilityObserver() override = default;
void OnAccessibilityStatusChanged() override { ++status_changed_count_; }
int status_changed_count_ = 0;
};
class AccessibilityControllerTestBase : public AshTestBase {
protected:
AccessibilityControllerTestBase() = default;
AccessibilityControllerTestBase(const AccessibilityControllerTestBase&) =
delete;
AccessibilityControllerTestBase& operator=(
const AccessibilityControllerTestBase&) = delete;
~AccessibilityControllerTestBase() override = default;
AccessibilityController* controller() {
return Shell::Get()->accessibility_controller();
}
SessionControllerImpl* session() {
return Shell::Get()->session_controller();
}
PrefService* prefs() { return session()->GetLastActiveUserPrefService(); }
base::test::ScopedFeatureList scoped_feature_list_;
};
class AccessibilityControllerTest : public AccessibilityControllerTestBase {
protected:
AccessibilityControllerTest() = default;
AccessibilityControllerTest(const AccessibilityControllerTest&) = delete;
AccessibilityControllerTest& operator=(const AccessibilityControllerTest&) =
delete;
~AccessibilityControllerTest() override = default;
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
{ash::features::kOnDeviceSpeechRecognition,
::features::kAccessibilityAccelerator,
::features::kAccessibilityMouseKeys,
::features::kAccessibilityFlashScreenFeature},
{});
AccessibilityControllerTestBase::SetUp();
}
void ExpectSessionDurationMetricCount(const std::string& feature_name,
int count) {
histogram_tester_.ExpectTotalCount(
"Accessibility." + feature_name + ".SessionDuration", count);
}
void ShowNotification(const message_center::RichNotificationData& data) {
const std::string notification_id("id");
const std::string notification_title("title");
message_center::MessageCenter::Get()->AddNotification(
std::make_unique<message_center::Notification>(
message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
base::UTF8ToUTF16(notification_title), u"test message",
ui::ImageModel(), std::u16string() , GURL(),
message_center::NotifierId(), data,
new message_center::NotificationDelegate()));
}
void ExpectFlashNotificationShown() {
gfx::AnimationTestApi animation_api(
AccessibilityController::Get()
->GetFlashScreenControllerForTesting()
->GetAnimationForTesting());
base::TimeTicks now = base::TimeTicks::Now();
animation_api.SetStartTime(now);
animation_api.Step(now + base::Milliseconds(1));
for (aura::Window* root_window : Shell::GetAllRootWindows()) {
const cc::FilterOperation::Matrix* matrix =
root_window->layer()->GetLayerCustomColorMatrix();
EXPECT_TRUE(matrix);
}
}
void ExpectFlashNotificationNotShown() {
for (aura::Window* root_window : Shell::GetAllRootWindows()) {
const cc::FilterOperation::Matrix* matrix =
root_window->layer()->GetLayerCustomColorMatrix();
EXPECT_FALSE(matrix);
}
}
private:
base::HistogramTester histogram_tester_;
};
TEST_F(AccessibilityControllerTest, ChangingCursorSizePrefChangesCursorSize) {
prefs()->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
CursorWindowController* cursor_window_controller =
Shell::Get()->window_tree_host_manager()->cursor_window_controller();
for (int size = 25; size <= 128; ++size) {
prefs()->SetInteger(prefs::kAccessibilityLargeCursorDipSize, size);
auto bounds = cursor_window_controller->GetCursorBoundsInScreenForTest();
EXPECT_EQ(bounds.height(), size);
EXPECT_EQ(bounds.width(), size);
}
}
TEST_F(AccessibilityControllerTest, PrefsAreRegistered) {
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityAutoclickEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityAutoclickDelayMs));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityCaretHighlightEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityCursorHighlightEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityCursorColorEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityDictationEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityDictationLocale));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFocusHighlightEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityHighContrastEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityLargeCursorDipSize));
EXPECT_TRUE(prefs()->FindPreference(::prefs::kLiveCaptionEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityMonoAudioEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityMouseKeysEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityMouseKeysAcceleration));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityMouseKeysMaxSpeed));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityMouseKeysUsePrimaryKeys));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityMouseKeysDominantHand));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityAutoclickDelayMs));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityScreenMagnifierEnabled));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityScreenMagnifierFocusFollowingEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityScreenMagnifierScale));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilitySpokenFeedbackEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityChromeVoxAutoRead));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxAnnounceDownloadNotifications));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxAnnounceRichTextAttributes));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxAudioStrategy));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleSideBySide));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleTable));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleTable6));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleTable8));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleTableType));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxBrailleWordWrap));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxCapitalStrategy));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxCapitalStrategyBackup));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxEnableBrailleLogging));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxEnableEarconLogging));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxEnableEventStreamLogging));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxEnableSpeechLogging));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxEventStreamFilters));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxLanguageSwitching));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxMenuBrailleCommands));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxNumberReadingStyle));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxPreferredBrailleDisplayAddress));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxPunctuationEcho));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxSmartStickyMode));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxSpeakTextUnderMouse));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxUsePitchChanges));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityChromeVoxUseVerboseMode));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxVirtualBrailleColumns));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityChromeVoxVirtualBrailleRows));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityChromeVoxVoiceName));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityStickyKeysEnabled));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityShortcutsEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityVirtualKeyboardEnabled));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityEnhancedNetworkVoicesInSelectToSpeakAllowed));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityColorCorrectionEnabled));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityColorCorrectionHasBeenSetup));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityColorVisionCorrectionType));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityColorVisionCorrectionAmount));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeCursorSpeedUp));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeCursorSpeedDown));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeCursorSpeedLeft));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeCursorSpeedRight));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeCursorUseAcceleration));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeGesturesToKeyCombos));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeGesturesToMacros));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeGesturesToConfidence));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeCursorControlEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeActionsEnabled));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeAdjustSpeedSeparately));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeVelocityThreshold));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazePrecisionClick));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazePrecisionClickSpeedFactor));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFaceGazeEnabledSentinel));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeEnabledSentinelShowDialog));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeCursorControlEnabledSentinel));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityFaceGazeActionsEnabledSentinel));
EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityCaretBlinkInterval));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFlashNotificationsEnabled));
EXPECT_TRUE(
prefs()->FindPreference(prefs::kAccessibilityFlashNotificationsColor));
EXPECT_TRUE(prefs()->FindPreference(
prefs::kAccessibilityAlwaysShowScrollbarsEnabled));
}
TEST_F(AccessibilityControllerTest, SetAlwaysShowScrollbarEnabled) {
EXPECT_FALSE(controller()->always_show_scrollbar().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->always_show_scrollbar().SetEnabled(true);
EXPECT_TRUE(controller()->always_show_scrollbar().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosAlwaysShowScrollbar", 0);
EXPECT_FALSE(ui::NativeTheme::GetInstanceForWeb()->use_overlay_scrollbar());
controller()->always_show_scrollbar().SetEnabled(false);
EXPECT_FALSE(controller()->always_show_scrollbar().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosAlwaysShowScrollbar", 1);
EXPECT_TRUE(ui::NativeTheme::GetInstanceForWeb()->use_overlay_scrollbar());
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetAutoclickEnabled) {
EXPECT_FALSE(controller()->autoclick().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->autoclick().SetEnabled(true);
EXPECT_TRUE(controller()->autoclick().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosAutoclick", 0);
controller()->autoclick().SetEnabled(false);
EXPECT_FALSE(controller()->autoclick().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosAutoclick", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetBounceKeysEnabled) {
EXPECT_FALSE(controller()->bounce_keys().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->bounce_keys().SetEnabled(true);
EXPECT_TRUE(controller()->bounce_keys().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosBounceKeys", 0);
controller()->bounce_keys().SetEnabled(false);
EXPECT_FALSE(controller()->bounce_keys().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosBounceKeys", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetCaretHighlightEnabled) {
EXPECT_FALSE(controller()->caret_highlight().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->caret_highlight().SetEnabled(true);
EXPECT_TRUE(controller()->caret_highlight().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCaretHighlight", 0);
controller()->caret_highlight().SetEnabled(false);
EXPECT_FALSE(controller()->caret_highlight().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCaretHighlight", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetColorCorrectionEnabled) {
EXPECT_FALSE(controller()->color_correction().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
EXPECT_EQ(0, GetSystemTrayClient()->show_color_correction_settings_count());
controller()->color_correction().SetEnabled(true);
EXPECT_TRUE(controller()->color_correction().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosColorCorrection", 0);
EXPECT_EQ(1, GetSystemTrayClient()->show_color_correction_settings_count());
controller()->color_correction().SetEnabled(false);
EXPECT_FALSE(controller()->color_correction().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosColorCorrection", 1);
controller()->color_correction().SetEnabled(true);
EXPECT_TRUE(controller()->color_correction().enabled());
EXPECT_EQ(3, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosColorCorrection", 1);
EXPECT_EQ(1, GetSystemTrayClient()->show_color_correction_settings_count());
controller()->color_correction().SetEnabled(false);
EXPECT_FALSE(controller()->color_correction().enabled());
EXPECT_EQ(4, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosColorCorrection", 2);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetCursorHighlightEnabled) {
EXPECT_FALSE(controller()->cursor_highlight().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->cursor_highlight().SetEnabled(true);
EXPECT_TRUE(controller()->cursor_highlight().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCursorHighlight", 0);
controller()->cursor_highlight().SetEnabled(false);
EXPECT_FALSE(controller()->cursor_highlight().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCursorHighlight", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetCursorColorEnabled) {
EXPECT_FALSE(controller()->cursor_color().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->cursor_color().SetEnabled(true);
EXPECT_TRUE(controller()->cursor_color().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCursorColor", 0);
controller()->cursor_color().SetEnabled(false);
EXPECT_FALSE(controller()->cursor_color().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosCursorColor", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetFaceGazeEnabled) {
EXPECT_FALSE(controller()->face_gaze().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->face_gaze().SetEnabled(true);
EXPECT_TRUE(controller()->face_gaze().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosFaceGaze", 0);
controller()->face_gaze().SetEnabled(false);
EXPECT_FALSE(controller()->face_gaze().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosFaceGaze", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, FaceGazeTrayMenuVisibility) {
controller()->face_gaze().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_TRUE(prefs()->GetBoolean(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_TRUE(controller()->face_gaze().enabled());
EXPECT_TRUE(controller()->IsFaceGazeSettingVisibleInTray());
controller()->face_gaze().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_FALSE(controller()->face_gaze().enabled());
EXPECT_TRUE(controller()->IsFaceGazeSettingVisibleInTray());
EXPECT_FALSE(prefs()->GetBoolean(prefs::kAccessibilityFaceGazeEnabled));
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityFaceGazeEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_TRUE(controller()->IsFaceGazeSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityFaceGazeEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityFaceGazeEnabled));
EXPECT_FALSE(controller()->face_gaze().enabled());
EXPECT_FALSE(controller()->IsFaceGazeSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SetFocusHighlightEnabled) {
EXPECT_FALSE(controller()->focus_highlight().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->focus_highlight().SetEnabled(true);
EXPECT_TRUE(controller()->focus_highlight().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosFocusHighlight", 0);
controller()->focus_highlight().SetEnabled(false);
EXPECT_FALSE(controller()->focus_highlight().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosFocusHighlight", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetHighContrastEnabled) {
EXPECT_FALSE(controller()->high_contrast().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->high_contrast().SetEnabled(true);
EXPECT_TRUE(controller()->high_contrast().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosHighContrast", 0);
controller()->high_contrast().SetEnabled(false);
EXPECT_FALSE(controller()->high_contrast().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosHighContrast", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetLargeCursorEnabled) {
EXPECT_FALSE(controller()->large_cursor().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->large_cursor().SetEnabled(true);
EXPECT_TRUE(controller()->large_cursor().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosLargeCursor", 0);
controller()->large_cursor().SetEnabled(false);
EXPECT_FALSE(controller()->large_cursor().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosLargeCursor", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, LargeCursorTrayMenuVisibility) {
controller()->large_cursor().SetEnabled(true);
EXPECT_TRUE(controller()->large_cursor().enabled());
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(controller()->IsLargeCursorSettingVisibleInTray());
controller()->large_cursor().SetEnabled(false);
EXPECT_FALSE(controller()->large_cursor().enabled());
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(controller()->IsLargeCursorSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityLargeCursorEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(controller()->large_cursor().enabled());
EXPECT_TRUE(controller()->IsLargeCursorSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityLargeCursorEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
EXPECT_FALSE(controller()->large_cursor().enabled());
EXPECT_FALSE(controller()->IsLargeCursorSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SetLiveCaptionEnabled) {
EXPECT_FALSE(controller()->live_caption().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->live_caption().SetEnabled(true);
EXPECT_TRUE(controller()->live_caption().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosLiveCaption", 0);
controller()->live_caption().SetEnabled(false);
EXPECT_FALSE(controller()->live_caption().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosLiveCaption", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, LiveCaptionTrayMenuVisibility) {
controller()->live_caption().SetEnabled(true);
EXPECT_TRUE(controller()->live_caption().enabled());
EXPECT_FALSE(prefs()->IsManagedPreference(::prefs::kLiveCaptionEnabled));
EXPECT_TRUE(controller()->IsLiveCaptionSettingVisibleInTray());
controller()->live_caption().SetEnabled(false);
EXPECT_FALSE(controller()->live_caption().enabled());
EXPECT_FALSE(prefs()->IsManagedPreference(::prefs::kLiveCaptionEnabled));
EXPECT_TRUE(controller()->IsLiveCaptionSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
::prefs::kLiveCaptionEnabled, std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(::prefs::kLiveCaptionEnabled));
EXPECT_TRUE(controller()->live_caption().enabled());
EXPECT_TRUE(controller()->IsLiveCaptionSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
::prefs::kLiveCaptionEnabled, std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(::prefs::kLiveCaptionEnabled));
EXPECT_FALSE(controller()->live_caption().enabled());
EXPECT_FALSE(controller()->IsLiveCaptionSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, HighContrastTrayMenuVisibility) {
controller()->high_contrast().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityHighContrastEnabled));
EXPECT_TRUE(controller()->high_contrast().enabled());
EXPECT_TRUE(controller()->IsHighContrastSettingVisibleInTray());
controller()->high_contrast().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityHighContrastEnabled));
EXPECT_FALSE(controller()->high_contrast().enabled());
EXPECT_TRUE(controller()->IsHighContrastSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityHighContrastEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityHighContrastEnabled));
EXPECT_TRUE(controller()->IsHighContrastSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityHighContrastEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityHighContrastEnabled));
EXPECT_FALSE(controller()->high_contrast().enabled());
EXPECT_FALSE(controller()->IsHighContrastSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, MonoAudioTrayMenuVisibility) {
controller()->mono_audio().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityMonoAudioEnabled));
EXPECT_TRUE(controller()->mono_audio().enabled());
EXPECT_TRUE(controller()->IsMonoAudioSettingVisibleInTray());
controller()->mono_audio().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityMonoAudioEnabled));
EXPECT_FALSE(controller()->mono_audio().enabled());
EXPECT_TRUE(controller()->IsMonoAudioSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityMonoAudioEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityMonoAudioEnabled));
EXPECT_TRUE(controller()->IsMonoAudioSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityMonoAudioEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityMonoAudioEnabled));
EXPECT_FALSE(controller()->mono_audio().enabled());
EXPECT_FALSE(controller()->IsMonoAudioSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SetMouseKeysEnabled) {
auto& mouse_keys = controller()->mouse_keys();
EXPECT_FALSE(mouse_keys.enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
MouseKeysController* mouse_keys_controller =
Shell::Get()->mouse_keys_controller();
mouse_keys.SetEnabled(true);
EXPECT_TRUE(mouse_keys.enabled());
EXPECT_FALSE(mouse_keys_controller->paused());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosMouseKeys", 0);
mouse_keys.SetEnabled(false);
EXPECT_FALSE(mouse_keys.enabled());
EXPECT_FALSE(mouse_keys_controller->paused());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosMouseKeys", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, DictationTrayMenuVisibility) {
prefs()->SetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted, true);
controller()->dictation().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityDictationEnabled));
EXPECT_TRUE(controller()->dictation().enabled());
EXPECT_TRUE(controller()->IsDictationSettingVisibleInTray());
controller()->dictation().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityDictationEnabled));
EXPECT_FALSE(controller()->dictation().enabled());
EXPECT_TRUE(controller()->IsDictationSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityDictationEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityDictationEnabled));
EXPECT_TRUE(controller()->IsDictationSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityDictationEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityDictationEnabled));
EXPECT_FALSE(controller()->dictation().enabled());
EXPECT_FALSE(controller()->IsDictationSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, DictationLanguageUpgradedNudge) {
struct {
std::string locale;
std::string application_locale;
std::string label;
} kTestCases[] = {
{"en-US", "en-US", "English"},
{"es-ES", "en-US", "Spanish"},
{"en-US", "es-ES", "inglés"},
{"es-ES", "es-ES", "español"},
};
auto* nudge_manager = Shell::Get()->anchored_nudge_manager();
for (const auto& testcase : kTestCases) {
controller()->ShowDictationLanguageUpgradedNudge(
testcase.locale, testcase.application_locale);
ASSERT_TRUE(nudge_manager->IsNudgeShown(kDictationLanguageUpgradedNudgeId));
const std::string body_text =
base::UTF16ToUTF8(nudge_manager->GetNudgeBodyTextForTest(
kDictationLanguageUpgradedNudgeId));
EXPECT_THAT(body_text, testing::HasSubstr(testcase.label));
}
}
TEST_F(AccessibilityControllerTest, CursorHighlightTrayMenuVisibility) {
controller()->cursor_highlight().SetEnabled(true);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityCursorHighlightEnabled));
EXPECT_TRUE(controller()->cursor_highlight().enabled());
EXPECT_TRUE(controller()->IsCursorHighlightSettingVisibleInTray());
controller()->cursor_highlight().SetEnabled(false);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityCursorHighlightEnabled));
EXPECT_FALSE(controller()->cursor_highlight().enabled());
EXPECT_TRUE(controller()->IsCursorHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityCursorHighlightEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityCursorHighlightEnabled));
EXPECT_TRUE(controller()->IsCursorHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityCursorHighlightEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityCursorHighlightEnabled));
EXPECT_FALSE(controller()->cursor_highlight().enabled());
EXPECT_FALSE(controller()->IsCursorHighlightSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, FullScreenMagnifierTrayMenuVisibility) {
controller()->fullscreen_magnifier().SetEnabled(true);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityScreenMagnifierEnabled));
EXPECT_TRUE(controller()->fullscreen_magnifier().enabled());
EXPECT_TRUE(controller()->IsFullScreenMagnifierSettingVisibleInTray());
controller()->fullscreen_magnifier().SetEnabled(false);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityScreenMagnifierEnabled));
EXPECT_FALSE(controller()->fullscreen_magnifier().enabled());
EXPECT_TRUE(controller()->IsFullScreenMagnifierSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityScreenMagnifierEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityScreenMagnifierEnabled));
EXPECT_TRUE(controller()->IsFullScreenMagnifierSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityScreenMagnifierEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityScreenMagnifierEnabled));
EXPECT_FALSE(controller()->fullscreen_magnifier().enabled());
EXPECT_FALSE(controller()->IsFullScreenMagnifierSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, DockedMagnifierTrayMenuVisibility) {
controller()->docked_magnifier().SetEnabled(true);
EXPECT_FALSE(prefs()->IsManagedPreference(prefs::kDockedMagnifierEnabled));
EXPECT_TRUE(controller()->docked_magnifier().enabled());
EXPECT_TRUE(controller()->IsDockedMagnifierSettingVisibleInTray());
controller()->docked_magnifier().SetEnabled(false);
EXPECT_FALSE(prefs()->IsManagedPreference(prefs::kDockedMagnifierEnabled));
EXPECT_FALSE(controller()->docked_magnifier().enabled());
EXPECT_TRUE(controller()->IsDockedMagnifierSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kDockedMagnifierEnabled, std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(prefs::kDockedMagnifierEnabled));
EXPECT_TRUE(controller()->IsDockedMagnifierSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kDockedMagnifierEnabled, std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(prefs::kDockedMagnifierEnabled));
EXPECT_FALSE(controller()->docked_magnifier().enabled());
EXPECT_FALSE(controller()->IsDockedMagnifierSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, CaretHighlightTrayMenuVisibility) {
controller()->caret_highlight().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityCaretHighlightEnabled));
EXPECT_TRUE(controller()->caret_highlight().enabled());
EXPECT_TRUE(controller()->IsCaretHighlightSettingVisibleInTray());
controller()->caret_highlight().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityCaretHighlightEnabled));
EXPECT_FALSE(controller()->caret_highlight().enabled());
EXPECT_TRUE(controller()->IsCaretHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityCaretHighlightEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityCaretHighlightEnabled));
EXPECT_TRUE(controller()->IsCaretHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityCaretHighlightEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityCaretHighlightEnabled));
EXPECT_FALSE(controller()->caret_highlight().enabled());
EXPECT_FALSE(controller()->IsCaretHighlightSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SelectToSpeakTrayMenuVisibility) {
controller()->select_to_speak().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySelectToSpeakEnabled));
EXPECT_TRUE(controller()->select_to_speak().enabled());
EXPECT_TRUE(controller()->IsSelectToSpeakSettingVisibleInTray());
controller()->select_to_speak().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySelectToSpeakEnabled));
EXPECT_FALSE(controller()->select_to_speak().enabled());
EXPECT_TRUE(controller()->IsSelectToSpeakSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySelectToSpeakEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySelectToSpeakEnabled));
EXPECT_TRUE(controller()->IsSelectToSpeakSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySelectToSpeakEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySelectToSpeakEnabled));
EXPECT_FALSE(controller()->select_to_speak().enabled());
EXPECT_FALSE(controller()->IsSelectToSpeakSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, AutoClickTrayMenuVisibility) {
controller()->autoclick().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityAutoclickEnabled));
EXPECT_TRUE(controller()->autoclick().enabled());
EXPECT_TRUE(controller()->IsAutoclickSettingVisibleInTray());
controller()->autoclick().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityAutoclickEnabled));
EXPECT_FALSE(controller()->autoclick().enabled());
EXPECT_TRUE(controller()->IsAutoclickSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityAutoclickEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityAutoclickEnabled));
EXPECT_TRUE(controller()->IsAutoclickSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityAutoclickEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityAutoclickEnabled));
EXPECT_FALSE(controller()->autoclick().enabled());
EXPECT_FALSE(controller()->IsAutoclickSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SpokenFeedbackTrayMenuVisibility) {
controller()->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySpokenFeedbackEnabled));
EXPECT_TRUE(controller()->spoken_feedback().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
controller()->SetSpokenFeedbackEnabled(false, A11Y_NOTIFICATION_NONE);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySpokenFeedbackEnabled));
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySpokenFeedbackEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySpokenFeedbackEnabled));
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySpokenFeedbackEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySpokenFeedbackEnabled));
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_FALSE(controller()->IsSpokenFeedbackSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, VirtualKeyboardTrayMenuVisibility) {
controller()->virtual_keyboard().SetEnabled(true);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityVirtualKeyboardEnabled));
EXPECT_TRUE(controller()->virtual_keyboard().enabled());
EXPECT_TRUE(controller()->IsVirtualKeyboardSettingVisibleInTray());
controller()->virtual_keyboard().SetEnabled(false);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityVirtualKeyboardEnabled));
EXPECT_FALSE(controller()->virtual_keyboard().enabled());
EXPECT_TRUE(controller()->IsVirtualKeyboardSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityVirtualKeyboardEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityVirtualKeyboardEnabled));
EXPECT_TRUE(controller()->IsVirtualKeyboardSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityVirtualKeyboardEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityVirtualKeyboardEnabled));
EXPECT_FALSE(controller()->virtual_keyboard().enabled());
EXPECT_FALSE(controller()->IsVirtualKeyboardSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SwitchAccessTrayMenuVisibility) {
controller()->switch_access().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySwitchAccessEnabled));
EXPECT_TRUE(controller()->switch_access().enabled());
EXPECT_TRUE(controller()->IsSwitchAccessSettingVisibleInTray());
controller()->switch_access().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilitySwitchAccessEnabled));
EXPECT_FALSE(controller()->switch_access().enabled());
EXPECT_TRUE(controller()->IsSwitchAccessSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySwitchAccessEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySwitchAccessEnabled));
EXPECT_TRUE(controller()->IsSwitchAccessSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySwitchAccessEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilitySwitchAccessEnabled));
EXPECT_FALSE(controller()->switch_access().enabled());
EXPECT_FALSE(controller()->IsSwitchAccessSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, ColorCorrectionTrayMenuVisibility) {
controller()->color_correction().SetEnabled(true);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityColorCorrectionEnabled));
EXPECT_TRUE(controller()->color_correction().enabled());
EXPECT_TRUE(controller()->IsColorCorrectionSettingVisibleInTray());
controller()->color_correction().SetEnabled(false);
EXPECT_FALSE(prefs()->IsManagedPreference(
prefs::kAccessibilityColorCorrectionEnabled));
EXPECT_FALSE(controller()->color_correction().enabled());
EXPECT_TRUE(controller()->IsColorCorrectionSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityColorCorrectionEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityColorCorrectionEnabled));
EXPECT_TRUE(controller()->IsColorCorrectionSettingVisibleInTray());
EXPECT_TRUE(controller()->color_correction().enabled());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityColorCorrectionEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(prefs()->IsManagedPreference(
prefs::kAccessibilityColorCorrectionEnabled));
EXPECT_FALSE(controller()->color_correction().enabled());
EXPECT_FALSE(controller()->IsColorCorrectionSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, FocusHighlightTrayMenuVisibility) {
controller()->focus_highlight().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityFocusHighlightEnabled));
EXPECT_TRUE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
controller()->focus_highlight().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityFocusHighlightEnabled));
EXPECT_FALSE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityFocusHighlightEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityFocusHighlightEnabled));
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityFocusHighlightEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityFocusHighlightEnabled));
EXPECT_FALSE(controller()->focus_highlight().enabled());
EXPECT_FALSE(controller()->IsFocusHighlightSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, StickyKeysTrayMenuVisibility) {
controller()->sticky_keys().SetEnabled(true);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityStickyKeysEnabled));
EXPECT_TRUE(controller()->sticky_keys().enabled());
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
controller()->sticky_keys().SetEnabled(false);
EXPECT_FALSE(
prefs()->IsManagedPreference(prefs::kAccessibilityStickyKeysEnabled));
EXPECT_FALSE(controller()->sticky_keys().enabled());
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityStickyKeysEnabled,
std::make_unique<base::Value>(true));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityStickyKeysEnabled));
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilityStickyKeysEnabled,
std::make_unique<base::Value>(false));
EXPECT_TRUE(
prefs()->IsManagedPreference(prefs::kAccessibilityStickyKeysEnabled));
EXPECT_FALSE(controller()->sticky_keys().enabled());
EXPECT_FALSE(controller()->IsStickyKeysSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, AccessibilityAcceleratorShowHide) {
auto* accelerator_controller = Shell::Get()->accelerator_controller();
aura::Window* target_root = Shell::GetRootWindowForNewWindows();
StatusAreaWidget* status_area_widget =
RootWindowController::ForWindow(target_root)->GetStatusAreaWidget();
UnifiedSystemTray* tray = status_area_widget->unified_system_tray();
ASSERT_FALSE(tray->IsBubbleShown());
accelerator_controller->PerformActionIfEnabled(
AcceleratorAction::kAccessibilityAction, {});
ASSERT_TRUE(tray->IsBubbleShown());
ASSERT_TRUE(tray->bubble()
->unified_system_tray_controller()
->showing_accessibility_detailed_view());
accelerator_controller->PerformActionIfEnabled(
AcceleratorAction::kAccessibilityAction, {});
ASSERT_FALSE(tray->IsBubbleShown());
}
TEST_F(AccessibilityControllerTest, DisableLargeCursorDoesNotResetSize) {
auto* shell = Shell::Get();
shell->cursor_manager()->ShowCursor();
auto* cursor_window_controller =
shell->window_tree_host_manager()->cursor_window_controller();
ASSERT_NE(nullptr, cursor_window_controller);
EXPECT_FALSE(cursor_window_controller->is_cursor_compositing_enabled());
EXPECT_EQ(kDefaultLargeCursorSize,
prefs()->GetInteger(prefs::kAccessibilityLargeCursorDipSize));
prefs()->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
prefs()->SetInteger(prefs::kAccessibilityLargeCursorDipSize, 48);
EXPECT_EQ(48, prefs()->GetInteger(prefs::kAccessibilityLargeCursorDipSize));
EXPECT_TRUE(cursor_window_controller->is_cursor_compositing_enabled());
EXPECT_EQ(cursor_window_controller->GetCursorBoundsInScreenForTest().width(),
48);
EXPECT_EQ(cursor_window_controller->GetCursorBoundsInScreenForTest().height(),
48);
prefs()->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, false);
EXPECT_EQ(48, prefs()->GetInteger(prefs::kAccessibilityLargeCursorDipSize));
EXPECT_FALSE(cursor_window_controller->is_cursor_compositing_enabled());
prefs()->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
EXPECT_EQ(48, prefs()->GetInteger(prefs::kAccessibilityLargeCursorDipSize));
EXPECT_TRUE(cursor_window_controller->is_cursor_compositing_enabled());
EXPECT_EQ(cursor_window_controller->GetCursorBoundsInScreenForTest().width(),
48);
EXPECT_EQ(cursor_window_controller->GetCursorBoundsInScreenForTest().height(),
48);
}
TEST_F(AccessibilityControllerTest, ChangingCursorColorPrefChangesCursorColor) {
prefs()->SetInteger(prefs::kAccessibilityCursorColor, SK_ColorBLUE);
prefs()->SetBoolean(prefs::kAccessibilityCursorColorEnabled, true);
CursorWindowController* cursor_window_controller =
Shell::Get()->window_tree_host_manager()->cursor_window_controller();
EXPECT_EQ(SK_ColorBLUE, cursor_window_controller->GetCursorColorForTest());
prefs()->SetInteger(prefs::kAccessibilityCursorColor, SK_ColorGREEN);
EXPECT_EQ(SK_ColorGREEN, cursor_window_controller->GetCursorColorForTest());
ExpectSessionDurationMetricCount("CrosCursorColor", 0);
prefs()->SetInteger(prefs::kAccessibilityCursorColor, 0);
prefs()->SetBoolean(prefs::kAccessibilityCursorColorEnabled, false);
EXPECT_EQ(ui::kDefaultCursorColor,
cursor_window_controller->GetCursorColorForTest());
ExpectSessionDurationMetricCount("CrosCursorColor", 1);
}
TEST_F(AccessibilityControllerTest, SetMonoAudioEnabled) {
EXPECT_FALSE(controller()->mono_audio().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->mono_audio().SetEnabled(true);
EXPECT_TRUE(controller()->mono_audio().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosMonoAudio", 0);
controller()->mono_audio().SetEnabled(false);
EXPECT_FALSE(controller()->mono_audio().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosMonoAudio", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetSlowKeysEnabled) {
EXPECT_FALSE(controller()->slow_keys().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->slow_keys().SetEnabled(true);
EXPECT_TRUE(controller()->slow_keys().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosSlowKeys", 0);
controller()->slow_keys().SetEnabled(false);
EXPECT_FALSE(controller()->slow_keys().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosSlowKeys", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetSpokenFeedbackEnabled) {
EXPECT_FALSE(controller()->spoken_feedback().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_SHOW);
EXPECT_TRUE(controller()->spoken_feedback().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosSpokenFeedback", 0);
controller()->SetSpokenFeedbackEnabled(false, A11Y_NOTIFICATION_NONE);
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosSpokenFeedback", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, FeaturesConflictingWithChromeVox) {
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_FALSE(controller()->sticky_keys().enabled());
EXPECT_FALSE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
controller()->sticky_keys().SetEnabled(true);
controller()->focus_highlight().SetEnabled(true);
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_TRUE(controller()->sticky_keys().enabled());
EXPECT_TRUE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
controller()->spoken_feedback().SetEnabled(true);
EXPECT_TRUE(controller()->spoken_feedback().enabled());
EXPECT_FALSE(controller()->sticky_keys().enabled());
EXPECT_FALSE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
EXPECT_FALSE(controller()->IsFocusHighlightSettingVisibleInTray());
EXPECT_FALSE(controller()->IsStickyKeysSettingVisibleInTray());
controller()->spoken_feedback().SetEnabled(false);
EXPECT_FALSE(controller()->spoken_feedback().enabled());
EXPECT_TRUE(controller()->sticky_keys().enabled());
EXPECT_TRUE(controller()->focus_highlight().enabled());
EXPECT_TRUE(controller()->IsSpokenFeedbackSettingVisibleInTray());
EXPECT_TRUE(controller()->IsFocusHighlightSettingVisibleInTray());
EXPECT_TRUE(controller()->IsStickyKeysSettingVisibleInTray());
}
TEST_F(AccessibilityControllerTest, SetStickyKeysEnabled) {
EXPECT_FALSE(controller()->sticky_keys().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
StickyKeysController* sticky_keys_controller =
Shell::Get()->sticky_keys_controller();
controller()->sticky_keys().SetEnabled(true);
EXPECT_TRUE(sticky_keys_controller->enabled_for_test());
EXPECT_TRUE(controller()->sticky_keys().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosStickyKeys", 0);
controller()->sticky_keys().SetEnabled(false);
EXPECT_FALSE(sticky_keys_controller->enabled_for_test());
EXPECT_FALSE(controller()->sticky_keys().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosStickyKeys", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, SetVirtualKeyboardEnabled) {
EXPECT_FALSE(controller()->virtual_keyboard().enabled());
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
controller()->virtual_keyboard().SetEnabled(true);
EXPECT_TRUE(keyboard::GetAccessibilityKeyboardEnabled());
EXPECT_TRUE(controller()->virtual_keyboard().enabled());
EXPECT_EQ(1, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosVirtualKeyboard", 0);
controller()->virtual_keyboard().SetEnabled(false);
EXPECT_FALSE(keyboard::GetAccessibilityKeyboardEnabled());
EXPECT_FALSE(controller()->virtual_keyboard().enabled());
EXPECT_EQ(2, observer.status_changed_count_);
ExpectSessionDurationMetricCount("CrosVirtualKeyboard", 1);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest, GetShutdownSoundDuration) {
TestAccessibilityControllerClient client;
EXPECT_EQ(TestAccessibilityControllerClient::kShutdownSoundDuration,
client.PlayShutdownSound());
EXPECT_EQ(TestAccessibilityControllerClient::kShutdownSoundDuration,
controller()->PlayShutdownSound());
}
TEST_F(AccessibilityControllerTest, GetShouldToggleSpokenFeedbackViaTouch) {
TestAccessibilityControllerClient client;
EXPECT_TRUE(client.ShouldToggleSpokenFeedbackViaTouch());
EXPECT_TRUE(controller()->ShouldToggleSpokenFeedbackViaTouch());
}
TEST_F(AccessibilityControllerTest, SetDarkenScreen) {
ASSERT_FALSE(
chromeos::FakePowerManagerClient::Get()->backlights_forced_off());
controller()->SetDarkenScreen(true);
EXPECT_TRUE(chromeos::FakePowerManagerClient::Get()->backlights_forced_off());
controller()->SetDarkenScreen(false);
EXPECT_FALSE(
chromeos::FakePowerManagerClient::Get()->backlights_forced_off());
}
TEST_F(AccessibilityControllerTest, ShowNotificationOnSpokenFeedback) {
const std::u16string kChromeVoxEnabledTitle = u"ChromeVox enabled";
const std::u16string kChromeVoxEnabled =
u"Press Ctrl + Alt + Z to disable spoken feedback.";
controller()->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_SHOW);
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(kChromeVoxEnabledTitle, (*notifications.begin())->title());
EXPECT_EQ(kChromeVoxEnabled, (*notifications.begin())->message());
controller()->SetSpokenFeedbackEnabled(false, A11Y_NOTIFICATION_SHOW);
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(0u, notifications.size());
controller()->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE);
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(0u, notifications.size());
}
TEST_F(AccessibilityControllerTest,
ShowNotificationOnBrailleDisplayStateChanged) {
const std::u16string kBrailleConnected = u"Braille display connected.";
const std::u16string kChromeVoxEnabled =
u"Press Ctrl + Alt + Z to disable spoken feedback.";
const std::u16string kBrailleConnectedAndChromeVoxEnabledTitle =
u"Braille and ChromeVox are enabled";
controller()->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_SHOW);
EXPECT_TRUE(controller()->spoken_feedback().enabled());
controller()->BrailleDisplayStateChanged(true);
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(kBrailleConnected, (*notifications.begin())->title());
EXPECT_EQ(std::u16string(), (*notifications.begin())->message());
controller()->BrailleDisplayStateChanged(false);
EXPECT_TRUE(controller()->spoken_feedback().enabled());
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(0u, notifications.size());
controller()->SetSpokenFeedbackEnabled(false, A11Y_NOTIFICATION_SHOW);
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(0u, notifications.size());
EXPECT_FALSE(controller()->spoken_feedback().enabled());
controller()->BrailleDisplayStateChanged(true);
EXPECT_TRUE(controller()->spoken_feedback().enabled());
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(kBrailleConnectedAndChromeVoxEnabledTitle,
(*notifications.begin())->title());
EXPECT_EQ(kChromeVoxEnabled, (*notifications.begin())->message());
}
TEST_F(AccessibilityControllerTest, SelectToSpeakStateChanges) {
TestAccessibilityObserver observer;
controller()->AddObserver(&observer);
controller()->SetSelectToSpeakState(
SelectToSpeakState::kSelectToSpeakStateSelecting);
EXPECT_EQ(controller()->GetSelectToSpeakState(),
SelectToSpeakState::kSelectToSpeakStateSelecting);
EXPECT_EQ(observer.status_changed_count_, 1);
controller()->SetSelectToSpeakState(
SelectToSpeakState::kSelectToSpeakStateSpeaking);
EXPECT_EQ(controller()->GetSelectToSpeakState(),
SelectToSpeakState::kSelectToSpeakStateSpeaking);
EXPECT_EQ(observer.status_changed_count_, 2);
controller()->RemoveObserver(&observer);
}
TEST_F(AccessibilityControllerTest,
SpeechRecognitionDownloadSucceededNotification) {
const std::u16string kSucceededTitle =
u"English speech files partially downloaded";
const std::u16string kSucceededDescription =
u"Speech is processed locally and dictation works offline, but some "
u"voice commands won’t work.";
controller()->ShowNotificationForDictation(
DictationNotificationType::kOnlySodaDownloaded, u"English");
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(kSucceededTitle, (*notifications.begin())->title());
EXPECT_EQ(kSucceededDescription, (*notifications.begin())->message());
EXPECT_EQ(u"Dictation", (*notifications.begin())->display_source());
EXPECT_EQ(message_center::SystemNotificationWarningLevel::CRITICAL_WARNING,
(*notifications.begin())->system_notification_warning_level());
}
TEST_F(AccessibilityControllerTest,
SpeechRecognitionDownloadFailedNotification) {
const std::u16string kFailedTitle = u"Couldn't download English speech files";
const std::u16string kFailedDescription =
u"Download will be attempted later. Speech will be sent to Google for "
u"processing for now.";
controller()->ShowNotificationForDictation(
DictationNotificationType::kNoDlcsDownloaded, u"English");
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(kFailedTitle, (*notifications.begin())->title());
EXPECT_EQ(kFailedDescription, (*notifications.begin())->message());
EXPECT_EQ(u"Dictation", (*notifications.begin())->display_source());
EXPECT_EQ(message_center::SystemNotificationWarningLevel::CRITICAL_WARNING,
(*notifications.begin())->system_notification_warning_level());
}
TEST_F(AccessibilityControllerTest, AllAccessibilityFeaturesHaveValidNames) {
for (int type = 0; type != static_cast<int>(A11yFeatureType::kFeatureCount);
type++) {
auto& feature =
controller()->GetFeature(static_cast<A11yFeatureType>(type));
if (!feature.toggleable_in_quicksettings()) {
continue;
}
std::u16string feature_name =
l10n_util::GetStringUTF16(feature.name_resource_id());
EXPECT_GT(feature_name.length(), 0u);
}
}
TEST_F(AccessibilityControllerTest, VerifyFeatureData) {
EXPECT_TRUE(controller()->VerifyFeaturesDataForTesting());
}
TEST_F(AccessibilityControllerTest, ChangingPrefChangesCaretBlinkInterval) {
EXPECT_EQ(
prefs()->GetInteger(prefs::kAccessibilityCaretBlinkInterval),
ui::OsSettingsProvider::kDefaultCaretBlinkInterval.InMilliseconds());
const auto* const native_theme = ui::NativeTheme::GetInstanceForNativeUi();
const auto* const native_theme_web = ui::NativeTheme::GetInstanceForWeb();
EXPECT_EQ(ui::OsSettingsProvider::kDefaultCaretBlinkInterval,
native_theme->caret_blink_interval());
EXPECT_EQ(ui::OsSettingsProvider::kDefaultCaretBlinkInterval,
native_theme_web->caret_blink_interval());
static constexpr auto kNewInterval = base::Milliseconds(42);
prefs()->SetInteger(prefs::kAccessibilityCaretBlinkInterval,
kNewInterval.InMilliseconds());
EXPECT_EQ(kNewInterval, native_theme->caret_blink_interval());
EXPECT_EQ(kNewInterval, native_theme_web->caret_blink_interval());
}
TEST_F(AccessibilityControllerTest, FlashNotificationsWhenEnabled) {
EXPECT_FALSE(
prefs()->GetBoolean(prefs::kAccessibilityFlashNotificationsEnabled));
controller()->flash_notifications().SetEnabled(true);
EXPECT_TRUE(
prefs()->GetBoolean(prefs::kAccessibilityFlashNotificationsEnabled));
ShowNotification(message_center::RichNotificationData());
ExpectFlashNotificationShown();
controller()->flash_notifications().SetEnabled(false);
}
TEST_F(AccessibilityControllerTest, FlashNotificationsPreview) {
EXPECT_FALSE(
prefs()->GetBoolean(prefs::kAccessibilityFlashNotificationsEnabled));
controller()->flash_notifications().SetEnabled(true);
EXPECT_TRUE(
prefs()->GetBoolean(prefs::kAccessibilityFlashNotificationsEnabled));
controller()->PreviewFlashNotification();
ExpectFlashNotificationShown();
controller()->flash_notifications().SetEnabled(false);
}
TEST_F(AccessibilityControllerTest, DoesNotFlashNotificationsWhenNotEnabled) {
EXPECT_FALSE(
prefs()->GetBoolean(prefs::kAccessibilityFlashNotificationsEnabled));
ShowNotification(message_center::RichNotificationData());
ExpectFlashNotificationNotShown();
}
TEST_F(AccessibilityControllerTest, DoesNotFlashSilentNotifications) {
controller()->flash_notifications().SetEnabled(true);
message_center::RichNotificationData data =
message_center::RichNotificationData();
data.silent = true;
ShowNotification(data);
ExpectFlashNotificationNotShown();
ShowNotification(data);
ExpectFlashNotificationNotShown();
}
TEST_F(AccessibilityControllerTest, DoesNotLowPriorityNotifications) {
controller()->flash_notifications().SetEnabled(true);
message_center::RichNotificationData data =
message_center::RichNotificationData();
data.priority = message_center::LOW_PRIORITY;
ShowNotification(data);
ExpectFlashNotificationNotShown();
}
TEST_F(AccessibilityControllerTest, DoesNotFlashWhenInQuietMode) {
controller()->flash_notifications().SetEnabled(true);
message_center::MessageCenter::Get()->SetQuietMode(true);
ShowNotification(message_center::RichNotificationData());
ExpectFlashNotificationNotShown();
message_center::MessageCenter::Get()->SetQuietMode(false);
ShowNotification(message_center::RichNotificationData());
ExpectFlashNotificationShown();
}
TEST_F(AccessibilityControllerTest, EnableOrToggleDictation) {
TestAccessibilityControllerClient client;
controller()->SetClient(&client);
prefs()->SetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted, false);
ASSERT_FALSE(controller()->dictation().enabled());
ASSERT_FALSE(controller()->dictation_active());
controller()->EnableOrToggleDictationFromSource(
DictationToggleSource::kKeyboard);
ASSERT_FALSE(controller()->dictation().enabled());
ASSERT_FALSE(controller()->dictation_active());
ASSERT_TRUE(controller()->IsDictationKeyboardDialogShowingForTesting());
controller()->DismissDictationKeyboardDialogForTesting();
prefs()->SetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted, true);
controller()->dictation().SetEnabled(false);
controller()->SetDictationActive(false);
controller()->EnableOrToggleDictationFromSource(
DictationToggleSource::kKeyboard);
ASSERT_TRUE(controller()->dictation().enabled());
ASSERT_FALSE(controller()->dictation_active());
ASSERT_FALSE(controller()->IsDictationKeyboardDialogShowingForTesting());
ASSERT_TRUE(
prefs()->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted));
ASSERT_FALSE(controller()->dictation_active());
controller()->dictation().SetEnabled(true);
controller()->EnableOrToggleDictationFromSource(
DictationToggleSource::kKeyboard);
ASSERT_TRUE(controller()->dictation().enabled());
ASSERT_TRUE(controller()->dictation_active());
ASSERT_FALSE(controller()->IsDictationKeyboardDialogShowingForTesting());
controller()->EnableOrToggleDictationFromSource(
DictationToggleSource::kKeyboard);
ASSERT_TRUE(controller()->dictation().enabled());
ASSERT_FALSE(controller()->dictation_active());
ASSERT_FALSE(controller()->IsDictationKeyboardDialogShowingForTesting());
}
TEST_F(AccessibilityControllerTest, LogsDurationAtSessionLogout) {
controller()->large_cursor().SetEnabled(true);
ExpectSessionDurationMetricCount("CrosLargeCursor", 0);
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
ExpectSessionDurationMetricCount("CrosLargeCursor", 1);
}
TEST_F(AccessibilityControllerTest, LogsDurationAtSessionLock) {
controller()->large_cursor().SetEnabled(true);
ExpectSessionDurationMetricCount("CrosLargeCursor", 0);
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOCKED);
ExpectSessionDurationMetricCount("CrosLargeCursor", 1);
}
TEST_F(AccessibilityControllerTest, LogsDurationAtShutdown) {
controller()->large_cursor().SetEnabled(true);
ExpectSessionDurationMetricCount("CrosLargeCursor", 0);
controller()->Shutdown();
ExpectSessionDurationMetricCount("CrosLargeCursor", 1);
}
TEST_F(AccessibilityControllerTest,
FilterKeysEventRewriterNotInitializedWhenBounceKeysFeatureDisabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(
::features::kAccessibilityBounceKeys);
EventRewriterController::Get()->Initialize(nullptr, nullptr);
ASSERT_EQ(controller()->GetFilterKeysEventRewriterForTest(), nullptr);
}
TEST_F(AccessibilityControllerTest, FaceGazeNotifications) {
ASSERT_FALSE(
prefs()->GetBoolean(prefs::kFaceGazeDlcSuccessNotificationHasBeenShown));
ASSERT_FALSE(
prefs()->GetBoolean(prefs::kFaceGazeDlcFailureNotificationHasBeenShown));
controller()->ShowNotificationForFaceGaze(
FaceGazeNotificationType::kDlcSucceeded);
ASSERT_EQ(1u, MessageCenter::Get()->GetVisibleNotifications().size());
ASSERT_TRUE(
prefs()->GetBoolean(prefs::kFaceGazeDlcSuccessNotificationHasBeenShown));
message_center::MessageCenter::Get()->RemoveAllNotifications(
false, message_center::MessageCenter::RemoveType::ALL);
controller()->ShowNotificationForFaceGaze(
FaceGazeNotificationType::kDlcSucceeded);
ASSERT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size());
controller()->ShowNotificationForFaceGaze(
FaceGazeNotificationType::kDlcFailed);
ASSERT_EQ(1u, MessageCenter::Get()->GetVisibleNotifications().size());
ASSERT_TRUE(
prefs()->GetBoolean(prefs::kFaceGazeDlcFailureNotificationHasBeenShown));
message_center::MessageCenter::Get()->RemoveAllNotifications(
false, message_center::MessageCenter::RemoveType::ALL);
controller()->ShowNotificationForFaceGaze(
FaceGazeNotificationType::kDlcFailed);
ASSERT_EQ(1u, MessageCenter::Get()->GetVisibleNotifications().size());
}
TEST_F(AccessibilityControllerTest, ShowNotificationOnFaceGaze) {
controller()->face_gaze().SetEnabled(true);
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(u"Face control active", (*notifications.begin())->title());
ASSERT_TRUE((*notifications.begin())->pinned());
controller()->face_gaze().SetEnabled(false);
notifications = MessageCenter::Get()->GetVisibleNotifications();
EXPECT_EQ(0u, notifications.size());
}
TEST_F(AccessibilityControllerTest, ClickNotification) {
controller()->face_gaze().SetEnabled(true);
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
base::RunLoop dialog_waiter;
controller()->AddFeatureDisableDialogCallbackForTesting(
base::BindLambdaForTesting([&dialog_waiter]() { dialog_waiter.Quit(); }));
(*notifications.begin())
->delegate()
->Click(1, std::nullopt);
dialog_waiter.Run();
}
namespace {
enum class TestUserLoginType {
kNewUser,
kGuest,
kExistingUser,
};
class AccessibilityControllerSigninTest
: public NoSessionAshTestBase,
public testing::WithParamInterface<TestUserLoginType> {
public:
AccessibilityControllerSigninTest() = default;
AccessibilityControllerSigninTest(const AccessibilityControllerSigninTest&) =
delete;
AccessibilityControllerSigninTest& operator=(
const AccessibilityControllerSigninTest&) = delete;
~AccessibilityControllerSigninTest() = default;
void SimulateLogin() {
constexpr char kUserEmail[] = "user1@test.com";
switch (GetParam()) {
case TestUserLoginType::kNewUser:
SimulateNewUserFirstLogin(kUserEmail);
break;
case TestUserLoginType::kGuest:
SimulateGuestLogin();
break;
case TestUserLoginType::kExistingUser:
SimulateUserLogin({kUserEmail});
break;
}
}
};
}
INSTANTIATE_TEST_SUITE_P(All,
AccessibilityControllerSigninTest,
::testing::Values(TestUserLoginType::kNewUser,
TestUserLoginType::kGuest,
TestUserLoginType::kExistingUser));
TEST_P(AccessibilityControllerSigninTest, EnableOnLoginScreenAndLogin) {
constexpr float kMagnifierScale = 4.3f;
AccessibilityController* accessibility =
Shell::Get()->accessibility_controller();
DockedMagnifierController* docked_magnifier =
Shell::Get()->docked_magnifier_controller();
SessionControllerImpl* session = Shell::Get()->session_controller();
EXPECT_EQ(session_manager::SessionState::LOGIN_PRIMARY,
session->GetSessionState());
EXPECT_FALSE(accessibility->large_cursor().enabled());
EXPECT_FALSE(accessibility->live_caption().enabled());
EXPECT_FALSE(accessibility->spoken_feedback().enabled());
EXPECT_FALSE(accessibility->high_contrast().enabled());
EXPECT_FALSE(accessibility->autoclick().enabled());
EXPECT_FALSE(accessibility->mono_audio().enabled());
EXPECT_FALSE(accessibility->mouse_keys().enabled());
EXPECT_FALSE(docked_magnifier->GetEnabled());
using prefs::kAccessibilityAutoclickEnabled;
using prefs::kAccessibilityHighContrastEnabled;
using prefs::kAccessibilityLargeCursorEnabled;
using prefs::kAccessibilityMonoAudioEnabled;
using prefs::kAccessibilityMouseKeysEnabled;
using prefs::kAccessibilitySpokenFeedbackEnabled;
using prefs::kDockedMagnifierEnabled;
PrefService* signin_prefs = session->GetSigninScreenPrefService();
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityLargeCursorEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityHighContrastEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityAutoclickEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityMonoAudioEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityMouseKeysEnabled));
EXPECT_FALSE(signin_prefs->GetBoolean(kDockedMagnifierEnabled));
accessibility->large_cursor().SetEnabled(true);
accessibility->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE);
accessibility->high_contrast().SetEnabled(true);
accessibility->autoclick().SetEnabled(true);
accessibility->mono_audio().SetEnabled(true);
accessibility->mouse_keys().SetEnabled(true);
docked_magnifier->SetEnabled(true);
docked_magnifier->SetScale(kMagnifierScale);
EXPECT_TRUE(accessibility->large_cursor().enabled());
EXPECT_TRUE(accessibility->spoken_feedback().enabled());
EXPECT_TRUE(accessibility->high_contrast().enabled());
EXPECT_TRUE(accessibility->autoclick().enabled());
EXPECT_TRUE(accessibility->mono_audio().enabled());
EXPECT_TRUE(accessibility->mouse_keys().enabled());
EXPECT_TRUE(docked_magnifier->GetEnabled());
EXPECT_FLOAT_EQ(kMagnifierScale, docked_magnifier->GetScale());
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityHighContrastEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityAutoclickEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityMonoAudioEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityMouseKeysEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kDockedMagnifierEnabled));
SimulateLogin();
PrefService* user_prefs = session->GetLastActiveUserPrefService();
EXPECT_NE(signin_prefs, user_prefs);
const bool should_signin_prefs_be_copied =
GetParam() == TestUserLoginType::kNewUser ||
GetParam() == TestUserLoginType::kGuest;
if (should_signin_prefs_be_copied) {
EXPECT_TRUE(accessibility->large_cursor().enabled());
EXPECT_TRUE(accessibility->spoken_feedback().enabled());
EXPECT_TRUE(accessibility->high_contrast().enabled());
EXPECT_TRUE(accessibility->autoclick().enabled());
EXPECT_TRUE(accessibility->mono_audio().enabled());
EXPECT_TRUE(accessibility->mouse_keys().enabled());
EXPECT_TRUE(docked_magnifier->GetEnabled());
EXPECT_FLOAT_EQ(kMagnifierScale, docked_magnifier->GetScale());
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityHighContrastEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityAutoclickEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityMonoAudioEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityMouseKeysEnabled));
EXPECT_TRUE(user_prefs->GetBoolean(kDockedMagnifierEnabled));
} else {
EXPECT_FALSE(accessibility->large_cursor().enabled());
EXPECT_FALSE(accessibility->spoken_feedback().enabled());
EXPECT_FALSE(accessibility->high_contrast().enabled());
EXPECT_FALSE(accessibility->autoclick().enabled());
EXPECT_FALSE(accessibility->mono_audio().enabled());
EXPECT_FALSE(accessibility->mouse_keys().enabled());
EXPECT_FALSE(docked_magnifier->GetEnabled());
EXPECT_NE(kMagnifierScale, docked_magnifier->GetScale());
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityHighContrastEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityAutoclickEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityMonoAudioEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityMouseKeysEnabled));
EXPECT_FALSE(user_prefs->GetBoolean(kDockedMagnifierEnabled));
}
}
TEST_P(AccessibilityControllerSigninTest, SwitchAccessPrefsSyncToSignIn) {
AccessibilityController* accessibility =
Shell::Get()->accessibility_controller();
SessionControllerImpl* session = Shell::Get()->session_controller();
EXPECT_EQ(session_manager::SessionState::LOGIN_PRIMARY,
session->GetSessionState());
EXPECT_FALSE(accessibility->switch_access().enabled());
using prefs::kAccessibilitySwitchAccessAutoScanEnabled;
using prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs;
using prefs::kAccessibilitySwitchAccessAutoScanSpeedMs;
using prefs::kAccessibilitySwitchAccessEnabled;
using prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond;
PrefService* signin_prefs = session->GetSigninScreenPrefService();
EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilitySwitchAccessEnabled));
EXPECT_FALSE(
signin_prefs->GetBoolean(kAccessibilitySwitchAccessAutoScanEnabled));
SimulateLogin();
PrefService* user_prefs = session->GetLastActiveUserPrefService();
EXPECT_NE(signin_prefs, user_prefs);
EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilitySwitchAccessEnabled));
EXPECT_FALSE(
user_prefs->GetBoolean(kAccessibilitySwitchAccessAutoScanEnabled));
accessibility->switch_access().SetEnabled(true);
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilitySwitchAccessEnabled));
EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilitySwitchAccessEnabled));
user_prefs->Set(kAccessibilitySwitchAccessAutoScanEnabled, base::Value(true));
EXPECT_TRUE(
signin_prefs->GetBoolean(kAccessibilitySwitchAccessAutoScanEnabled));
user_prefs->Set(kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs,
base::Value(123));
EXPECT_EQ(123, signin_prefs->GetInteger(
kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs));
user_prefs->Set(kAccessibilitySwitchAccessAutoScanSpeedMs, base::Value(234));
EXPECT_EQ(
234, signin_prefs->GetInteger(kAccessibilitySwitchAccessAutoScanSpeedMs));
user_prefs->Set(kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond,
base::Value(345));
EXPECT_EQ(345, signin_prefs->GetInteger(
kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond));
signin_prefs->Set(kAccessibilitySwitchAccessEnabled, base::Value(false));
EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilitySwitchAccessEnabled));
}
TEST_P(AccessibilityControllerSigninTest,
UpdatesNonLoginWindowVisibilityOnLogin) {
aura::Window* container =
Shell::GetContainer(Shell::GetPrimaryRootWindow(),
kShellWindowId_NonLockScreenContainersContainer);
BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
EXPECT_TRUE(
container->GetProperty(ui::kAXConsiderInvisibleAndIgnoreChildren));
UnblockUserSession();
EXPECT_FALSE(
container->GetProperty(ui::kAXConsiderInvisibleAndIgnoreChildren));
BlockUserSession(BLOCKED_BY_LOGIN_SCREEN);
EXPECT_TRUE(
container->GetProperty(ui::kAXConsiderInvisibleAndIgnoreChildren));
UnblockUserSession();
EXPECT_FALSE(
container->GetProperty(ui::kAXConsiderInvisibleAndIgnoreChildren));
BlockUserSession(BLOCKED_BY_USER_ADDING_SCREEN);
EXPECT_TRUE(
container->GetProperty(ui::kAXConsiderInvisibleAndIgnoreChildren));
}
class AccessibilityControllerSelectToSpeakKeyboardShortcutTest
: public AccessibilityControllerTestBase {
protected:
AccessibilityControllerSelectToSpeakKeyboardShortcutTest() = default;
AccessibilityControllerSelectToSpeakKeyboardShortcutTest(
const AccessibilityControllerSelectToSpeakKeyboardShortcutTest&) = delete;
AccessibilityControllerSelectToSpeakKeyboardShortcutTest& operator=(
const AccessibilityControllerSelectToSpeakKeyboardShortcutTest&) = delete;
~AccessibilityControllerSelectToSpeakKeyboardShortcutTest() override =
default;
void SetDialogAcceptedPref(bool accepted) {
prefs()->SetBoolean(prefs::kSelectToSpeakAcceleratorDialogHasBeenAccepted,
accepted);
}
};
TEST_F(AccessibilityControllerSelectToSpeakKeyboardShortcutTest,
DialogNotAccepted) {
TestAccessibilityControllerClient client;
controller()->SetClient(&client);
SetDialogAcceptedPref(false);
ASSERT_FALSE(controller()->select_to_speak().enabled());
controller()->EnableSelectToSpeakWithDialog();
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(controller()->select_to_speak().enabled());
}
TEST_F(AccessibilityControllerSelectToSpeakKeyboardShortcutTest,
DialogAccepted) {
TestAccessibilityControllerClient client;
controller()->SetClient(&client);
SetDialogAcceptedPref(true);
ASSERT_FALSE(controller()->select_to_speak().enabled());
controller()->EnableSelectToSpeakWithDialog();
ASSERT_TRUE(controller()->select_to_speak().enabled());
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
}
TEST_F(AccessibilityControllerSelectToSpeakKeyboardShortcutTest,
SelectToSpeakAlreadyEnabled) {
TestAccessibilityControllerClient client;
controller()->SetClient(&client);
SetDialogAcceptedPref(true);
controller()->select_to_speak().SetEnabled(true);
ASSERT_TRUE(controller()->select_to_speak().enabled());
controller()->EnableSelectToSpeakWithDialog();
ASSERT_TRUE(controller()->select_to_speak().enabled());
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
}
TEST_F(AccessibilityControllerSelectToSpeakKeyboardShortcutTest,
NoDialogIfDisabledByPolicy) {
TestAccessibilityControllerClient client;
controller()->SetClient(&client);
SetDialogAcceptedPref(false);
ASSERT_FALSE(controller()->select_to_speak().enabled());
static_cast<TestingPrefServiceSimple*>(prefs())->SetManagedPref(
prefs::kAccessibilitySelectToSpeakEnabled,
std::make_unique<base::Value>(false));
controller()->EnableSelectToSpeakWithDialog();
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(controller()->select_to_speak().enabled());
}
class AccessibilityControllerDisableTouchpadTest : public AshTestBase {
protected:
AccessibilityControllerDisableTouchpadTest()
: AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
AccessibilityControllerDisableTouchpadTest(
const AccessibilityControllerDisableTouchpadTest&) = delete;
AccessibilityControllerDisableTouchpadTest& operator=(
const AccessibilityControllerDisableTouchpadTest&) = delete;
~AccessibilityControllerDisableTouchpadTest() override = default;
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(
::features::kAccessibilityDisableTouchpad);
AshTestBase::SetUp();
EventRewriterController::Get()->Initialize(nullptr, nullptr);
ASSERT_NE(disable_touchpad_event_rewriter(), nullptr);
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
}
AccessibilityController* controller() {
return Shell::Get()->accessibility_controller();
}
PrefService* prefs() {
return Shell::Get()->session_controller()->GetLastActiveUserPrefService();
}
base::RepeatingTimer& confirmation_dialog_timer() {
return controller()->GetConfirmationDialogForTest()->timer_;
}
DisableTouchpadEventRewriter* disable_touchpad_event_rewriter() {
return controller()->GetDisableTouchpadEventRewriterForTest();
}
base::HistogramTester histogram_tester_;
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(AccessibilityControllerDisableTouchpadTest,
PrefChangesEventRewriterEnabledState) {
ASSERT_FALSE(
prefs()->GetBoolean(prefs::kAccessibilityDisableTrackpadEnabled));
ASSERT_FALSE(controller()->disable_touchpad().enabled());
ASSERT_EQ(prefs()->GetInteger(prefs::kAccessibilityDisableTrackpadMode),
static_cast<int>(DisableTouchpadMode::kNever));
ASSERT_NE(disable_touchpad_event_rewriter(), nullptr);
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
prefs()->SetBoolean(prefs::kAccessibilityDisableTrackpadEnabled, true);
ASSERT_TRUE(controller()->disable_touchpad().enabled());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
prefs()->SetBoolean(prefs::kAccessibilityDisableTrackpadEnabled, false);
ASSERT_FALSE(controller()->disable_touchpad().enabled());
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest, NoDialogOnNeverMode) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kNever));
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
DialogShowsWhenSetToAlwaysMode) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
EventRewriterDisabledWhenDialogDismissed) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
controller()->DismissDisableTouchpadDialogForTesting();
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
EventRewriterEnabledWhenDialogAccepted) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
controller()->AcceptDisableTouchpadDialogForTesting();
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
DialogShowsWhenExternalMouseAlreadyConnected) {
SimulateExternalMouseConnected();
prefs()->SetInteger(
prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kOnExternalMouseConnected));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
NoDialogWithNoExternalMouseConnected) {
SimulateOnlyInternalTouchpadConnected();
prefs()->SetInteger(
prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kOnExternalMouseConnected));
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
ShowNotificationWhenDialogAccepted) {
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(0u, notifications.size());
SimulateOnlyInternalTouchpadConnected();
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
controller()->AcceptDisableTouchpadDialogForTesting();
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
const std::u16string kTouchpadDisabled = u"Built-in touchpad is disabled";
const std::u16string kPressEscape =
u"Press Shift 5 times to enable the touchpad";
notifications = MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(kTouchpadDisabled, (*notifications.begin())->title());
EXPECT_EQ(kPressEscape, (*notifications.begin())->message());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
NoNotificationWhenDialogRejected) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
controller()->DismissDisableTouchpadDialogForTesting();
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
message_center::NotificationList::Notifications notifications =
MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(0u, notifications.size());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
ToastShowsWhenPrefIsSwitchedToNeverMode) {
ASSERT_EQ(static_cast<int>(DisableTouchpadMode::kNever),
prefs()->GetInteger(prefs::kAccessibilityDisableTrackpadMode));
auto* toast_manager = Shell::Get()->toast_manager();
ASSERT_FALSE(toast_manager->IsToastShown(kAccessibilityToast));
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_FALSE(toast_manager->IsToastShown(kAccessibilityToast));
controller()->DismissDisableTouchpadDialogForTesting();
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(toast_manager->IsToastShown(kAccessibilityToast));
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
DialogShowsWhenExternalMouseLaterConnected) {
SimulateOnlyInternalTouchpadConnected();
prefs()->SetInteger(
prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kOnExternalMouseConnected));
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
SimulateExternalMouseConnected();
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
}
TEST_F(AccessibilityControllerDisableTouchpadTest, DialogClosesAfter30Seconds) {
SimulateOnlyInternalTouchpadConnected();
prefs()->SetInteger(
prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kOnExternalMouseConnected));
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
SimulateExternalMouseConnected();
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(confirmation_dialog_timer().IsRunning());
for (int i = 0; i < kDialogTimeoutSeconds; ++i) {
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
task_environment()->FastForwardBy(base::Seconds(1));
}
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_TRUE(confirmation_dialog_timer().IsRunning());
for (int i = 0; i < kDialogTimeoutSeconds; ++i) {
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
task_environment()->FastForwardBy(base::Seconds(1));
}
ASSERT_FALSE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_EQ(nullptr, controller()->GetConfirmationDialogForTest());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
TouchpadDisabledNotificationRemovedWhenTouchpadEnabledToastIsShown) {
ASSERT_EQ(static_cast<int>(DisableTouchpadMode::kNever),
prefs()->GetInteger(prefs::kAccessibilityDisableTrackpadMode));
auto* toast_manager = Shell::Get()->toast_manager();
ASSERT_FALSE(toast_manager->IsToastShown(kAccessibilityToast));
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_FALSE(toast_manager->IsToastShown(kAccessibilityToast));
controller()->AcceptDisableTouchpadDialogForTesting();
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
auto notifications = MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kNever));
ASSERT_TRUE(toast_manager->IsToastShown(kAccessibilityToast));
ASSERT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
TouchpadEnabledToastRemovedWhenConfirmationDialogIsShown) {
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kNever));
auto notifications = MessageCenter::Get()->GetVisibleNotifications();
auto* toast_manager = Shell::Get()->toast_manager();
ASSERT_TRUE(toast_manager->IsToastShown(kAccessibilityToast));
ASSERT_EQ(0u, notifications.size());
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
ASSERT_NE(nullptr, controller()->GetConfirmationDialogForTest());
ASSERT_TRUE(disable_touchpad_event_rewriter()->IsEnabled());
ASSERT_FALSE(toast_manager->IsToastShown(kAccessibilityToast));
controller()->AcceptDisableTouchpadDialogForTesting();
notifications = MessageCenter::Get()->GetVisibleNotifications();
ASSERT_EQ(1u, notifications.size());
}
TEST_F(AccessibilityControllerDisableTouchpadTest,
DisableInternalTouchpadMetrics) {
const std::string kDisableInternalTouchpadUmaMetric =
"Accessibility.CrosDisableTouchpad.SessionDuration";
AccessibilityController* controller =
Shell::Get()->accessibility_controller();
TestAccessibilityObserver observer;
controller->AddObserver(&observer);
EXPECT_EQ(0, observer.status_changed_count_);
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kAlways));
EXPECT_EQ(1, observer.status_changed_count_);
histogram_tester_.ExpectTotalCount(kDisableInternalTouchpadUmaMetric, 0);
prefs()->SetInteger(prefs::kAccessibilityDisableTrackpadMode,
static_cast<int>(DisableTouchpadMode::kNever));
EXPECT_EQ(2, observer.status_changed_count_);
histogram_tester_.ExpectTotalCount(kDisableInternalTouchpadUmaMetric, 1);
controller->RemoveObserver(&observer);
}
class AccessibilityControllerBounceKeysTest
: public AccessibilityControllerTestBase {
protected:
AccessibilityControllerBounceKeysTest() = default;
AccessibilityControllerBounceKeysTest(
const AccessibilityControllerBounceKeysTest&) = delete;
AccessibilityControllerBounceKeysTest& operator=(
const AccessibilityControllerBounceKeysTest&) = delete;
~AccessibilityControllerBounceKeysTest() override = default;
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(
::features::kAccessibilityBounceKeys);
AccessibilityControllerTestBase::SetUp();
EventRewriterController::Get()->Initialize(nullptr, nullptr);
ASSERT_NE(filter_keys_event_rewriter(), nullptr);
}
FilterKeysEventRewriter* filter_keys_event_rewriter() {
return controller()->GetFilterKeysEventRewriterForTest();
}
};
TEST_F(AccessibilityControllerBounceKeysTest, ToggleBounceKeysEnabledPref) {
ASSERT_FALSE(prefs()->GetBoolean(prefs::kAccessibilityBounceKeysEnabled));
ASSERT_FALSE(controller()->bounce_keys().enabled());
ASSERT_FALSE(filter_keys_event_rewriter()->IsBounceKeysEnabled());
prefs()->SetBoolean(prefs::kAccessibilityBounceKeysEnabled, true);
EXPECT_TRUE(controller()->bounce_keys().enabled());
EXPECT_TRUE(filter_keys_event_rewriter()->IsBounceKeysEnabled());
prefs()->SetBoolean(prefs::kAccessibilityBounceKeysEnabled, false);
EXPECT_FALSE(controller()->bounce_keys().enabled());
EXPECT_FALSE(filter_keys_event_rewriter()->IsBounceKeysEnabled());
}
TEST_F(AccessibilityControllerBounceKeysTest, UpdateBounceKeysDelayPref) {
ASSERT_EQ(prefs()->GetInteger(prefs::kAccessibilityBounceKeysDelayMs),
kDefaultAccessibilityBounceKeysDelay.InMilliseconds());
ASSERT_EQ(filter_keys_event_rewriter()->GetBounceKeysDelay(),
kDefaultAccessibilityBounceKeysDelay);
base::TimeDelta expected_delta = base::Milliseconds(123);
prefs()->SetInteger(prefs::kAccessibilityBounceKeysDelayMs,
expected_delta.InMilliseconds());
EXPECT_EQ(filter_keys_event_rewriter()->GetBounceKeysDelay(), expected_delta);
expected_delta = base::Milliseconds(789);
prefs()->SetInteger(prefs::kAccessibilityBounceKeysDelayMs,
expected_delta.InMilliseconds());
EXPECT_EQ(filter_keys_event_rewriter()->GetBounceKeysDelay(), expected_delta);
}
class AccessibilityControllerRegisterProfilePrefsTest
: public AccessibilityControllerTestBase,
public testing::WithParamInterface<bool> {
public:
AccessibilityControllerRegisterProfilePrefsTest() {
if (GetParam()) {
scoped_feature_list_.InitWithFeatures(
{features::kOsSyncAccessibilitySettingsBatch1,
features::kOsSyncAccessibilitySettingsBatch2,
features::kOsSyncAccessibilitySettingsBatch3},
{});
} else {
scoped_feature_list_.InitWithFeatures(
{}, {features::kOsSyncAccessibilitySettingsBatch1,
features::kOsSyncAccessibilitySettingsBatch2,
features::kOsSyncAccessibilitySettingsBatch3});
}
}
~AccessibilityControllerRegisterProfilePrefsTest() override = default;
protected:
template <size_t N>
void CheckPrefsSyncableFlags(const std::array<const char*, N>& pref_names) {
const bool expect_sync = GetParam();
for (const char* pref_name : pref_names) {
const auto* pref = prefs()->FindPreference(pref_name);
ASSERT_TRUE(pref) << pref_name;
const uint32_t flags = pref->registration_flags();
if (expect_sync) {
EXPECT_NE(0u,
flags & user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF)
<< pref_name;
} else {
EXPECT_EQ(0u,
flags & user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF)
<< pref_name;
}
}
}
};
TEST_P(AccessibilityControllerRegisterProfilePrefsTest,
RegistersVisualPrefsWithExpectedSyncFlags) {
constexpr auto kBatch1AccessibilitySyncPrefs = std::to_array<const char*>({
prefs::kAccessibilityColorCorrectionEnabled,
prefs::kAccessibilityColorCorrectionHasBeenSetup,
prefs::kAccessibilityCursorHighlightEnabled,
prefs::kAccessibilityCursorColorEnabled,
prefs::kAccessibilityCursorColor,
prefs::kAccessibilityLargeCursorEnabled,
prefs::kAccessibilityLargeCursorDipSize,
prefs::kAccessibilityHighContrastEnabled,
prefs::kHighContrastAcceleratorDialogHasBeenAccepted,
prefs::kAccessibilityCaretHighlightEnabled,
prefs::kAccessibilityCaretBlinkInterval,
prefs::kAccessibilityFocusHighlightEnabled,
});
CheckPrefsSyncableFlags(kBatch1AccessibilitySyncPrefs);
constexpr auto kBatch2AccessibilitySyncPrefs = std::to_array<const char*>({
prefs::kAccessibilityReducedAnimationsEnabled,
});
CheckPrefsSyncableFlags(kBatch2AccessibilitySyncPrefs);
constexpr auto kBatch3AccessibilitySyncPrefs = std::to_array<const char*>(
{prefs::kAccessibilityScreenMagnifierEnabled,
prefs::kAccessibilitySelectToSpeakEnabled,
prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted,
prefs::kDockedMagnifierAcceleratorDialogHasBeenAccepted,
prefs::kSelectToSpeakAcceleratorDialogHasBeenAccepted,
prefs::kAccessibilityScreenMagnifierScale});
CheckPrefsSyncableFlags(kBatch3AccessibilitySyncPrefs);
}
INSTANTIATE_TEST_SUITE_P(All,
AccessibilityControllerRegisterProfilePrefsTest,
::testing::Values(true, false));
}