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"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
3629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch#include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.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"
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/browser_resources.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/audio/chromeos_sounds.h"
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chromeos/ime/input_method_manager.h"
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/login/login_state.h"
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_accessibility_state.h"
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_details.h"
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/notification_service.h"
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_source.h"
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_contents.h"
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_ui.h"
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "extensions/browser/file_reader.h"
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h"
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "extensions/common/extension_resource.h"
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "media/audio/sounds/sounds_manager.h"
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/keyboard/keyboard_controller.h"
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/keyboard/keyboard_util.h"
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using content::BrowserThread;
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::RenderViewHost;
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::api::braille_display_private::BrailleController;
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::api::braille_display_private::DisplayState;
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using extensions::api::braille_display_private::KeyEvent;
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace chromeos {
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static chromeos::AccessibilityManager* g_accessibility_manager = NULL;
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static BrailleController* g_braille_controller_for_test = NULL;
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)BrailleController* GetBrailleController() {
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return g_braille_controller_for_test
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ? g_braille_controller_for_test
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : BrailleController::GetInstance();
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::FilePath GetChromeVoxPath() {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath path;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!PathService::Get(chrome::DIR_RESOURCES, &path))
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  path = path.Append(extension_misc::kChromeVoxExtensionPath);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return path;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Helper class that directly loads an extension's content scripts into
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// all of the frames corresponding to a given RenderViewHost.
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ContentScriptLoader {
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Initialize the ContentScriptLoader with the ID of the extension
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and the RenderViewHost where the scripts should be loaded.
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ContentScriptLoader(const std::string& extension_id,
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      int render_process_id,
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      int render_view_id)
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : extension_id_(extension_id),
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_process_id_(render_process_id),
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_view_id_(render_view_id) {}
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Call this once with the ExtensionResource corresponding to each
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // content script to be loaded.
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void AppendScript(extensions::ExtensionResource resource) {
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resources_.push(resource);
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Finally, call this method once to fetch all of the resources and
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // load them. This method will delete this object when done.
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void Run() {
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (resources_.empty()) {
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      delete this;
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extensions::ExtensionResource resource = resources_.front();
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resources_.pop();
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<FileReader> reader(new FileReader(resource, base::Bind(
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &ContentScriptLoader::OnFileLoaded, base::Unretained(this))));
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    reader->Start();
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void OnFileLoaded(bool success, const std::string& data) {
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (success) {
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ExtensionMsg_ExecuteCode_Params params;
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.request_id = 0;
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.extension_id = extension_id_;
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.is_javascript = true;
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.code = data;
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.run_at = extensions::UserScript::DOCUMENT_IDLE;
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.all_frames = true;
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      params.match_about_blank = false;
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      params.in_main_world = false;
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RenderViewHost* render_view_host =
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          RenderViewHost::FromID(render_process_id_, render_view_id_);
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (render_view_host) {
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        render_view_host->Send(new ExtensionMsg_ExecuteCode(
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            render_view_host->GetRoutingID(), params));
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Run();
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string extension_id_;
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int render_process_id_;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int render_view_id_;
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::queue<extensions::ExtensionResource> resources_;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InjectChromeVoxContentScript(
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ExtensionService* extension_service,
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_view_id,
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb);
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void LoadChromeVoxExtension(
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Profile* profile,
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RenderViewHost* render_view_host,
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::Closure done_cb) {
171a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ExtensionService* extension_service =
172a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      extensions::ExtensionSystem::Get(profile)->extension_service();
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host) {
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Wrap the passed in callback to inject the content script.
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    done_cb = base::Bind(
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        &InjectChromeVoxContentScript,
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        extension_service,
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_view_host->GetProcess()->GetID(),
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_view_host->GetRoutingID(),
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        done_cb);
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  extension_service->component_loader()->AddChromeVoxExtension(done_cb);
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InjectChromeVoxContentScript(
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ExtensionService* extension_service,
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_view_id,
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make sure to always run |done_cb|.  ChromeVox was loaded even if we end up
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // not injecting into this particular render view.
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ScopedClosureRunner done_runner(done_cb);
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RenderViewHost* render_view_host =
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      RenderViewHost::FromID(render_process_id, render_view_id);
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!render_view_host)
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const extensions::Extension* extension =
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension_service->extensions()->GetByID(
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          extension_misc::kChromeVoxExtensionId);
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set a flag to tell ChromeVox that it's just been enabled,
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // so that it won't interrupt our speech feedback enabled message.
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ExtensionMsg_ExecuteCode_Params params;
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.request_id = 0;
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.extension_id = extension->id();
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.is_javascript = true;
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.code = "window.INJECTED_AFTER_LOAD = true;";
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.run_at = extensions::UserScript::DOCUMENT_IDLE;
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.all_frames = true;
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.match_about_blank = false;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  params.in_main_world = false;
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  render_view_host->Send(new ExtensionMsg_ExecuteCode(
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_view_host->GetRoutingID(), params));
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Inject ChromeVox' content scripts.
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ContentScriptLoader* loader = new ContentScriptLoader(
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension->id(), render_view_host->GetProcess()->GetID(),
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_view_host->GetRoutingID());
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const extensions::UserScriptList& content_scripts =
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extensions::ContentScriptsInfo::GetContentScripts(extension);
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < content_scripts.size(); i++) {
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const extensions::UserScript& script = content_scripts[i];
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (size_t j = 0; j < script.js_scripts().size(); ++j) {
2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const extensions::UserScript::File& file = script.js_scripts()[j];
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extensions::ExtensionResource resource = extension->GetResource(
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          file.relative_path());
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      loader->AppendScript(resource);
229a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
230a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  loader->Run();  // It cleans itself up when done.
232a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
233a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
234a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid UnloadChromeVoxExtension(Profile* profile) {
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath path = GetChromeVoxPath();
236a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ExtensionService* extension_service =
237a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      extensions::ExtensionSystem::Get(profile)->extension_service();
238a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  extension_service->component_loader()->Remove(path);
239a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// AccessibilityStatusEventDetails
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityStatusEventDetails::AccessibilityStatusEventDetails(
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityNotificationType notification_type,
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify)
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  : notification_type(notification_type),
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    enabled(enabled),
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    magnifier_type(ash::kDefaultMagnifierType),
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    notify(notify) {}
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityStatusEventDetails::AccessibilityStatusEventDetails(
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityNotificationType notification_type,
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::MagnifierType magnifier_type,
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify)
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  : notification_type(notification_type),
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    enabled(enabled),
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    magnifier_type(magnifier_type),
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    notify(notify) {}
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// AccessibilityManager::PrefHandler
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAccessibilityManager::PrefHandler::PrefHandler(const char* pref_path)
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : pref_path_(pref_path) {}
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAccessibilityManager::PrefHandler::~PrefHandler() {}
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AccessibilityManager::PrefHandler::HandleProfileChanged(
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Profile* previous_profile, Profile* current_profile) {
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Returns if the current profile is null.
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!current_profile)
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If the user set a pref value on the login screen and is now starting a
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // session with a new profile, copy the pref value to the profile.
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if ((previous_profile &&
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       ProfileHelper::IsSigninProfile(previous_profile) &&
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       current_profile->IsNewProfile() &&
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       !ProfileHelper::IsSigninProfile(current_profile)) ||
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Special case for Guest mode:
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Guest mode launches a guest-mode browser process before session starts,
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // so the previous profile is null.
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (!previous_profile &&
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       current_profile->IsGuestSession())) {
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Returns if the pref has not been set by the user.
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const PrefService::Preference* pref = ProfileHelper::GetSigninProfile()->
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        GetPrefs()->FindPreference(pref_path_);
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!pref || !pref->IsUserControlled())
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return;
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Copy the pref value from the signin screen.
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Value* value_on_login = pref->GetValue();
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PrefService* user_prefs = current_profile->GetPrefs();
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    user_prefs->Set(pref_path_, *value_on_login);
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch///////////////////////////////////////////////////////////////////////////////
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// AccessibilityManager
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Initialize() {
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(g_accessibility_manager == NULL);
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_accessibility_manager = new AccessibilityManager();
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Shutdown() {
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(g_accessibility_manager);
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  delete g_accessibility_manager;
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_accessibility_manager = NULL;
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager* AccessibilityManager::Get() {
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return g_accessibility_manager;
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager::AccessibilityManager()
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : profile_(NULL),
328a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_lock_screen_(false),
329a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_user_screen_(false),
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      large_cursor_pref_handler_(prefs::kAccessibilityLargeCursorEnabled),
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      spoken_feedback_pref_handler_(prefs::kAccessibilitySpokenFeedbackEnabled),
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      high_contrast_pref_handler_(prefs::kAccessibilityHighContrastEnabled),
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      autoclick_pref_handler_(prefs::kAccessibilityAutoclickEnabled),
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      autoclick_delay_pref_handler_(prefs::kAccessibilityAutoclickDelayMs),
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      virtual_keyboard_pref_handler_(
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          prefs::kAccessibilityVirtualKeyboardEnabled),
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      large_cursor_enabled_(false),
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sticky_keys_enabled_(false),
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      spoken_feedback_enabled_(false),
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      high_contrast_enabled_(false),
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      autoclick_enabled_(false),
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      autoclick_delay_ms_(ash::AutoclickController::kDefaultAutoclickDelayMs),
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      virtual_keyboard_enabled_(false),
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      spoken_feedback_notification_(ash::A11Y_NOTIFICATION_NONE),
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      should_speak_chrome_vox_announcements_on_user_screen_(true),
346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      system_sounds_enabled_(false),
347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      braille_display_connected_(false),
348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      scoped_braille_observer_(this),
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      braille_ime_current_(false),
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
352a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              chrome::NOTIFICATION_SESSION_STARTED,
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notification_registrar_.Add(this,
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              chrome::NOTIFICATION_PROFILE_DESTROYED,
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              content::NotificationService::AllSources());
360a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  notification_registrar_.Add(this,
361a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
362a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                              content::NotificationService::AllSources());
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_method::InputMethodManager::Get()->AddObserver(this);
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::SoundsManager* manager = media::SoundsManager::Get();
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(SOUND_SHUTDOWN,
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      bundle.GetRawDataResource(IDR_SOUND_SHUTDOWN_WAV));
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SOUND_SPOKEN_FEEDBACK_ENABLED,
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_ENABLED_WAV));
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager->Initialize(
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SOUND_SPOKEN_FEEDBACK_DISABLED,
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_DISABLED_WAV));
3766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager->Initialize(SOUND_PASSTHROUGH,
3776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      bundle.GetRawDataResource(IDR_SOUND_PASSTHROUGH_WAV));
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager->Initialize(SOUND_EXIT_SCREEN,
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      bundle.GetRawDataResource(IDR_SOUND_EXIT_SCREEN_WAV));
3806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager->Initialize(SOUND_ENTER_SCREEN,
3816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      bundle.GetRawDataResource(IDR_SOUND_ENTER_SCREEN_WAV));
382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AccessibilityManager::~AccessibilityManager() {
385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(this == g_accessibility_manager);
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_MANAGER_SHUTDOWN,
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      false,
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_method::InputMethodManager::Get()->RemoveObserver(this);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::ShouldShowAccessibilityMenu() {
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If any of the loaded profiles has an accessibility feature turned on - or
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // enforced to always show the menu - we return true to show the menu.
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<Profile*> profiles =
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->profile_manager()->GetLoadedProfiles();
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<Profile*>::iterator it = profiles.begin();
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != profiles.end();
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefService* pref_service = (*it)->GetPrefs();
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pref_service->GetBoolean(prefs::kAccessibilityStickyKeysEnabled) ||
404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityLargeCursorEnabled) ||
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled) ||
406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityHighContrastEnabled) ||
407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityAutoclickEnabled) ||
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pref_service->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu) ||
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled) ||
410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_service->GetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled))
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::ShouldEnableCursorCompositing() {
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_CHROMEOS)
4180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!profile_)
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Enable cursor compositing when one or more of the listed accessibility
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // features are turned on.
423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (pref_service->GetBoolean(prefs::kAccessibilityLargeCursorEnabled) ||
424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_service->GetBoolean(prefs::kAccessibilityHighContrastEnabled) ||
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_service->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled))
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return true;
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableLargeCursor(bool enabled) {
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, enabled);
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateLargeCursorFromPref() {
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const bool enabled =
445f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityLargeCursorEnabled);
446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (large_cursor_enabled_ == enabled)
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  large_cursor_enabled_ = enabled;
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // crbug.com/408733 (and for all USE_ATHENA in this file)
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(USE_ASH)
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Large cursor is implemented only in ash.
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ash::Shell::GetInstance()->cursor_manager()->SetCursorSet(
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      enabled ? ui::CURSOR_SET_LARGE : ui::CURSOR_SET_NORMAL);
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->SetCursorCompositingEnabled(
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShouldEnableCursorCompositing());
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // !USE_ATHENA
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool AccessibilityManager::IsIncognitoAllowed() {
4760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Supervised users can't create incognito-mode windows.
4776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !(user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser());
4780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsLargeCursorEnabled() {
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return large_cursor_enabled_;
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AccessibilityManager::EnableStickyKeys(bool enabled) {
485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile_)
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityStickyKeysEnabled, enabled);
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  pref_service->CommitPendingWrite();
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool AccessibilityManager::IsStickyKeysEnabled() {
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sticky_keys_enabled_;
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AccessibilityManager::UpdateStickyKeysFromPref() {
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!profile_)
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const bool enabled =
501f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityStickyKeysEnabled);
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (sticky_keys_enabled_ == enabled)
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  sticky_keys_enabled_ = enabled;
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA)
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->sticky_keys_controller()->Enable(enabled);
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableSpokenFeedback(
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool enabled,
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify) {
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled ? ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              : ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK);
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_notification_ = notify;
524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
526f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, enabled);
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_notification_ = ash::A11Y_NOTIFICATION_NONE;
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateSpokenFeedbackFromPref() {
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
536f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilitySpokenFeedbackEnabled);
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (spoken_feedback_enabled_ == enabled)
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  spoken_feedback_enabled_ = enabled;
543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionAccessibilityEventRouter::GetInstance()->
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetAccessibilityEnabled(enabled);
546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      spoken_feedback_notification_);
551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (enabled) {
555a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    LoadChromeVox();
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UnloadChromeVox();
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  UpdateBrailleImeState();
560a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
561a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
562a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::LoadChromeVox() {
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::Closure done_cb = base::Bind(&AccessibilityManager::PostLoadChromeVox,
564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     weak_ptr_factory_.GetWeakPtr(),
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     profile_);
566a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
567a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (screen_locker && screen_locker->locked()) {
568a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // If on the lock screen, loads ChromeVox only to the lock screen as for
569a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // now. On unlock, it will be loaded to the user screen.
570a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // (see. AccessibilityManager::Observe())
571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LoadChromeVoxToLockScreen(done_cb);
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LoadChromeVoxToUserScreen(done_cb);
5745e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  }
575a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
576a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AccessibilityManager::LoadChromeVoxToUserScreen(
578f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
579a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_user_screen_)
580a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
581a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
582a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Determine whether an OOBE screen is currently being shown. If so,
583a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // ChromeVox will be injected directly into that screen.
584a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  content::WebUI* login_web_ui = NULL;
585a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
586a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (ProfileHelper::IsSigninProfile(profile_)) {
587a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host();
588a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (login_display_host) {
589a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      WebUILoginView* web_ui_login_view =
590a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          login_display_host->GetWebUILoginView();
591a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if (web_ui_login_view)
592a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        login_web_ui = web_ui_login_view->GetWebUI();
593a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Lock screen uses the signin progile.
5960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    chrome_vox_loaded_on_lock_screen_ = true;
5975e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  }
5985e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
599a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  chrome_vox_loaded_on_user_screen_ = true;
600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadChromeVoxExtension(
601f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_, login_web_ui ?
602f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      login_web_ui->GetWebContents()->GetRenderViewHost() : NULL,
603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      done_cb);
604a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AccessibilityManager::LoadChromeVoxToLockScreen(
607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
608a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_lock_screen_)
609a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
610a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
611a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
612a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (screen_locker && screen_locker->locked()) {
613a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    content::WebUI* lock_web_ui = screen_locker->GetAssociatedWebUI();
614a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (lock_web_ui) {
615a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      Profile* profile = Profile::FromWebUI(lock_web_ui);
616a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      chrome_vox_loaded_on_lock_screen_ = true;
617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      LoadChromeVoxExtension(
618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          profile,
619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          lock_web_ui->GetWebContents()->GetRenderViewHost(),
620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          done_cb);
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
622a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
623a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
624a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
625a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::UnloadChromeVox() {
626a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_lock_screen_)
627a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    UnloadChromeVoxFromLockScreen();
628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
629a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (chrome_vox_loaded_on_user_screen_) {
630a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    UnloadChromeVoxExtension(profile_);
631a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    chrome_vox_loaded_on_user_screen_ = false;
632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PostUnloadChromeVox(profile_);
635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
637a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AccessibilityManager::UnloadChromeVoxFromLockScreen() {
638a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Lock screen uses the signin progile.
639a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  Profile* signin_profile = ProfileHelper::GetSigninProfile();
640a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  UnloadChromeVoxExtension(signin_profile);
641a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  chrome_vox_loaded_on_lock_screen_ = false;
642a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
643a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsSpokenFeedbackEnabled() {
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return spoken_feedback_enabled_;
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::ToggleSpokenFeedback(
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::AccessibilityNotificationVisibility notify) {
6505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  EnableSpokenFeedback(!IsSpokenFeedbackEnabled(), notify);
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::EnableHighContrast(bool enabled) {
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityHighContrastEnabled, enabled);
659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_service->CommitPendingWrite();
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateHighContrastFromPref() {
663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!profile_)
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilityHighContrastEnabled);
668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (high_contrast_enabled_ == enabled)
670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  high_contrast_enabled_ = enabled;
673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(USE_ASH)
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ash::Shell::GetInstance()->high_contrast_controller()->SetEnabled(enabled);
685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->SetCursorCompositingEnabled(
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShouldEnableCursorCompositing());
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityManager::OnLocaleChanged() {
6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!profile_)
6977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!IsSpokenFeedbackEnabled())
7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
7017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the system locale changes and spoken feedback is enabled,
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // reload ChromeVox so that it switches its internal translations
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to the new language.
7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EnableSpokenFeedback(false, ash::A11Y_NOTIFICATION_NONE);
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_NONE);
7076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
7086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void AccessibilityManager::PlayEarcon(int sound_key) {
7106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(sound_key < chromeos::SOUND_COUNT);
7116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ash::PlaySystemSoundIfSpokenFeedback(sound_key);
7127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
7137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccessibilityManager::IsHighContrastEnabled() {
715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return high_contrast_enabled_;
716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AccessibilityManager::EnableAutoclick(bool enabled) {
7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!profile_)
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
723f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityAutoclickEnabled, enabled);
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  pref_service->CommitPendingWrite();
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool AccessibilityManager::IsAutoclickEnabled() {
7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return autoclick_enabled_;
7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AccessibilityManager::UpdateAutoclickFromPref() {
7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool enabled =
733f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityAutoclickEnabled);
7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (autoclick_enabled_ == enabled)
7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  autoclick_enabled_ = enabled;
7384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA)
7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ash::Shell::GetInstance()->autoclick_controller()->SetEnabled(enabled);
7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::SetAutoclickDelay(int delay_ms) {
7451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!profile_)
7461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetInteger(prefs::kAccessibilityAutoclickDelayMs, delay_ms);
7501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pref_service->CommitPendingWrite();
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int AccessibilityManager::GetAutoclickDelay() const {
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return autoclick_delay_ms_;
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::UpdateAutoclickDelayFromPref() {
7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int autoclick_delay_ms =
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetInteger(prefs::kAccessibilityAutoclickDelayMs);
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (autoclick_delay_ms == autoclick_delay_ms_)
7621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  autoclick_delay_ms_ = autoclick_delay_ms;
7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA)
7661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ash::Shell::GetInstance()->autoclick_controller()->SetAutoclickDelay(
7671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      autoclick_delay_ms_);
7681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::EnableVirtualKeyboard(bool enabled) {
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!profile_)
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_service->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled,
777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           enabled);
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pref_service->CommitPendingWrite();
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccessibilityManager::IsVirtualKeyboardEnabled() {
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return virtual_keyboard_enabled_;
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::UpdateVirtualKeyboardFromPref() {
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!profile_)
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
789f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const bool enabled = profile_->GetPrefs()->GetBoolean(
790f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kAccessibilityVirtualKeyboardEnabled);
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (virtual_keyboard_enabled_ == enabled)
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual_keyboard_enabled_ = enabled;
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AccessibilityStatusEventDetails details(
797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD,
798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      enabled,
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ash::A11Y_NOTIFICATION_NONE);
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyAccessibilityStatusChanged(details);
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA)
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard::SetAccessibilityKeyboardEnabled(enabled);
805010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Note that there are two versions of the on-screen keyboard. A full layout
806010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // is provided for accessibility, which includes sticky modifier keys to
807010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // enable typing of hotkeys. A compact version is used in touchview mode
808010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to provide a layout with larger keys to facilitate touch typing. In the
809010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // event that the a11y keyboard is being disabled, an on-screen keyboard might
810010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // still be enabled and a forced reset is required to pick up the layout
811010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // change.
812010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (keyboard::IsKeyboardEnabled())
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::Shell::GetInstance()->CreateKeyboard();
814010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::Shell::GetInstance()->DeactivateKeyboard();
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
819effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool AccessibilityManager::IsBrailleDisplayConnected() const {
820effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return braille_display_connected_;
821effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
822effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
8231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::CheckBrailleState() {
824effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  BrailleController* braille_controller = GetBrailleController();
825effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!scoped_braille_observer_.IsObserving(braille_controller))
826effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_braille_observer_.Add(braille_controller);
8271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
828effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      BrowserThread::IO,
829effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FROM_HERE,
830effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&BrailleController::GetDisplayState,
831effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 base::Unretained(braille_controller)),
8321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&AccessibilityManager::ReceiveBrailleDisplayState,
8331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
8351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::ReceiveBrailleDisplayState(
8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<extensions::api::braille_display_private::DisplayState> state) {
838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  OnBrailleDisplayStateChanged(*state);
839010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
840010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
841010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::UpdateBrailleImeState() {
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!profile_)
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  PrefService* pref_service = profile_->GetPrefs();
845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<std::string> preload_engines;
846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::SplitString(pref_service->GetString(prefs::kLanguagePreloadEngines),
847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    ',',
848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    &preload_engines);
849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<std::string>::iterator it =
850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::find(preload_engines.begin(),
851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                preload_engines.end(),
852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                extension_misc::kBrailleImeEngineId);
853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool is_enabled = (it != preload_engines.end());
854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool should_be_enabled =
855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      (spoken_feedback_enabled_ && braille_display_connected_);
856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (is_enabled == should_be_enabled)
857010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (should_be_enabled)
859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    preload_engines.push_back(extension_misc::kBrailleImeEngineId);
860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    preload_engines.erase(it);
862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  pref_service->SetString(prefs::kLanguagePreloadEngines,
863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          JoinString(preload_engines, ','));
864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  braille_ime_current_ = false;
8651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
8661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
867effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Overridden from InputMethodManager::Observer.
868effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AccessibilityManager::InputMethodChanged(
869effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    input_method::InputMethodManager* manager,
870effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool show_message) {
8711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH) && !defined(USE_ATHENA)
872effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Sticky keys is implemented only in ash.
8731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(dpolukhin): support Athena, crbug.com/408733.
874effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ash::Shell::GetInstance()->sticky_keys_controller()->SetModifiersEnabled(
875effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      manager->IsISOLevel5ShiftUsedByCurrentInputMethod(),
876effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      manager->IsAltGrUsedByCurrentInputMethod());
877effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const chromeos::input_method::InputMethodDescriptor descriptor =
87903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      manager->GetActiveIMEState()->GetCurrentInputMethod();
880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  braille_ime_current_ =
881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      (descriptor.id() == extension_misc::kBrailleImeEngineId);
882effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
8831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::SetProfile(Profile* profile) {
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  pref_change_registrar_.reset();
8867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  local_state_pref_change_registrar_.reset();
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (profile) {
8897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // TODO(yoshiki): Move following code to PrefHandler.
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_.reset(new PrefChangeRegistrar);
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Init(profile->GetPrefs());
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
893f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityLargeCursorEnabled,
894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateLargeCursorFromPref,
895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
897f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityStickyKeysEnabled,
898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&AccessibilityManager::UpdateStickyKeysFromPref,
899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   base::Unretained(this)));
900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    pref_change_registrar_->Add(
901f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilitySpokenFeedbackEnabled,
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateSpokenFeedbackFromPref,
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pref_change_registrar_->Add(
905f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityHighContrastEnabled,
906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateHighContrastFromPref,
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   base::Unretained(this)));
9084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pref_change_registrar_->Add(
909f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityAutoclickEnabled,
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateAutoclickFromPref,
9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   base::Unretained(this)));
9121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pref_change_registrar_->Add(
913f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityAutoclickDelayMs,
9141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateAutoclickDelayFromPref,
9151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   base::Unretained(this)));
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    pref_change_registrar_->Add(
917f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kAccessibilityVirtualKeyboardEnabled,
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&AccessibilityManager::UpdateVirtualKeyboardFromPref,
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this)));
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_.reset(new PrefChangeRegistrar);
9227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_->Init(g_browser_process->local_state());
9237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    local_state_pref_change_registrar_->Add(
9247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        prefs::kApplicationLocale,
925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&AccessibilityManager::OnLocaleChanged,
9267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   base::Unretained(this)));
9277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::BrowserAccessibilityState::GetInstance()->AddHistogramCallback(
929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(
930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            &AccessibilityManager::UpdateChromeOSAccessibilityHistograms,
931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            base::Unretained(this)));
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  large_cursor_pref_handler_.HandleProfileChanged(profile_, profile);
9357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile);
9367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  high_contrast_pref_handler_.HandleProfileChanged(profile_, profile);
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  autoclick_pref_handler_.HandleProfileChanged(profile_, profile);
9381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile);
9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile);
940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
941effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool had_profile = (profile_ != NULL);
942effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  profile_ = profile;
943effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
944effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!had_profile && profile)
9451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CheckBrailleState();
946010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  else
947010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UpdateBrailleImeState();
948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateLargeCursorFromPref();
949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UpdateStickyKeysFromPref();
950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateSpokenFeedbackFromPref();
951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UpdateHighContrastFromPref();
9524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAutoclickFromPref();
9531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  UpdateAutoclickDelayFromPref();
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateVirtualKeyboardFromPref();
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::ActiveUserChanged(const std::string& user_id) {
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetProfile(ProfileManager::GetActiveUserProfile());
959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::SetProfileForTest(Profile* profile) {
962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetProfile(profile);
963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccessibilityManager::SetBrailleControllerForTest(
9661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    BrailleController* controller) {
9671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_braille_controller_for_test = controller;
9681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
9691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::EnableSystemSounds(bool system_sounds_enabled) {
9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  system_sounds_enabled_ = system_sounds_enabled;
9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta AccessibilityManager::PlayShutdownSound() {
9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!system_sounds_enabled_)
9765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::TimeDelta();
9775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  system_sounds_enabled_ = false;
9781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ash::PlaySystemSoundIfSpokenFeedback(SOUND_SHUTDOWN))
9805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::TimeDelta();
9811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return media::SoundsManager::Get()->GetDuration(SOUND_SHUTDOWN);
9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::InjectChromeVox(RenderViewHost* render_view_host) {
986f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadChromeVoxExtension(profile_, render_view_host, base::Closure());
9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<AccessibilityStatusSubscription>
990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityManager::RegisterCallback(
991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        const AccessibilityStatusCallback& cb) {
992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return callback_list_.Add(cb);
993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityManager::NotifyAccessibilityStatusChanged(
996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AccessibilityStatusEventDetails& details) {
997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_list_.Notify(details);
998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::UpdateChromeOSAccessibilityHistograms() {
1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosSpokenFeedback",
1002868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        IsSpokenFeedbackEnabled());
1003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosHighContrast",
1004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        IsHighContrastEnabled());
1005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosVirtualKeyboard",
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        IsVirtualKeyboardEnabled());
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosStickyKeys", IsStickyKeysEnabled());
1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (MagnificationManager::Get()) {
1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32 type = MagnificationManager::Get()->IsMagnifierEnabled() ?
1010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      MagnificationManager::Get()->GetMagnifierType() : 0;
1011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // '0' means magnifier is disabled.
1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Accessibility.CrosScreenMagnifier",
1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              type,
1014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              ash::kMaxMagnifierType + 1);
1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
10167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (profile_) {
10177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const PrefService* const prefs = profile_->GetPrefs();
1018f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
1019f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "Accessibility.CrosLargeCursor",
1020f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs->GetBoolean(prefs::kAccessibilityLargeCursorEnabled));
10217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
10227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "Accessibility.CrosAlwaysShowA11yMenu",
10237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        prefs->GetBoolean(prefs::kShouldAlwaysShowAccessibilityMenu));
10241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1025f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool autoclick_enabled =
1026f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs->GetBoolean(prefs::kAccessibilityAutoclickEnabled);
10271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosAutoclick", autoclick_enabled);
10281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (autoclick_enabled) {
10291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // We only want to log the autoclick delay if the user has actually
10301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // enabled autoclick.
10311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES(
10321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "Accessibility.CrosAutoclickDelay",
10331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(
1034f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              prefs->GetInteger(prefs::kAccessibilityAutoclickDelayMs)),
10351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(1),
10361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(3000),
10371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          50);
10381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
10397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccessibilityManager::Observe(
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int type,
1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const content::NotificationSource& source,
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const content::NotificationDetails& details) {
1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
1047a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE: {
10487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when entering the login screen.
10495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Profile* profile = ProfileManager::GetActiveUserProfile();
1050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (ProfileHelper::IsSigninProfile(profile))
1051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetProfile(profile);
1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
10547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case chrome::NOTIFICATION_SESSION_STARTED:
10557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when entering a session.
10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SetProfile(ProfileManager::GetActiveUserProfile());
1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Ensure ChromeVox makes announcements at the start of new sessions.
1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      should_speak_chrome_vox_announcements_on_user_screen_ = true;
10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Add a session state observer to be able to monitor session changes.
10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!session_state_observer_.get() && ash::Shell::HasInstance())
10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        session_state_observer_.reset(
10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new ash::ScopedSessionStateObserver(this));
1065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case chrome::NOTIFICATION_PROFILE_DESTROYED: {
10677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Update |profile_| when exiting a session or shutting down.
10687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      Profile* profile = content::Source<Profile>(source).ptr();
10697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_ == profile)
10707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetProfile(NULL);
1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1073a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: {
1074a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      bool is_screen_locked = *content::Details<bool>(details).ptr();
1075a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (spoken_feedback_enabled_) {
1076f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        if (is_screen_locked)
1077f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          LoadChromeVoxToLockScreen(base::Closure());
1078f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // If spoken feedback was enabled, make sure it is also enabled on
1079f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // the user screen.
1080f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // The status tray gets verbalized by user screen ChromeVox, so we need
1081f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        // to load it on the user screen even if the screen is locked.
1082f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        LoadChromeVoxToUserScreen(base::Closure());
1083a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
1084a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
1085a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1089010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::OnBrailleDisplayStateChanged(
10901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const DisplayState& display_state) {
1091effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  braille_display_connected_ = display_state.available;
1092010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (braille_display_connected_) {
10931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_SHOW);
1094010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1095010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  UpdateBrailleImeState();
1096effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1097effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  AccessibilityStatusEventDetails details(
1098effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ACCESSIBILITY_BRAILLE_DISPLAY_CONNECTION_STATE_CHANGED,
1099effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      braille_display_connected_,
1100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ash::A11Y_NOTIFICATION_SHOW);
1101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NotifyAccessibilityStatusChanged(details);
11021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityManager::OnBrailleKeyEvent(const KeyEvent& event) {
1105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure the braille IME is active on braille keyboard (dots) input.
1106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if ((event.command ==
1107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       extensions::api::braille_display_private::KEY_COMMAND_DOTS) &&
1108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !braille_ime_current_) {
110903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    input_method::InputMethodManager::Get()
111003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ->GetActiveIMEState()
111103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ->ChangeInputMethod(extension_misc::kBrailleImeEngineId,
111203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            false /* show_message */);
1113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
11165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::PostLoadChromeVox(Profile* profile) {
11175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Do any setup work needed immediately after ChromeVox actually loads.
1118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (system_sounds_enabled_)
1119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ash::PlaySystemSoundAlways(SOUND_SPOKEN_FEEDBACK_ENABLED);
1120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ExtensionAccessibilityEventRouter::GetInstance()->
1122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      OnChromeVoxLoadStateChanged(profile_,
1123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          IsSpokenFeedbackEnabled(),
1124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          chrome_vox_loaded_on_lock_screen_ ||
1125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              should_speak_chrome_vox_announcements_on_user_screen_);
1126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  should_speak_chrome_vox_announcements_on_user_screen_ =
1128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chrome_vox_loaded_on_lock_screen_;
1129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccessibilityManager::PostUnloadChromeVox(Profile* profile) {
1132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Do any teardown work needed immediately after ChromeVox actually unloads.
1133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (system_sounds_enabled_)
1134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ash::PlaySystemSoundAlways(SOUND_SPOKEN_FEEDBACK_DISABLED);
113529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  // Clear the accessibility focus ring.
113629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  AccessibilityFocusRingController::GetInstance()->SetFocusRing(
113729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch      std::vector<gfx::Rect>());
1138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace chromeos
1141