1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/audio/sounds.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/autoclick/autoclick_controller.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/high_contrast/high_contrast_controller.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/shell.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/sticky_keys/sticky_keys_controller.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/callback.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/callback_helpers.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/singleton.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/metrics/histogram.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/path_service.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_member.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h"
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_split.h"
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_util.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/time/time.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/values.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/accessibility/accessibility_extension_api.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/lock/screen_locker.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/login_display_host.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/user_manager.h"
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/common/extensions/api/accessibility_private.h"
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/audio/chromeos_sounds.h"
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chromeos/ime/input_method_manager.h"
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/login/login_state.h"
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_accessibility_state.h"
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_details.h"
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/notification_service.h"
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_source.h"
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_contents.h"
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_ui.h"
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "extensions/browser/file_reader.h"
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h"
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "extensions/common/extension_resource.h"
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "grit/browser_resources.h"
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "grit/generated_resources.h"
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "media/audio/sounds/sounds_manager.h"
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/keyboard/keyboard_controller.h"
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/keyboard/keyboard_util.h"
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using content::BrowserThread;
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::RenderViewHost;
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::api::braille_display_private::BrailleController;
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::api::braille_display_private::DisplayState;
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using extensions::api::braille_display_private::KeyEvent;
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace chromeos {
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static chromeos::AccessibilityManager* g_accessibility_manager = NULL;
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static BrailleController* g_braille_controller_for_test = NULL;
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)BrailleController* GetBrailleController() {
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return g_braille_controller_for_test
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ? g_braille_controller_for_test
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : BrailleController::GetInstance();
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::FilePath GetChromeVoxPath() {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath path;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!PathService::Get(chrome::DIR_RESOURCES, &path))
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  path = path.Append(extension_misc::kChromeVoxExtensionPath);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return path;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Helper class that directly loads an extension's content scripts into
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// all of the frames corresponding to a given RenderViewHost.
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ContentScriptLoader {
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Initialize the ContentScriptLoader with the ID of the extension
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and the RenderViewHost where the scripts should be loaded.
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ContentScriptLoader(const std::string& extension_id,
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      int render_process_id,
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      int render_view_id)
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : extension_id_(extension_id),
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_process_id_(render_process_id),
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_view_id_(render_view_id) {}
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Call this once with the ExtensionResource corresponding to each
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // content script to be loaded.
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void AppendScript(extensions::ExtensionResource resource) {
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resources_.push(resource);
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Finally, call this method once to fetch all of the resources and
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // load them. This method will delete this object when done.
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void Run() {
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (resources_.empty()) {
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      delete this;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extensions::ExtensionResource resource = resources_.front();
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resources_.pop();
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<FileReader> reader(new FileReader(resource, base::Bind(
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &ContentScriptLoader::OnFileLoaded, base::Unretained(this))));
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    reader->Start();
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void OnFileLoaded(bool success, const std::string& data) {
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (success) {
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ExtensionMsg_ExecuteCode_Params params;
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.request_id = 0;
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.extension_id = extension_id_;
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.is_javascript = true;
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.code = data;
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.run_at = extensions::UserScript::DOCUMENT_IDLE;
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.all_frames = true;
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      params.match_about_blank = false;
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.in_main_world = false;
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RenderViewHost* render_view_host =
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          RenderViewHost::FromID(render_process_id_, render_view_id_);
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (render_view_host) {
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_view_host->Send(new ExtensionMsg_ExecuteCode(
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            render_view_host->GetRoutingID(), params));
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Run();
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string extension_id_;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int render_process_id_;
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int render_view_id_;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::queue<extensions::ExtensionResource> resources_;
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InjectChromeVoxContentScript(
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ExtensionService* extension_service,
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_view_id,
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb);
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LoadChromeVoxExtension(
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Profile* profile,
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RenderViewHost* render_view_host,
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::Closure done_cb) {
172a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ExtensionService* extension_service =
173a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      extensions::ExtensionSystem::Get(profile)->extension_service();
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host) {
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Wrap the passed in callback to inject the content script.
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    done_cb = base::Bind(
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        &InjectChromeVoxContentScript,
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        extension_service,
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_view_host->GetProcess()->GetID(),
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_view_host->GetRoutingID(),
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        done_cb);
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  extension_service->component_loader()->AddChromeVoxExtension(done_cb);
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InjectChromeVoxContentScript(
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ExtensionService* extension_service,
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_view_id,
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make sure to always run |done_cb|.  ChromeVox was loaded even if we end up
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // not injecting into this particular render view.
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ScopedClosureRunner done_runner(done_cb);
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RenderViewHost* render_view_host =
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      RenderViewHost::FromID(render_process_id, render_view_id);
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!render_view_host)
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const extensions::Extension* extension =
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension_service->extensions()->GetByID(
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          extension_misc::kChromeVoxExtensionId);
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set a flag to tell ChromeVox that it's just been enabled,
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // so that it won't interrupt our speech feedback enabled message.
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ExtensionMsg_ExecuteCode_Params params;
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.request_id = 0;
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.extension_id = extension->id();
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.is_javascript = true;
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.code = "window.INJECTED_AFTER_LOAD = true;";
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.run_at = extensions::UserScript::DOCUMENT_IDLE;
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.all_frames = true;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.match_about_blank = false;
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.in_main_world = false;
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  render_view_host->Send(new ExtensionMsg_ExecuteCode(
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_view_host->GetRoutingID(), params));
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Inject ChromeVox' content scripts.
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ContentScriptLoader* loader = new ContentScriptLoader(
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension->id(), render_view_host->GetProcess()->GetID(),
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_view_host->GetRoutingID());
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const extensions::UserScriptList& content_scripts =
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extensions::ContentScriptsInfo::GetContentScripts(extension);
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < content_scripts.size(); i++) {
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const extensions::UserScript& script = content_scripts[i];
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (size_t j = 0; j < script.js_scripts().size(); ++j) {
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const extensions::UserScript::File &file = script.js_scripts()[j];
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extensions::ExtensionResource resource = extension->GetResource(
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          file.relative_path());
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      loader->AppendScript(resource);
230a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
231a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  loader->Run();  // It cleans itself up when done.
233a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
234a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
235a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid UnloadChromeVoxExtension(Profile* profile) {
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath path = GetChromeVoxPath();
237a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ExtensionService* extension_service =
238a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      extensions::ExtensionSystem::Get(profile)->extension_service();
239a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  extension_service->component_loader()->Remove(path);
240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
241a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// AccessibilityStatusEventDetails
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityStatusEventDetails::AccessibilityStatusEventDetails(
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityNotificationType notification_type,
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify)
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  : notification_type(notification_type),
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    enabled(enabled),
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    magnifier_type(ash::kDefaultMagnifierType),
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    notify(notify) {}
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityStatusEventDetails::AccessibilityStatusEventDetails(
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityNotificationType notification_type,
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::MagnifierType magnifier_type,
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify)
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  : notification_type(notification_type),
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    enabled(enabled),
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    magnifier_type(magnifier_type),
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    notify(notify) {}
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// AccessibilityManager::PrefHandler
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAccessibilityManager::PrefHandler::PrefHandler(const char* pref_path)
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : pref_path_(pref_path) {}
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAccessibilityManager::PrefHandler::~PrefHandler() {}
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AccessibilityManager::PrefHandler::HandleProfileChanged(
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Profile* previous_profile, Profile* current_profile) {
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Returns if the current profile is null.
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!current_profile)
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If the user set a pref value on the login screen and is now starting a
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // session with a new profile, copy the pref value to the profile.
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if ((previous_profile &&
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       ProfileHelper::IsSigninProfile(previous_profile) &&
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       current_profile->IsNewProfile() &&
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       !ProfileHelper::IsSigninProfile(current_profile)) ||
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Special case for Guest mode:
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Guest mode launches a guest-mode browser process before session starts,
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // so the previous profile is null.
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (!previous_profile &&
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       current_profile->IsGuestSession())) {
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Returns if the pref has not been set by the user.
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const PrefService::Preference* pref = ProfileHelper::GetSigninProfile()->
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        GetPrefs()->FindPreference(pref_path_);
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!pref || !pref->IsUserControlled())
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Copy the pref value from the signin screen.
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Value* value_on_login = pref->GetValue();
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PrefService* user_prefs = current_profile->GetPrefs();
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    user_prefs->Set(pref_path_, *value_on_login);
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch///////////////////////////////////////////////////////////////////////////////
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// AccessibilityManager
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Initialize() {
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(g_accessibility_manager == NULL);
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_accessibility_manager = new AccessibilityManager();
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Shutdown() {
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(g_accessibility_manager);
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  delete g_accessibility_manager;
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_accessibility_manager = NULL;
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager* AccessibilityManager::Get() {
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return g_accessibility_manager;
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager::AccessibilityManager()
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : profile_(NULL),
329a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_lock_screen_(false),
330a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_user_screen_(false),
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      large_cursor_pref_handler_(prefs::kAccessibilityLargeCursorEnabled),
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      spoken_feedback_pref_handler_(prefs::kAccessibilitySpokenFeedbackEnabled),
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      high_contrast_pref_handler_(prefs::kAccessibilityHighContrastEnabled),
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      autoclick_pref_handler_(prefs::kAccessibilityAutoclickEnabled),
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      autoclick_delay_pref_handler_(prefs::kAccessibilityAutoclickDelayMs),
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      virtual_keyboard_pref_handler_(
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          prefs::kAccessibilityVirtualKeyboardEnabled),
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      large_cursor_enabled_(false),
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sticky_keys_enabled_(false),
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      spoken_feedback_enabled_(false),
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      high_contrast_enabled_(false),
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      autoclick_enabled_(false),
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      autoclick_delay_ms_(ash::AutoclickController::kDefaultAutoclickDelayMs),
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      virtual_keyboard_enabled_(false),
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      spoken_feedback_notification_(ash::A11Y_NOTIFICATION_NONE),
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_ptr_factory_(this),
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      should_speak_chrome_vox_announcements_on_user_screen_(true),
348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      system_sounds_enabled_(false),
349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      braille_display_connected_(false),
350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      scoped_braille_observer_(this),
351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      braille_ime_current_(false) {
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
353a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              chrome::NOTIFICATION_SESSION_STARTED,
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              chrome::NOTIFICATION_PROFILE_DESTROYED,
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
361a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  notification_registrar_.Add(this,
362a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
363a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              content::NotificationService::AllSources());
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_method::InputMethodManager::Get()->AddObserver(this);
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::SoundsManager* manager = media::SoundsManager::Get();
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(SOUND_SHUTDOWN,
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      bundle.GetRawDataResource(IDR_SOUND_SHUTDOWN_WAV));
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SOUND_SPOKEN_FEEDBACK_ENABLED,
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_ENABLED_WAV));
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SOUND_SPOKEN_FEEDBACK_DISABLED,
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_DISABLED_WAV));
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager::~AccessibilityManager() {
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(this == g_accessibility_manager);
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_MANAGER_SHUTDOWN,
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      false,
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
386effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_method::InputMethodManager::Get()->RemoveObserver(this);
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::ShouldShowAccessibilityMenu() {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If any of the loaded profiles has an accessibility feature turned on - or
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // enforced to always show the menu - we return true to show the menu.
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<Profile*> profiles =
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->profile_manager()->GetLoadedProfiles();
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<Profile*>::iterator it = profiles.begin();
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != profiles.end();
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefService* pref_service = (*it)->GetPrefs();
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pref_service->GetBoolean(prefs::kAccessibilityStickyKeysEnabled) ||
399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityLargeCursorEnabled) ||
400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled) ||
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityHighContrastEnabled) ||
402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityAutoclickEnabled) ||
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pref_service->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu) ||
404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled) ||
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled))
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::ShouldEnableCursorCompositing() {
4120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_CHROMEOS)
4130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!profile_)
4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Enable cursor compositing when one or more of the listed accessibility
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // features are turned on.
418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (pref_service->GetBoolean(prefs::kAccessibilityLargeCursorEnabled) ||
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_service->GetBoolean(prefs::kAccessibilityHighContrastEnabled) ||
420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_service->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled))
4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return true;
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableLargeCursor(bool enabled) {
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
431f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, enabled);
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateLargeCursorFromPref() {
436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const bool enabled =
440f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityLargeCursorEnabled);
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (large_cursor_enabled_ == enabled)
443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  large_cursor_enabled_ = enabled;
446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(USE_ASH)
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Large cursor is implemented only in ash.
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ash::Shell::GetInstance()->cursor_manager()->SetCursorSet(
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      enabled ? ui::CURSOR_SET_LARGE : ui::CURSOR_SET_NORMAL);
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->SetCursorCompositingEnabled(
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShouldEnableCursorCompositing());
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool AccessibilityManager::IsIncognitoAllowed() {
4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  UserManager* user_manager = UserManager::Get();
4680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Supervised users can't create incognito-mode windows.
4690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return !(user_manager->IsLoggedInAsLocallyManagedUser());
4700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsLargeCursorEnabled() {
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return large_cursor_enabled_;
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AccessibilityManager::EnableStickyKeys(bool enabled) {
477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile_)
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityStickyKeysEnabled, enabled);
481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  pref_service->CommitPendingWrite();
482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool AccessibilityManager::IsStickyKeysEnabled() {
485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sticky_keys_enabled_;
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AccessibilityManager::UpdateStickyKeysFromPref() {
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile_)
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const bool enabled =
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityStickyKeysEnabled);
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (sticky_keys_enabled_ == enabled)
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  sticky_keys_enabled_ = enabled;
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(USE_ASH)
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Sticky keys is implemented only in ash.
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->sticky_keys_controller()->Enable(enabled);
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableSpokenFeedback(
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify) {
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled ? ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              : ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK);
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_notification_ = notify;
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
518f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, enabled);
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_notification_ = ash::A11Y_NOTIFICATION_NONE;
522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateSpokenFeedbackFromPref() {
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
528f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
529f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilitySpokenFeedbackEnabled);
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (spoken_feedback_enabled_ == enabled)
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_enabled_ = enabled;
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionAccessibilityEventRouter::GetInstance()->
537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetAccessibilityEnabled(enabled);
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      spoken_feedback_notification_);
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (enabled) {
547a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    LoadChromeVox();
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UnloadChromeVox();
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  UpdateBrailleImeState();
552a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
553a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
554a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::LoadChromeVox() {
555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::Closure done_cb = base::Bind(&AccessibilityManager::PostLoadChromeVox,
556f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     weak_ptr_factory_.GetWeakPtr(),
557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     profile_);
558a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
559a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (screen_locker && screen_locker->locked()) {
560a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // If on the lock screen, loads ChromeVox only to the lock screen as for
561a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // now. On unlock, it will be loaded to the user screen.
562a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // (see. AccessibilityManager::Observe())
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LoadChromeVoxToLockScreen(done_cb);
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LoadChromeVoxToUserScreen(done_cb);
5665e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  }
567a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
568a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
569f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AccessibilityManager::LoadChromeVoxToUserScreen(
570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
571a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_user_screen_)
572a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
573a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
574a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Determine whether an OOBE screen is currently being shown. If so,
575a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // ChromeVox will be injected directly into that screen.
576a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  content::WebUI* login_web_ui = NULL;
577a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
578a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (ProfileHelper::IsSigninProfile(profile_)) {
579a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host();
580a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (login_display_host) {
581a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      WebUILoginView* web_ui_login_view =
582a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          login_display_host->GetWebUILoginView();
583a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if (web_ui_login_view)
584a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        login_web_ui = web_ui_login_view->GetWebUI();
585a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
5860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Lock screen uses the signin progile.
5880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    chrome_vox_loaded_on_lock_screen_ = true;
5895e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  }
5905e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
591a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  chrome_vox_loaded_on_user_screen_ = true;
592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadChromeVoxExtension(
593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_, login_web_ui ?
594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      login_web_ui->GetWebContents()->GetRenderViewHost() : NULL,
595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      done_cb);
596a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AccessibilityManager::LoadChromeVoxToLockScreen(
599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
600a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_lock_screen_)
601a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
602a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
603a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
604a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (screen_locker && screen_locker->locked()) {
605a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    content::WebUI* lock_web_ui = screen_locker->GetAssociatedWebUI();
606a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (lock_web_ui) {
607a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      Profile* profile = Profile::FromWebUI(lock_web_ui);
608a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_lock_screen_ = true;
609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      LoadChromeVoxExtension(
610f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          profile,
611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          lock_web_ui->GetWebContents()->GetRenderViewHost(),
612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          done_cb);
613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
614a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
615a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
616a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
617a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::UnloadChromeVox() {
618a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_lock_screen_)
619a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    UnloadChromeVoxFromLockScreen();
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
621a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_user_screen_) {
622a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    UnloadChromeVoxExtension(profile_);
623a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    chrome_vox_loaded_on_user_screen_ = false;
624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PostUnloadChromeVox(profile_);
627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
629a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::UnloadChromeVoxFromLockScreen() {
630a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Lock screen uses the signin progile.
631a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  Profile* signin_profile = ProfileHelper::GetSigninProfile();
632a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  UnloadChromeVoxExtension(signin_profile);
633a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  chrome_vox_loaded_on_lock_screen_ = false;
634a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
635a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsSpokenFeedbackEnabled() {
637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return spoken_feedback_enabled_;
638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::ToggleSpokenFeedback(
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify) {
6425e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  EnableSpokenFeedback(!IsSpokenFeedbackEnabled(), notify);
643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableHighContrast(bool enabled) {
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityHighContrastEnabled, enabled);
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateHighContrastFromPref() {
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilityHighContrastEnabled);
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (high_contrast_enabled_ == enabled)
662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  high_contrast_enabled_ = enabled;
665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(USE_ASH)
674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ash::Shell::GetInstance()->high_contrast_controller()->SetEnabled(enabled);
675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->SetCursorCompositingEnabled(
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShouldEnableCursorCompositing());
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityManager::OnLocaleChanged() {
6847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!profile_)
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!IsSpokenFeedbackEnabled())
6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the system locale changes and spoken feedback is enabled,
6917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // reload ChromeVox so that it switches its internal translations
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to the new language.
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EnableSpokenFeedback(false, ash::A11Y_NOTIFICATION_NONE);
6947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_NONE);
6957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsHighContrastEnabled() {
698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return high_contrast_enabled_;
699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AccessibilityManager::EnableAutoclick(bool enabled) {
7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!profile_)
7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
706f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityAutoclickEnabled, enabled);
7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  pref_service->CommitPendingWrite();
7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool AccessibilityManager::IsAutoclickEnabled() {
7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return autoclick_enabled_;
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AccessibilityManager::UpdateAutoclickFromPref() {
7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool enabled =
716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityAutoclickEnabled);
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (autoclick_enabled_ == enabled)
7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  autoclick_enabled_ = enabled;
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_ASH)
7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ash::Shell::GetInstance()->autoclick_controller()->SetEnabled(enabled);
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::SetAutoclickDelay(int delay_ms) {
7281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!profile_)
7291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
7301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
732f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetInteger(prefs::kAccessibilityAutoclickDelayMs, delay_ms);
7331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pref_service->CommitPendingWrite();
7341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int AccessibilityManager::GetAutoclickDelay() const {
7371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return autoclick_delay_ms_;
7381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::UpdateAutoclickDelayFromPref() {
7411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int autoclick_delay_ms =
742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetInteger(prefs::kAccessibilityAutoclickDelayMs);
7431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (autoclick_delay_ms == autoclick_delay_ms_)
7451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
7461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  autoclick_delay_ms_ = autoclick_delay_ms;
7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(USE_ASH)
7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ash::Shell::GetInstance()->autoclick_controller()->SetAutoclickDelay(
7501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      autoclick_delay_ms_);
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::EnableVirtualKeyboard(bool enabled) {
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!profile_)
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled,
760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           enabled);
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pref_service->CommitPendingWrite();
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::IsVirtualKeyboardEnabled() {
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return virtual_keyboard_enabled_;
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::UpdateVirtualKeyboardFromPref() {
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!profile_)
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilityVirtualKeyboardEnabled);
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (virtual_keyboard_enabled_ == enabled)
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual_keyboard_enabled_ = enabled;
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_ASH)
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard::SetAccessibilityKeyboardEnabled(enabled);
788010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Note that there are two versions of the on-screen keyboard. A full layout
789010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // is provided for accessibility, which includes sticky modifier keys to
790010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // enable typing of hotkeys. A compact version is used in touchview mode
791010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to provide a layout with larger keys to facilitate touch typing. In the
792010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // event that the a11y keyboard is being disabled, an on-screen keyboard might
793010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // still be enabled and a forced reset is required to pick up the layout
794010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // change.
795010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (keyboard::IsKeyboardEnabled())
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::Shell::GetInstance()->CreateKeyboard();
797010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::Shell::GetInstance()->DeactivateKeyboard();
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
802effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool AccessibilityManager::IsBrailleDisplayConnected() const {
803effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return braille_display_connected_;
804effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
805effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
8061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::CheckBrailleState() {
807effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  BrailleController* braille_controller = GetBrailleController();
808effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!scoped_braille_observer_.IsObserving(braille_controller))
809effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_braille_observer_.Add(braille_controller);
8101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
811effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      BrowserThread::IO,
812effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FROM_HERE,
813effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&BrailleController::GetDisplayState,
814effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 base::Unretained(braille_controller)),
8151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&AccessibilityManager::ReceiveBrailleDisplayState,
8161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
8171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
8181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::ReceiveBrailleDisplayState(
8201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<extensions::api::braille_display_private::DisplayState> state) {
821010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  OnBrailleDisplayStateChanged(*state);
822010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
823010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
824010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::UpdateBrailleImeState() {
825010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!profile_)
826010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
827010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
828010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<std::string> preload_engines;
829010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::SplitString(pref_service->GetString(prefs::kLanguagePreloadEngines),
830010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    ',',
831010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    &preload_engines);
832010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<std::string>::iterator it =
833010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::find(preload_engines.begin(),
834010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                preload_engines.end(),
835010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                extension_misc::kBrailleImeEngineId);
836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool is_enabled = (it != preload_engines.end());
837010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool should_be_enabled =
838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      (spoken_feedback_enabled_ && braille_display_connected_);
839010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (is_enabled == should_be_enabled)
840010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
841010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (should_be_enabled)
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    preload_engines.push_back(extension_misc::kBrailleImeEngineId);
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    preload_engines.erase(it);
845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  pref_service->SetString(prefs::kLanguagePreloadEngines,
846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          JoinString(preload_engines, ','));
847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  braille_ime_current_ = false;
8481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
8491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
850effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Overridden from InputMethodManager::Observer.
851effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AccessibilityManager::InputMethodChanged(
852effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    input_method::InputMethodManager* manager,
853effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool show_message) {
854effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(USE_ASH)
855effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Sticky keys is implemented only in ash.
856effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ash::Shell::GetInstance()->sticky_keys_controller()->SetModifiersEnabled(
857effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      manager->IsISOLevel5ShiftUsedByCurrentInputMethod(),
858effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      manager->IsAltGrUsedByCurrentInputMethod());
859effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const chromeos::input_method::InputMethodDescriptor descriptor =
861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      manager->GetCurrentInputMethod();
862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  braille_ime_current_ =
863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      (descriptor.id() == extension_misc::kBrailleImeEngineId);
864effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
8651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::SetProfile(Profile* profile) {
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_change_registrar_.reset();
8687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  local_state_pref_change_registrar_.reset();
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (profile) {
8717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // TODO(yoshiki): Move following code to PrefHandler.
872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_.reset(new PrefChangeRegistrar);
873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Init(profile->GetPrefs());
874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
875f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityLargeCursorEnabled,
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateLargeCursorFromPref,
877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
879f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityStickyKeysEnabled,
880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&AccessibilityManager::UpdateStickyKeysFromPref,
881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   base::Unretained(this)));
882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    pref_change_registrar_->Add(
883f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilitySpokenFeedbackEnabled,
884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateSpokenFeedbackFromPref,
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
887f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityHighContrastEnabled,
888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateHighContrastFromPref,
889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pref_change_registrar_->Add(
891f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityAutoclickEnabled,
8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateAutoclickFromPref,
8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   base::Unretained(this)));
8941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pref_change_registrar_->Add(
895f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityAutoclickDelayMs,
8961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateAutoclickDelayFromPref,
8971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   base::Unretained(this)));
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    pref_change_registrar_->Add(
899f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityVirtualKeyboardEnabled,
9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateVirtualKeyboardFromPref,
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this)));
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_.reset(new PrefChangeRegistrar);
9047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_->Init(g_browser_process->local_state());
9057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_->Add(
9067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        prefs::kApplicationLocale,
907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&AccessibilityManager::OnLocaleChanged,
9087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   base::Unretained(this)));
9097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::BrowserAccessibilityState::GetInstance()->AddHistogramCallback(
911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            &AccessibilityManager::UpdateChromeOSAccessibilityHistograms,
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            base::Unretained(this)));
914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  large_cursor_pref_handler_.HandleProfileChanged(profile_, profile);
9177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile);
9187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  high_contrast_pref_handler_.HandleProfileChanged(profile_, profile);
9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  autoclick_pref_handler_.HandleProfileChanged(profile_, profile);
9201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile);
9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile);
922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
923effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool had_profile = (profile_ != NULL);
924effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  profile_ = profile;
925effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
926effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!had_profile && profile)
9271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CheckBrailleState();
928010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
929010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UpdateBrailleImeState();
930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateLargeCursorFromPref();
931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UpdateStickyKeysFromPref();
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateSpokenFeedbackFromPref();
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateHighContrastFromPref();
9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAutoclickFromPref();
9351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  UpdateAutoclickDelayFromPref();
9365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateVirtualKeyboardFromPref();
9375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::ActiveUserChanged(const std::string& user_id) {
9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetProfile(ProfileManager::GetActiveUserProfile());
941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::SetProfileForTest(Profile* profile) {
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetProfile(profile);
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::SetBrailleControllerForTest(
9481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    BrailleController* controller) {
9491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_braille_controller_for_test = controller;
9501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
9511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::EnableSystemSounds(bool system_sounds_enabled) {
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  system_sounds_enabled_ = system_sounds_enabled;
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta AccessibilityManager::PlayShutdownSound() {
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!system_sounds_enabled_)
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::TimeDelta();
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  system_sounds_enabled_ = false;
960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ash::PlaySystemSoundIfSpokenFeedback(SOUND_SHUTDOWN))
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::TimeDelta();
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return media::SoundsManager::Get()->GetDuration(SOUND_SHUTDOWN);
9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::InjectChromeVox(RenderViewHost* render_view_host) {
966f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadChromeVoxExtension(profile_, render_view_host, base::Closure());
9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
969a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<AccessibilityStatusSubscription>
970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityManager::RegisterCallback(
971a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        const AccessibilityStatusCallback& cb) {
972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return callback_list_.Add(cb);
973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
974a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
975a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityManager::NotifyAccessibilityStatusChanged(
976a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityStatusEventDetails& details) {
977a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_list_.Notify(details);
978a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateChromeOSAccessibilityHistograms() {
981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosSpokenFeedback",
982868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        IsSpokenFeedbackEnabled());
983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosHighContrast",
984868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        IsHighContrastEnabled());
985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosVirtualKeyboard",
9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        IsVirtualKeyboardEnabled());
9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosStickyKeys", IsStickyKeysEnabled());
988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (MagnificationManager::Get()) {
989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32 type = MagnificationManager::Get()->IsMagnifierEnabled() ?
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      MagnificationManager::Get()->GetMagnifierType() : 0;
991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // '0' means magnifier is disabled.
992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Accessibility.CrosScreenMagnifier",
993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              type,
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              ash::kMaxMagnifierType + 1);
995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
9967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (profile_) {
9977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const PrefService* const prefs = profile_->GetPrefs();
998f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
999f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "Accessibility.CrosLargeCursor",
1000f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs->GetBoolean(prefs::kAccessibilityLargeCursorEnabled));
10017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
10027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "Accessibility.CrosAlwaysShowA11yMenu",
10037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        prefs->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu));
10041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1005f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool autoclick_enabled =
1006f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs->GetBoolean(prefs::kAccessibilityAutoclickEnabled);
10071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosAutoclick", autoclick_enabled);
10081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (autoclick_enabled) {
10091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // We only want to log the autoclick delay if the user has actually
10101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // enabled autoclick.
10111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES(
10121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "Accessibility.CrosAutoclickDelay",
10131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(
1014f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              prefs->GetInteger(prefs::kAccessibilityAutoclickDelayMs)),
10151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(1),
10161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(3000),
10171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          50);
10181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
10197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Observe(
1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int type,
1024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const content::NotificationSource& source,
1025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const content::NotificationDetails& details) {
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
1027a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE: {
10287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when entering the login screen.
10295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Profile* profile = ProfileManager::GetActiveUserProfile();
1030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (ProfileHelper::IsSigninProfile(profile))
1031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetProfile(profile);
1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case chrome::NOTIFICATION_SESSION_STARTED:
10357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when entering a session.
10365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SetProfile(ProfileManager::GetActiveUserProfile());
1037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Ensure ChromeVox makes announcements at the start of new sessions.
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      should_speak_chrome_vox_announcements_on_user_screen_ = true;
10405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Add a session state observer to be able to monitor session changes.
10425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!session_state_observer_.get() && ash::Shell::HasInstance())
10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        session_state_observer_.reset(
10445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new ash::ScopedSessionStateObserver(this));
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case chrome::NOTIFICATION_PROFILE_DESTROYED: {
10477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when exiting a session or shutting down.
10487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      Profile* profile = content::Source<Profile>(source).ptr();
10497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_ == profile)
10507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetProfile(NULL);
1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1053a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: {
1054a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      bool is_screen_locked = *content::Details<bool>(details).ptr();
1055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (spoken_feedback_enabled_) {
1056f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        if (is_screen_locked)
1057f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          LoadChromeVoxToLockScreen(base::Closure());
1058f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // If spoken feedback was enabled, make sure it is also enabled on
1059f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // the user screen.
1060f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // The status tray gets verbalized by user screen ChromeVox, so we need
1061f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // to load it on the user screen even if the screen is locked.
1062f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        LoadChromeVoxToUserScreen(base::Closure());
1063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
1064a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
1065a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1069010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::OnBrailleDisplayStateChanged(
10701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const DisplayState& display_state) {
1071effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  braille_display_connected_ = display_state.available;
1072010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (braille_display_connected_) {
10731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_SHOW);
1074010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1075010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  UpdateBrailleImeState();
1076effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1077effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AccessibilityStatusEventDetails details(
1078effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ACCESSIBILITY_BRAILLE_DISPLAY_CONNECTION_STATE_CHANGED,
1079effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      braille_display_connected_,
1080effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ash::A11Y_NOTIFICATION_SHOW);
1081effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NotifyAccessibilityStatusChanged(details);
10821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1083f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1084010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::OnBrailleKeyEvent(const KeyEvent& event) {
1085010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure the braille IME is active on braille keyboard (dots) input.
1086010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if ((event.command ==
1087010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       extensions::api::braille_display_private::KEY_COMMAND_DOTS) &&
1088010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !braille_ime_current_) {
1089010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    input_method::InputMethodManager::Get()->ChangeInputMethod(
1090010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        extension_misc::kBrailleImeEngineId);
1091010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1092010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1093010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::PostLoadChromeVox(Profile* profile) {
10955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Do any setup work needed immediately after ChromeVox actually loads.
1096a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (system_sounds_enabled_)
1097a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ash::PlaySystemSoundAlways(SOUND_SPOKEN_FEEDBACK_ENABLED);
1098f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1099a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ExtensionAccessibilityEventRouter::GetInstance()->
1100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      OnChromeVoxLoadStateChanged(profile_,
1101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          IsSpokenFeedbackEnabled(),
1102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          chrome_vox_loaded_on_lock_screen_ ||
1103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              should_speak_chrome_vox_announcements_on_user_screen_);
1104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  should_speak_chrome_vox_announcements_on_user_screen_ =
1106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chrome_vox_loaded_on_lock_screen_;
1107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::PostUnloadChromeVox(Profile* profile) {
1110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Do any teardown work needed immediately after ChromeVox actually unloads.
1111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (system_sounds_enabled_)
1112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ash::PlaySystemSoundAlways(SOUND_SPOKEN_FEEDBACK_DISABLED);
1113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace chromeos
1116