Home | History | Annotate | Download | only in accessibility
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_MANAGER_H_
      6 #define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_MANAGER_H_
      7 
      8 #include <set>
      9 
     10 #include "ash/accessibility_delegate.h"
     11 #include "ash/session/session_state_observer.h"
     12 #include "base/callback_forward.h"
     13 #include "base/callback_list.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/prefs/pref_change_registrar.h"
     16 #include "base/scoped_observer.h"
     17 #include "base/time/time.h"
     18 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
     19 #include "chrome/browser/extensions/api/braille_display_private/braille_controller.h"
     20 #include "chromeos/ime/input_method_manager.h"
     21 #include "content/public/browser/notification_observer.h"
     22 #include "content/public/browser/notification_registrar.h"
     23 #include "extensions/browser/event_router.h"
     24 #include "extensions/browser/extension_system.h"
     25 
     26 namespace content {
     27 class RenderViewHost;
     28 }
     29 class Profile;
     30 
     31 namespace chromeos {
     32 
     33 enum AccessibilityNotificationType {
     34   ACCESSIBILITY_MANAGER_SHUTDOWN,
     35   ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
     36   ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
     37   ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
     38   ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
     39   ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
     40   ACCESSIBILITY_BRAILLE_DISPLAY_CONNECTION_STATE_CHANGED
     41 };
     42 
     43 struct AccessibilityStatusEventDetails {
     44   AccessibilityStatusEventDetails(
     45       AccessibilityNotificationType notification_type,
     46       bool enabled,
     47       ash::AccessibilityNotificationVisibility notify);
     48 
     49   AccessibilityStatusEventDetails(
     50       AccessibilityNotificationType notification_type,
     51       bool enabled,
     52       ash::MagnifierType magnifier_type,
     53       ash::AccessibilityNotificationVisibility notify);
     54 
     55   AccessibilityNotificationType notification_type;
     56   bool enabled;
     57   ash::MagnifierType magnifier_type;
     58   ash::AccessibilityNotificationVisibility notify;
     59 };
     60 
     61 typedef base::Callback<void(const AccessibilityStatusEventDetails&)>
     62     AccessibilityStatusCallback;
     63 
     64 typedef base::CallbackList<void(const AccessibilityStatusEventDetails&)>
     65     AccessibilityStatusCallbackList;
     66 
     67 typedef AccessibilityStatusCallbackList::Subscription
     68     AccessibilityStatusSubscription;
     69 
     70 // AccessibilityManager changes the statuses of accessibility features
     71 // watching profile notifications and pref-changes.
     72 // TODO(yoshiki): merge MagnificationManager with AccessibilityManager.
     73 class AccessibilityManager
     74     : public content::NotificationObserver,
     75       public extensions::api::braille_display_private::BrailleObserver,
     76       public input_method::InputMethodManager::Observer,
     77       public ash::SessionStateObserver {
     78  public:
     79   // Creates an instance of AccessibilityManager, this should be called once,
     80   // because only one instance should exist at the same time.
     81   static void Initialize();
     82   // Deletes the existing instance of AccessibilityManager.
     83   static void Shutdown();
     84   // Returns the existing instance. If there is no instance, returns NULL.
     85   static AccessibilityManager* Get();
     86 
     87   // On a user's first login into a device, any a11y features enabled/disabled
     88   // by the user on the login screen are enabled/disabled in the user's profile.
     89   // This class watches for profile changes and copies settings into the user's
     90   // profile when it detects a login with a newly created profile.
     91   class PrefHandler {
     92    public:
     93     explicit PrefHandler(const char* pref_path);
     94     virtual ~PrefHandler();
     95 
     96     // Should be called from AccessibilityManager::SetProfile().
     97     void HandleProfileChanged(Profile* previous_profile,
     98                               Profile* current_profile);
     99 
    100    private:
    101     const char* pref_path_;
    102 
    103     DISALLOW_COPY_AND_ASSIGN(PrefHandler);
    104   };
    105 
    106   // Returns true when the accessibility menu should be shown.
    107   bool ShouldShowAccessibilityMenu();
    108 
    109   // Returns true when cursor compositing should be enabled.
    110   bool ShouldEnableCursorCompositing();
    111 
    112   // Enables or disables the large cursor.
    113   void EnableLargeCursor(bool enabled);
    114   // Returns true if the large cursor is enabled, or false if not.
    115   bool IsLargeCursorEnabled();
    116 
    117   // Enables or disable Sticky Keys.
    118   void EnableStickyKeys(bool enabled);
    119 
    120   // Returns true if Incognito mode is allowed, or false if not.
    121   bool IsIncognitoAllowed();
    122 
    123   // Returns true if the Sticky Keys is enabled, or false if not.
    124   bool IsStickyKeysEnabled();
    125 
    126   // Enables or disables spoken feedback. Enabling spoken feedback installs the
    127   // ChromeVox component extension.
    128   void EnableSpokenFeedback(bool enabled,
    129                             ash::AccessibilityNotificationVisibility notify);
    130 
    131   // Returns true if spoken feedback is enabled, or false if not.
    132   bool IsSpokenFeedbackEnabled();
    133 
    134   // Toggles whether Chrome OS spoken feedback is on or off.
    135   void ToggleSpokenFeedback(ash::AccessibilityNotificationVisibility notify);
    136 
    137   // Enables or disables the high contrast mode for Chrome.
    138   void EnableHighContrast(bool enabled);
    139 
    140   // Returns true if High Contrast is enabled, or false if not.
    141   bool IsHighContrastEnabled();
    142 
    143   // Enables or disables autoclick.
    144   void EnableAutoclick(bool enabled);
    145 
    146   // Returns true if autoclick is enabled.
    147   bool IsAutoclickEnabled();
    148 
    149   // Set the delay for autoclicking after stopping the cursor in milliseconds.
    150   void SetAutoclickDelay(int delay_ms);
    151 
    152   // Returns the autoclick delay in milliseconds.
    153   int GetAutoclickDelay() const;
    154 
    155   // Enables or disables the virtual keyboard.
    156   void EnableVirtualKeyboard(bool enabled);
    157   // Returns true if the virtual keyboard is enabled, otherwise false.
    158   bool IsVirtualKeyboardEnabled();
    159 
    160   // Returns true if a braille display is connected to the system, otherwise
    161   // false.
    162   bool IsBrailleDisplayConnected() const;
    163 
    164   // SessionStateObserver overrides:
    165   virtual void ActiveUserChanged(const std::string& user_id) OVERRIDE;
    166 
    167   void SetProfileForTest(Profile* profile);
    168 
    169   static void SetBrailleControllerForTest(
    170       extensions::api::braille_display_private::BrailleController* controller);
    171 
    172   // Enables/disables system sounds.
    173   void EnableSystemSounds(bool system_sounds_enabled);
    174 
    175   // Initiates play of shutdown sound and returns it's duration.
    176   base::TimeDelta PlayShutdownSound();
    177 
    178   // Injects ChromeVox scripts into given |render_view_host|.
    179   void InjectChromeVox(content::RenderViewHost* render_view_host);
    180 
    181   // Register a callback to be notified when the status of an accessibility
    182   // option changes.
    183   scoped_ptr<AccessibilityStatusSubscription> RegisterCallback(
    184       const AccessibilityStatusCallback& cb);
    185 
    186   // Notify registered callbacks of a status change in an accessibility setting.
    187   void NotifyAccessibilityStatusChanged(
    188       AccessibilityStatusEventDetails& details);
    189 
    190   // Notify accessibility when locale changes occur.
    191   void OnLocaleChanged();
    192 
    193  protected:
    194   AccessibilityManager();
    195   virtual ~AccessibilityManager();
    196 
    197  private:
    198   void LoadChromeVox();
    199   void LoadChromeVoxToUserScreen(const base::Closure& done_cb);
    200   void LoadChromeVoxToLockScreen(const base::Closure& done_cb);
    201   void UnloadChromeVox();
    202   void UnloadChromeVoxFromLockScreen();
    203   void PostLoadChromeVox(Profile* profile);
    204   void PostUnloadChromeVox(Profile* profile);
    205 
    206   void UpdateLargeCursorFromPref();
    207   void UpdateStickyKeysFromPref();
    208   void UpdateSpokenFeedbackFromPref();
    209   void UpdateHighContrastFromPref();
    210   void UpdateAutoclickFromPref();
    211   void UpdateAutoclickDelayFromPref();
    212   void UpdateVirtualKeyboardFromPref();
    213 
    214   void CheckBrailleState();
    215   void ReceiveBrailleDisplayState(
    216       scoped_ptr<extensions::api::braille_display_private::DisplayState> state);
    217   void UpdateBrailleImeState();
    218 
    219   void SetProfile(Profile* profile);
    220 
    221   void UpdateChromeOSAccessibilityHistograms();
    222 
    223   // content::NotificationObserver
    224   virtual void Observe(int type,
    225                        const content::NotificationSource& source,
    226                        const content::NotificationDetails& details) OVERRIDE;
    227 
    228   // extensions::api::braille_display_private::BrailleObserver implementation.
    229   // Enables spoken feedback if a braille display becomes available.
    230   virtual void OnBrailleDisplayStateChanged(
    231       const extensions::api::braille_display_private::DisplayState&
    232           display_state) OVERRIDE;
    233   virtual void OnBrailleKeyEvent(
    234       const extensions::api::braille_display_private::KeyEvent& event) OVERRIDE;
    235 
    236   // InputMethodManager::Observer
    237   virtual void InputMethodChanged(input_method::InputMethodManager* manager,
    238                                   bool show_message) OVERRIDE;
    239 
    240 
    241   // Profile which has the current a11y context.
    242   Profile* profile_;
    243 
    244   // Profile which ChromeVox is currently loaded to. If NULL, ChromeVox is not
    245   // loaded to any profile.
    246   bool chrome_vox_loaded_on_lock_screen_;
    247   bool chrome_vox_loaded_on_user_screen_;
    248 
    249   content::NotificationRegistrar notification_registrar_;
    250   scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
    251   scoped_ptr<PrefChangeRegistrar> local_state_pref_change_registrar_;
    252   scoped_ptr<ash::ScopedSessionStateObserver> session_state_observer_;
    253 
    254   PrefHandler large_cursor_pref_handler_;
    255   PrefHandler spoken_feedback_pref_handler_;
    256   PrefHandler high_contrast_pref_handler_;
    257   PrefHandler autoclick_pref_handler_;
    258   PrefHandler autoclick_delay_pref_handler_;
    259   PrefHandler virtual_keyboard_pref_handler_;
    260 
    261   bool large_cursor_enabled_;
    262   bool sticky_keys_enabled_;
    263   bool spoken_feedback_enabled_;
    264   bool high_contrast_enabled_;
    265   bool autoclick_enabled_;
    266   int autoclick_delay_ms_;
    267   bool virtual_keyboard_enabled_;
    268 
    269   ash::AccessibilityNotificationVisibility spoken_feedback_notification_;
    270 
    271   base::WeakPtrFactory<AccessibilityManager> weak_ptr_factory_;
    272 
    273   bool should_speak_chrome_vox_announcements_on_user_screen_;
    274 
    275   bool system_sounds_enabled_;
    276 
    277   AccessibilityStatusCallbackList callback_list_;
    278 
    279   bool braille_display_connected_;
    280   ScopedObserver<extensions::api::braille_display_private::BrailleController,
    281                  AccessibilityManager> scoped_braille_observer_;
    282 
    283   bool braille_ime_current_;
    284 
    285   DISALLOW_COPY_AND_ASSIGN(AccessibilityManager);
    286 };
    287 
    288 }  // namespace chromeos
    289 
    290 #endif  // CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_MANAGER_H_
    291