diff options
31 files changed, 291 insertions, 33 deletions
diff --git a/ash/accessibility_delegate.h b/ash/accessibility_delegate.h index a4ef7eb..8d4b932 100644 --- a/ash/accessibility_delegate.h +++ b/ash/accessibility_delegate.h @@ -63,6 +63,9 @@ class ASH_EXPORT AccessibilityDelegate { // Returns if autoclick is enabled or not. virtual bool IsAutoclickEnabled() const = 0; + // Returns if the a11y virtual keyboard is enabled. + virtual bool IsVirtualKeyboardEnabled() const = 0; + // Returns true when the accessibility menu should be shown. virtual bool ShouldShowAccessibilityMenu() const = 0; diff --git a/ash/default_accessibility_delegate.cc b/ash/default_accessibility_delegate.cc index 99540d7..94a3d30 100644 --- a/ash/default_accessibility_delegate.cc +++ b/ash/default_accessibility_delegate.cc @@ -65,6 +65,10 @@ bool DefaultAccessibilityDelegate::IsAutoclickEnabled() const { return autoclick_enabled_; } +bool DefaultAccessibilityDelegate::IsVirtualKeyboardEnabled() const { + return false; +} + bool DefaultAccessibilityDelegate::ShouldShowAccessibilityMenu() const { return spoken_feedback_enabled_ || high_contrast_enabled_ || diff --git a/ash/default_accessibility_delegate.h b/ash/default_accessibility_delegate.h index 84d0e3e..ad0b684 100644 --- a/ash/default_accessibility_delegate.h +++ b/ash/default_accessibility_delegate.h @@ -29,6 +29,7 @@ class ASH_EXPORT DefaultAccessibilityDelegate : public AccessibilityDelegate { virtual bool IsLargeCursorEnabled() const OVERRIDE; virtual void SetAutoclickEnabled(bool enabled) OVERRIDE; virtual bool IsAutoclickEnabled() const OVERRIDE; + virtual bool IsVirtualKeyboardEnabled() const OVERRIDE; virtual bool ShouldShowAccessibilityMenu() const OVERRIDE; virtual void SilenceSpokenFeedback() const OVERRIDE; virtual void ToggleSpokenFeedback( diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index d295cae..e5030ad 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -614,13 +614,10 @@ void RootWindowController::ActivateKeyboard( void RootWindowController::DeactivateKeyboard( keyboard::KeyboardController* keyboard_controller) { - if (!keyboard::IsKeyboardEnabled()) + if (!keyboard_controller || + !keyboard_controller->keyboard_container_initialized()) { return; - - DCHECK(keyboard_controller); - if (!keyboard_controller->keyboard_container_initialized()) - return; - + } aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); if (keyboard_container->GetRootWindow() == root_window()) { diff --git a/ash/shell.cc b/ash/shell.cc index d5209fb..4c298a4 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -416,6 +416,17 @@ void Shell::CreateKeyboard() { } } +void Shell::DeactivateKeyboard() { + if (keyboard_controller_.get()) { + RootWindowControllerList controllers = GetAllRootWindowControllers(); + for (RootWindowControllerList::iterator iter = controllers.begin(); + iter != controllers.end(); ++iter) { + (*iter)->DeactivateKeyboard(keyboard_controller_.get()); + } + } + keyboard_controller_.reset(); +} + void Shell::ShowShelf() { RootWindowControllerList controllers = GetAllRootWindowControllers(); for (RootWindowControllerList::iterator iter = controllers.begin(); @@ -860,8 +871,9 @@ void Shell::Init() { // The keyboard system must be initialized before the RootWindowController is // created. - if (keyboard::IsKeyboardEnabled()) +#if defined(OS_CHROMEOS) keyboard::InitializeKeyboard(); +#endif lock_state_controller_.reset(new LockStateController); power_button_controller_.reset(new PowerButtonController( diff --git a/ash/shell.h b/ash/shell.h index a9a0d2a..949de18 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -292,10 +292,13 @@ class ASH_EXPORT Shell // Initializes |shelf_|. Does nothing if it's already initialized. void CreateShelf(); - // Creates virtual keyboard. Deletes the old virtual keyboard if it's already - // exist. + // Creates a virtual keyboard. Deletes the old virtual keyboard if it already + // exists. void CreateKeyboard(); + // Deactivates the virtual keyboard. + void DeactivateKeyboard(); + // Show shelf view if it was created hidden (before session has started). void ShowShelf(); diff --git a/ash/system/tray_accessibility.cc b/ash/system/tray_accessibility.cc index 8b1902d..3ce65bf 100644 --- a/ash/system/tray_accessibility.cc +++ b/ash/system/tray_accessibility.cc @@ -38,6 +38,7 @@ enum AccessibilityState { A11Y_SCREEN_MAGNIFIER = 1 << 2, A11Y_LARGE_CURSOR = 1 << 3, A11Y_AUTOCLICK = 1 << 4, + A11Y_VIRTUAL_KEYBOARD = 1 << 5, }; uint32 GetAccessibilityState() { @@ -54,6 +55,8 @@ uint32 GetAccessibilityState() { state |= A11Y_LARGE_CURSOR; if (delegate->IsAutoclickEnabled()) state |= A11Y_AUTOCLICK; + if (delegate->IsVirtualKeyboardEnabled()) + state |= A11Y_VIRTUAL_KEYBOARD; return state; } diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index e544874..e7d6b22 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc @@ -27,6 +27,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "ui/keyboard/keyboard.h" #endif #if defined(USE_X11) @@ -113,6 +114,7 @@ void AshTestHelper::TearDown() { chromeos::DBusThreadManager::Shutdown(); dbus_thread_manager_initialized_ = false; } + keyboard::ResetKeyboardForTesting(); #endif aura::Env::DeleteInstance(); diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 55b38b4..72aad18 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -1215,6 +1215,9 @@ Press any key to continue exploring. <message name="IDS_OOBE_SCREEN_MAGNIFIER_OPTION" desc="Screen magnifier option shown on OOBE screens accessibility menu."> Screen magnifier </message> + <message name="IDS_OOBE_VIRTUAL_KEYBOARD_OPTION" desc="Virtual keyboard option shown on the OOBE screens accessibility menu."> + On-screen keyboard + </message> <message name="IDS_LOGIN_TITLE" desc="Title of sign in box"> Sign in </message> @@ -1847,7 +1850,7 @@ Press any key to continue exploring. Enable tap dragging </message> <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_VIRTUAL_KEYBOARD_DESCRIPTION" desc="In the settings tab, the text next to the checkbox for virtual keyboard."> - Enable virtual keyboard + Enable on-screen keyboard </message> <message name="IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SHOULD_ALWAYS_SHOW_MENU" desc="In the settings tab, the text next to the checkbox to show the accessibility tray menu regardless of the state of a11y features."> Show accessibility options in the system menu diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h index 2c7d7df..c0b1ea8 100644 --- a/chrome/browser/chrome_notification_types.h +++ b/chrome/browser/chrome_notification_types.h @@ -866,6 +866,9 @@ enum NotificationType { // Sent when spoken feedback is toggled. NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK, + // Sent when a11y on-screen keyboard is toggled. + NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + #endif #if defined(TOOLKIT_VIEWS) diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 4b6e862..60c024a 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc @@ -61,6 +61,8 @@ #include "media/audio/sounds/sounds_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_util.h" using content::BrowserThread; using content::RenderViewHost; @@ -296,12 +298,14 @@ AccessibilityManager::AccessibilityManager() high_contrast_pref_handler_(prefs::kHighContrastEnabled), autoclick_pref_handler_(prefs::kAutoclickEnabled), autoclick_delay_pref_handler_(prefs::kAutoclickDelayMs), + virtual_keyboard_pref_handler_(prefs::kVirtualKeyboardEnabled), large_cursor_enabled_(false), sticky_keys_enabled_(false), spoken_feedback_enabled_(false), high_contrast_enabled_(false), autoclick_enabled_(false), autoclick_delay_ms_(ash::AutoclickController::kDefaultAutoclickDelayMs), + virtual_keyboard_enabled_(false), spoken_feedback_notification_(ash::A11Y_NOTIFICATION_NONE), weak_ptr_factory_(this), should_speak_chrome_vox_announcements_on_user_screen_(true), @@ -367,7 +371,8 @@ bool AccessibilityManager::ShouldShowAccessibilityMenu() { pref_service->GetBoolean(prefs::kHighContrastEnabled) || pref_service->GetBoolean(prefs::kAutoclickEnabled) || pref_service->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu) || - pref_service->GetBoolean(prefs::kScreenMagnifierEnabled)) + pref_service->GetBoolean(prefs::kScreenMagnifierEnabled) || + pref_service->GetBoolean(prefs::kVirtualKeyboardEnabled)) return true; } return false; @@ -681,6 +686,45 @@ void AccessibilityManager::UpdateAutoclickDelayFromPref() { #endif } +void AccessibilityManager::EnableVirtualKeyboard(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kVirtualKeyboardEnabled, enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsVirtualKeyboardEnabled() { + return virtual_keyboard_enabled_; +} + +void AccessibilityManager::UpdateVirtualKeyboardFromPref() { + if (!profile_) + return; + + const bool enabled = + profile_->GetPrefs()->GetBoolean(prefs::kVirtualKeyboardEnabled); + + if (virtual_keyboard_enabled_ == enabled) + return; + virtual_keyboard_enabled_ = enabled; + + AccessibilityStatusEventDetails detail(enabled, ash::A11Y_NOTIFICATION_NONE); + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + content::NotificationService::AllSources(), + content::Details<AccessibilityStatusEventDetails>(&detail)); + +#if defined(USE_ASH) + keyboard::SetAccessibilityKeyboardEnabled(enabled); + if (enabled) + ash::Shell::GetInstance()->CreateKeyboard(); + else if (!keyboard::IsKeyboardEnabled()) + ash::Shell::GetInstance()->DeactivateKeyboard(); +#endif +} + void AccessibilityManager::CheckBrailleState() { BrowserThread::PostTaskAndReplyWithResult( BrowserThread::IO, FROM_HERE, base::Bind( @@ -728,6 +772,10 @@ void AccessibilityManager::SetProfile(Profile* profile) { prefs::kAutoclickDelayMs, base::Bind(&AccessibilityManager::UpdateAutoclickDelayFromPref, base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kVirtualKeyboardEnabled, + base::Bind(&AccessibilityManager::UpdateVirtualKeyboardFromPref, + base::Unretained(this))); local_state_pref_change_registrar_.reset(new PrefChangeRegistrar); local_state_pref_change_registrar_->Init(g_browser_process->local_state()); @@ -761,6 +809,7 @@ void AccessibilityManager::SetProfile(Profile* profile) { UpdateHighContrastFromPref(); UpdateAutoclickFromPref(); UpdateAutoclickDelayFromPref(); + UpdateVirtualKeyboardFromPref(); } void AccessibilityManager::ActiveUserChanged(const std::string& user_id) { @@ -795,7 +844,7 @@ void AccessibilityManager::UpdateChromeOSAccessibilityHistograms() { UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosHighContrast", IsHighContrastEnabled()); UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosVirtualKeyboard", - accessibility::IsVirtualKeyboardEnabled()); + IsVirtualKeyboardEnabled()); if (MagnificationManager::Get()) { uint32 type = MagnificationManager::Get()->IsMagnifierEnabled() ? MagnificationManager::Get()->GetMagnifierType() : 0; diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 82f0a5f..a5ef522 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h @@ -117,6 +117,11 @@ class AccessibilityManager : public content::NotificationObserver, // Returns the autoclick delay in milliseconds. int GetAutoclickDelay() const; + // Enables or disables the virtual keyboard. + void EnableVirtualKeyboard(bool enabled); + // Returns true if the virtual keyboard is enabled, otherwise false. + bool IsVirtualKeyboardEnabled(); + // SessionStateObserver overrides: virtual void ActiveUserChanged(const std::string& user_id) OVERRIDE; @@ -150,6 +155,7 @@ class AccessibilityManager : public content::NotificationObserver, void UpdateHighContrastFromPref(); void UpdateAutoclickFromPref(); void UpdateAutoclickDelayFromPref(); + void UpdateVirtualKeyboardFromPref(); void LocalePrefChanged(); void CheckBrailleState(); @@ -199,6 +205,7 @@ class AccessibilityManager : public content::NotificationObserver, PrefHandler high_contrast_pref_handler_; PrefHandler autoclick_pref_handler_; PrefHandler autoclick_delay_pref_handler_; + PrefHandler virtual_keyboard_pref_handler_; bool large_cursor_enabled_; bool sticky_keys_enabled_; @@ -206,6 +213,7 @@ class AccessibilityManager : public content::NotificationObserver, bool high_contrast_enabled_; bool autoclick_enabled_; int autoclick_delay_ms_; + bool virtual_keyboard_enabled_; ash::AccessibilityNotificationVisibility spoken_feedback_notification_; diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc index c7788f6..8d47034 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc @@ -55,6 +55,10 @@ class MockAccessibilityObserver : public content::NotificationObserver { this, chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, content::NotificationService::AllSources()); + registrar_.Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + content::NotificationService::AllSources()); } virtual ~MockAccessibilityObserver() {} @@ -85,6 +89,11 @@ class MockAccessibilityObserver : public content::NotificationObserver { observed_enabled_ = accessibility_status->enabled; observed_type_ = type; break; + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD: + observed_ = true; + observed_enabled_ = accessibility_status->enabled; + observed_type_ = type; + break; } } @@ -175,6 +184,14 @@ int GetAutoclickDelay() { return AccessibilityManager::Get()->GetAutoclickDelay(); } +void SetVirtualKeyboardEnabled(bool enabled) { + return AccessibilityManager::Get()->EnableVirtualKeyboard(enabled); +} + +bool IsVirtualKeyboardEnabled() { + return AccessibilityManager::Get()->IsVirtualKeyboardEnabled(); +} + Profile* GetProfile() { Profile* profile = ProfileManager::GetActiveUserProfile(); DCHECK(profile); @@ -205,6 +222,10 @@ void SetAutoclickDelayPref(int delay_ms) { GetPrefs()->SetInteger(prefs::kAutoclickDelayMs, delay_ms); } +void SetVirtualKeyboardEnabledPref(bool enabled) { + GetPrefs()->SetBoolean(prefs::kVirtualKeyboardEnabled, enabled); +} + bool GetLargeCursorEnabledFromPref() { return GetPrefs()->GetBoolean(prefs::kLargeCursorEnabled); } @@ -269,6 +290,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, Login) { EXPECT_FALSE(IsSpokenFeedbackEnabled()); EXPECT_FALSE(IsHighContrastEnabled()); EXPECT_FALSE(IsAutoclickEnabled()); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay()); // Logs in. @@ -279,6 +301,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, Login) { EXPECT_FALSE(IsSpokenFeedbackEnabled()); EXPECT_FALSE(IsHighContrastEnabled()); EXPECT_FALSE(IsAutoclickEnabled()); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay()); UserManager::Get()->SessionStarted(); @@ -288,6 +311,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, Login) { EXPECT_FALSE(IsSpokenFeedbackEnabled()); EXPECT_FALSE(IsHighContrastEnabled()); EXPECT_FALSE(IsAutoclickEnabled()); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay()); // Enables large cursor. @@ -313,6 +337,11 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, Login) { // Test that autoclick delay is set properly. SetAutoclickDelay(kTestAutoclickDelayMs); EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); + + // Enable on-screen keyboard + SetVirtualKeyboardEnabled(true); + // Confirm that the on-screen keyboard option is enabled. + EXPECT_TRUE(IsVirtualKeyboardEnabled()); } IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, BrailleOnLoginScreen) { @@ -338,6 +367,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) { EXPECT_FALSE(IsHighContrastEnabled()); EXPECT_FALSE(IsAutoclickEnabled()); EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay()); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); // Sets the pref as true to enable the large cursor. SetLargeCursorEnabledPref(true); @@ -364,6 +394,11 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) { // Confirm that the correct value is set. EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); + // Sets the on-screen keyboard pref. + SetVirtualKeyboardEnabledPref(true); + // Confirm that the on-screen keyboard option is enabled. + EXPECT_TRUE(IsVirtualKeyboardEnabled()); + SetLargeCursorEnabledPref(false); EXPECT_FALSE(IsLargeCursorEnabled()); @@ -375,6 +410,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) { SetAutoclickEnabledPref(false); EXPECT_FALSE(IsAutoclickEnabled()); + + SetVirtualKeyboardEnabledPref(false); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); } IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, ResumeSavedPref) { @@ -402,15 +440,20 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, ResumeSavedPref) { SetAutoclickDelayPref(kTestAutoclickDelayMs); EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay()); + // Sets the pref to enable the on-screen keyboard before login. + SetVirtualKeyboardEnabledPref(true); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); + // Logs in. UserManager::Get()->SessionStarted(); - // Confirms that features are enabled by restring from pref just after login. + // Confirms that features are enabled by restoring from pref just after login. EXPECT_TRUE(IsLargeCursorEnabled()); EXPECT_TRUE(IsSpokenFeedbackEnabled()); EXPECT_TRUE(IsHighContrastEnabled()); EXPECT_TRUE(IsAutoclickEnabled()); EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); + EXPECT_TRUE(IsVirtualKeyboardEnabled()); } IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, @@ -454,6 +497,22 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, EXPECT_EQ(observer.observed_type(), chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE); EXPECT_FALSE(IsHighContrastEnabled()); + + observer.reset(); + SetVirtualKeyboardEnabled(true); + EXPECT_TRUE(observer.observed()); + EXPECT_TRUE(observer.observed_enabled()); + EXPECT_EQ(observer.observed_type(), + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD); + EXPECT_TRUE(IsVirtualKeyboardEnabled()); + + observer.reset(); + SetVirtualKeyboardEnabled(false); + EXPECT_TRUE(observer.observed()); + EXPECT_FALSE(observer.observed_enabled()); + EXPECT_EQ(observer.observed_type(), + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); } IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, @@ -497,6 +556,22 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, EXPECT_EQ(observer.observed_type(), chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE); EXPECT_FALSE(IsHighContrastEnabled()); + + observer.reset(); + SetVirtualKeyboardEnabledPref(true); + EXPECT_TRUE(observer.observed()); + EXPECT_TRUE(observer.observed_enabled()); + EXPECT_EQ(observer.observed_type(), + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD); + EXPECT_TRUE(IsVirtualKeyboardEnabled()); + + observer.reset(); + SetVirtualKeyboardEnabledPref(false); + EXPECT_TRUE(observer.observed()); + EXPECT_FALSE(observer.observed_enabled()); + EXPECT_EQ(observer.observed_type(), + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); } class AccessibilityManagerUserTypeTest @@ -575,6 +650,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AcessibilityMenuVisibility) { EXPECT_FALSE(IsHighContrastEnabled()); EXPECT_FALSE(IsAutoclickEnabled()); EXPECT_FALSE(ShouldShowAccessibilityMenu()); + EXPECT_FALSE(IsVirtualKeyboardEnabled()); // Check large cursor. SetLargeCursorEnabled(true); @@ -599,6 +675,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AcessibilityMenuVisibility) { EXPECT_TRUE(ShouldShowAccessibilityMenu()); SetAutoclickEnabled(false); EXPECT_FALSE(ShouldShowAccessibilityMenu()); + + // Check on-screen keyboard. + SetVirtualKeyboardEnabled(true); + EXPECT_TRUE(ShouldShowAccessibilityMenu()); + SetVirtualKeyboardEnabled(false); + EXPECT_FALSE(ShouldShowAccessibilityMenu()); } } // namespace chromeos diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index df8282b..d25473d 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc @@ -170,6 +170,10 @@ void Preferences::RegisterProfilePrefs( ash::AutoclickController::kDefaultAutoclickDelayMs, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref( + prefs::kVirtualKeyboardEnabled, + false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( prefs::kShouldAlwaysShowAccessibilityMenu, false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); @@ -331,6 +335,8 @@ void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) { prefs, callback); a11y_screen_magnifier_scale_.Init(prefs::kScreenMagnifierScale, prefs, callback); + a11y_virtual_keyboard_enabled_.Init(prefs::kVirtualKeyboardEnabled, + prefs, callback); mouse_sensitivity_.Init(prefs::kMouseSensitivity, prefs, callback); touchpad_sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, callback); use_24hour_clock_.Init(prefs::kUse24HourClock, prefs, callback); diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h index 3f26f5a..c1efa93 100644 --- a/chrome/browser/chromeos/preferences.h +++ b/chrome/browser/chromeos/preferences.h @@ -106,6 +106,7 @@ class Preferences : public PrefServiceSyncableObserver, BooleanPrefMember a11y_screen_magnifier_enabled_; IntegerPrefMember a11y_screen_magnifier_type_; DoublePrefMember a11y_screen_magnifier_scale_; + BooleanPrefMember a11y_virtual_keyboard_enabled_; IntegerPrefMember speed_factor_; IntegerPrefMember mouse_sensitivity_; IntegerPrefMember touchpad_sensitivity_; diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index cae250a..98d2a46 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc @@ -359,8 +359,7 @@ void ComponentLoader::AddChromeApp() { void ComponentLoader::AddKeyboardApp() { #if defined(USE_AURA) - if (keyboard::IsKeyboardEnabled()) - Add(IDR_KEYBOARD_MANIFEST, base::FilePath(FILE_PATH_LITERAL("keyboard"))); + Add(IDR_KEYBOARD_MANIFEST, base::FilePath(FILE_PATH_LITERAL("keyboard"))); #endif } diff --git a/chrome/browser/extensions/image_loader.cc b/chrome/browser/extensions/image_loader.cc index 8ccfef6..582ab39 100644 --- a/chrome/browser/extensions/image_loader.cc +++ b/chrome/browser/extensions/image_loader.cc @@ -247,14 +247,12 @@ bool ImageLoader::IsComponentExtensionResource( path_to_resource_id.Pointer(), kExtraComponentExtensionResources, arraysize(kExtraComponentExtensionResources)); -#if defined(USE_AURA) - if (keyboard::IsKeyboardEnabled()) { - size_t size; - const GritResourceMap* keyboard_resources = - keyboard::GetKeyboardExtensionResources(&size); - AddComponentResourceEntries( - path_to_resource_id.Pointer(), keyboard_resources, size); - } +#if defined(OS_CHROMEOS) + size_t size; + const GritResourceMap* keyboard_resources = + keyboard::GetKeyboardExtensionResources(&size); + AddComponentResourceEntries( + path_to_resource_id.Pointer(), keyboard_resources, size); #endif } diff --git a/chrome/browser/resources/chromeos/login/accessibility_menu.html b/chrome/browser/resources/chromeos/login/accessibility_menu.html index 8078692..38d2530 100644 --- a/chrome/browser/resources/chromeos/login/accessibility_menu.html +++ b/chrome/browser/resources/chromeos/login/accessibility_menu.html @@ -24,4 +24,10 @@ i18n-content="screenMagnifierOption"> </label> </div> + <div class="checkboxrow"> + <input id="virtual-keyboard" type="checkbox"> + <label for="virtual-keyboard" class="checkboxlabel" + i18n-content="virtualKeyboardOption"> + </label> + </div> </div> diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index db990d85..c09bce9 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js @@ -100,6 +100,8 @@ cr.define('cr.ui.Oobe', function() { Oobe.handleSpokenFeedbackClick); $('screen-magnifier').addEventListener('click', Oobe.handleScreenMagnifierClick); + $('virtual-keyboard').addEventListener('click', + Oobe.handleVirtualKeyboardClick); // A11y menu should be accessible i.e. disable autohide on any // keydown or click inside menu. @@ -163,6 +165,14 @@ cr.define('cr.ui.Oobe', function() { }, /** + * On-screen keyboard checkbox handler. + */ + handleVirtualKeyboardClick: function(e) { + chrome.send('enableVirtualKeyboard', [$('virtual-keyboard').checked]); + e.stopPropagation(); + }, + + /** * Sets usage statistics checkbox. * @param {boolean} checked Is the checkbox checked? */ diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index cb8c0c4..528e430 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html @@ -847,6 +847,22 @@ </span> </div> </div> + <div class="option_name" id="accessibility_onscreen_keyboard"> + <div class="checkbox"> + <span class="controlled-setting-with-label"> + <input id="accessibility-virtual-keyboard-check" + pref="settings.a11y.virtual_keyboard" type="checkbox"> + <span> + <label for="accessibility-virtual-keyboard-check" + i18n-content="accessibilityVirtualKeyboard"> + </label> + <span class="controlled-setting-indicator" + pref="settings.a11y.virtual_keyboard"> + </span> + </span> + </span> + </div> + </div> </section> <if expr="pp_ifdef('chromeos')"> <section id="factory-reset-section" hidden> diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc index 9853ac8..e567dfb 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc @@ -119,6 +119,11 @@ class AccessibilityDelegateImpl : public ash::AccessibilityDelegate { return chromeos::AccessibilityManager::Get()->IsAutoclickEnabled(); } + virtual bool IsVirtualKeyboardEnabled() const OVERRIDE { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsVirtualKeyboardEnabled(); + } + virtual bool ShouldShowAccessibilityMenu() const OVERRIDE { DCHECK(chromeos::AccessibilityManager::Get()); return chromeos::AccessibilityManager::Get()-> diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc index db4feb3..0580ea4 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc @@ -123,6 +123,10 @@ class EmptyAccessibilityDelegate : public ash::AccessibilityDelegate { virtual void SilenceSpokenFeedback() const OVERRIDE { } + virtual bool IsVirtualKeyboardEnabled() const OVERRIDE { + return false; + } + virtual void TriggerAccessibilityAlert( ash::AccessibilityAlert alert) OVERRIDE { } diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc index ebdc893..c8c1cc4 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc @@ -299,6 +299,10 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, this, chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, content::NotificationService::AllSources()); + registrar_->Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + content::NotificationService::AllSources()); } virtual void Initialize() OVERRIDE { @@ -1171,7 +1175,8 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, } case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK: case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE: - case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: { + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD: { AccessibilityStatusEventDetails* accessibility_status = content::Details<AccessibilityStatusEventDetails>(details).ptr(); OnAccessibilityModeChanged(accessibility_status->notify); diff --git a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc index d6b1094..6c6d1c4 100644 --- a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc @@ -79,8 +79,7 @@ void ChromeBrowserMainExtraPartsAsh::PreProfileInit() { // For OS_CHROMEOS, virtual keyboard needs to be initialized before profile // initialized. Otherwise, virtual keyboard extension will not load at login // screen. - if (keyboard::IsKeyboardEnabled()) - keyboard::InitializeKeyboard(); + keyboard::InitializeKeyboard(); #endif #if defined(OS_CHROMEOS) diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index 4d3cba0..9913e09 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc @@ -31,6 +31,7 @@ const char kJsScreenPath[] = "cr.ui.Oobe"; // JS API callbacks names. const char kJsApiEnableHighContrast[] = "enableHighContrast"; +const char kJsApiEnableVirtualKeyboard[] = "enableVirtualKeyboard"; const char kJsApiEnableScreenMagnifier[] = "enableScreenMagnifier"; const char kJsApiEnableLargeCursor[] = "enableLargeCursor"; const char kJsApiEnableSpokenFeedback[] = "enableSpokenFeedback"; @@ -66,6 +67,10 @@ CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui) this, chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_LARGE_CURSOR, content::NotificationService::AllSources()); + registrar_.Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + content::NotificationService::AllSources()); } CoreOobeHandler::~CoreOobeHandler() { @@ -86,6 +91,7 @@ void CoreOobeHandler::DeclareLocalizedValues(LocalizedValuesBuilder* builder) { builder->Add("largeCursorOption", IDS_OOBE_LARGE_CURSOR_OPTION); builder->Add("highContrastOption", IDS_OOBE_HIGH_CONTRAST_MODE_OPTION); builder->Add("screenMagnifierOption", IDS_OOBE_SCREEN_MAGNIFIER_OPTION); + builder->Add("virtualKeyboardOption", IDS_OOBE_VIRTUAL_KEYBOARD_OPTION); // Strings for the device requisition prompt. builder->Add("deviceRequisitionPromptCancel", @@ -126,6 +132,8 @@ void CoreOobeHandler::RegisterMessages() { &CoreOobeHandler::HandleEnableHighContrast); AddCallback(kJsApiEnableLargeCursor, &CoreOobeHandler::HandleEnableLargeCursor); + AddCallback(kJsApiEnableVirtualKeyboard, + &CoreOobeHandler::HandleEnableVirtualKeyboard); AddCallback(kJsApiEnableScreenMagnifier, &CoreOobeHandler::HandleEnableScreenMagnifier); AddCallback(kJsApiEnableSpokenFeedback, @@ -220,6 +228,10 @@ void CoreOobeHandler::HandleEnableLargeCursor(bool enabled) { AccessibilityManager::Get()->EnableLargeCursor(enabled); } +void CoreOobeHandler::HandleEnableVirtualKeyboard(bool enabled) { + AccessibilityManager::Get()->EnableVirtualKeyboard(enabled); +} + void CoreOobeHandler::HandleEnableScreenMagnifier(bool enabled) { // TODO(nkostylev): Add support for partial screen magnifier. DCHECK(MagnificationManager::Get()); @@ -321,7 +333,9 @@ void CoreOobeHandler::Observe(int type, chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE || type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_LARGE_CURSOR || type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER || - type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) { + type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK || + type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD) + { UpdateA11yState(); } else { NOTREACHED() << "Unexpected notification " << type; diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h index 6b4c8df..c60eccc 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h @@ -81,6 +81,7 @@ class CoreOobeHandler : public BaseScreenHandler, // Handlers for JS WebUI messages. void HandleEnableLargeCursor(bool enabled); void HandleEnableHighContrast(bool enabled); + void HandleEnableVirtualKeyboard(bool enabled); void HandleEnableScreenMagnifier(bool enabled); void HandleEnableSpokenFeedback(); void HandleInitialized(); diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 3c29593..5aff591 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -684,6 +684,7 @@ const char kLanguageXkbAutoRepeatInterval[] = // A boolean pref which determines whether the large cursor feature is enabled. const char kLargeCursorEnabled[] = "settings.a11y.large_cursor_enabled"; + // A boolean pref which determines whether the sticky keys feature is enabled. const char kStickyKeysEnabled[] = "settings.a11y.sticky_keys_enabled"; // A boolean pref which determines whether spoken feedback is enabled. @@ -698,8 +699,9 @@ const char kScreenMagnifierEnabled[] = "settings.a11y.screen_magnifier"; const char kScreenMagnifierType[] = "settings.a11y.screen_magnifier_type2"; // A double pref which determines a zooming scale of the screen magnifier. const char kScreenMagnifierScale[] = "settings.a11y.screen_magnifier_scale"; -// A boolean pref which determines whether virtual keyboard is enabled. -// TODO(hashimoto): Remove this pref. +// A boolean pref which determines whether the virtual keyboard is enabled for +// accessibility. This feature is separate from displaying an onscreen keyboard +// due to lack of a physical keyboard. const char kVirtualKeyboardEnabled[] = "settings.a11y.virtual_keyboard"; // A boolean pref which determines whether autoclick is enabled. const char kAutoclickEnabled[] = "settings.a11y.autoclick"; diff --git a/ui/keyboard/keyboard.cc b/ui/keyboard/keyboard.cc index 7825c79..d790127 100644 --- a/ui/keyboard/keyboard.cc +++ b/ui/keyboard/keyboard.cc @@ -65,8 +65,15 @@ class KeyboardWebUIControllerFactory : public content::WebUIControllerFactory { namespace keyboard { +static bool initialized = false; + +void ResetKeyboardForTesting() { + content::WebUIControllerFactory::UnregisterFactoryForTesting( + KeyboardWebUIControllerFactory::GetInstance()); + initialized = false; +} + void InitializeKeyboard() { - static bool initialized = false; if (initialized) return; initialized = true; diff --git a/ui/keyboard/keyboard.h b/ui/keyboard/keyboard.h index ce14a0b..c47cf8c 100644 --- a/ui/keyboard/keyboard.h +++ b/ui/keyboard/keyboard.h @@ -15,6 +15,11 @@ namespace keyboard { // virtual keyboard. This becomes a no-op after the first call. KEYBOARD_EXPORT void InitializeKeyboard(); +// Resets the keyboard to an uninitialized state. Required for +// BrowserWithTestWindowTest tests as they tear down the controller factory +// after each test yet resume testing in the same process. +KEYBOARD_EXPORT void ResetKeyboardForTesting(); + } // namespace keyboard #endif // UI_KEYBOARD_KEYBOARD_H_ diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc index c3b66b5..f31407a 100644 --- a/ui/keyboard/keyboard_util.cc +++ b/ui/keyboard/keyboard_util.cc @@ -35,14 +35,21 @@ void SendProcessKeyEvent(ui::EventType type, base::LazyInstance<base::Time> g_keyboard_load_time_start = LAZY_INSTANCE_INITIALIZER; +bool g_accessibility_keyboard_enabled = false; + } // namespace namespace keyboard { +void SetAccessibilityKeyboardEnabled(bool enabled) { + g_accessibility_keyboard_enabled = enabled; +} + bool IsKeyboardEnabled() { - return CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableVirtualKeyboard) || - IsKeyboardUsabilityExperimentEnabled(); + return g_accessibility_keyboard_enabled || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableVirtualKeyboard) || + IsKeyboardUsabilityExperimentEnabled(); } bool IsKeyboardUsabilityExperimentEnabled() { diff --git a/ui/keyboard/keyboard_util.h b/ui/keyboard/keyboard_util.h index 2321273..148a854 100644 --- a/ui/keyboard/keyboard_util.h +++ b/ui/keyboard/keyboard_util.h @@ -32,6 +32,9 @@ enum KeyboardControlEvent { KEYBOARD_CONTROL_MAX, }; +// Sets the state of the a11y onscreen keyboard. +KEYBOARD_EXPORT void SetAccessibilityKeyboardEnabled(bool enabled); + // Returns true if the virtual keyboard is enabled. KEYBOARD_EXPORT bool IsKeyboardEnabled(); |