Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: chrome/browser/chromeos/accessibility/accessibility_manager.cc

Issue 2212863002: Factor the extension loading code out of AccessibilityManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_load_chromevox
Patch Set: Rebased and updated Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 5 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 16 matching lines...) Expand all
27 #include "base/memory/singleton.h" 27 #include "base/memory/singleton.h"
28 #include "base/metrics/histogram_macros.h" 28 #include "base/metrics/histogram_macros.h"
29 #include "base/path_service.h" 29 #include "base/path_service.h"
30 #include "base/strings/string_split.h" 30 #include "base/strings/string_split.h"
31 #include "base/strings/string_util.h" 31 #include "base/strings/string_util.h"
32 #include "base/time/time.h" 32 #include "base/time/time.h"
33 #include "base/values.h" 33 #include "base/values.h"
34 #include "chrome/browser/accessibility/accessibility_extension_api.h" 34 #include "chrome/browser/accessibility/accessibility_extension_api.h"
35 #include "chrome/browser/browser_process.h" 35 #include "chrome/browser/browser_process.h"
36 #include "chrome/browser/chrome_notification_types.h" 36 #include "chrome/browser/chrome_notification_types.h"
37 #include "chrome/browser/chromeos/accessibility/accessibility_extension_loader.h "
37 #include "chrome/browser/chromeos/accessibility/accessibility_highlight_manager. h" 38 #include "chrome/browser/chromeos/accessibility/accessibility_highlight_manager. h"
38 #include "chrome/browser/chromeos/accessibility/magnification_manager.h" 39 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
39 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
40 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
41 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
42 #include "chrome/browser/chromeos/profiles/profile_helper.h" 40 #include "chrome/browser/chromeos/profiles/profile_helper.h"
43 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" 41 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h"
44 #include "chrome/browser/extensions/api/braille_display_private/stub_braille_con troller.h" 42 #include "chrome/browser/extensions/api/braille_display_private/stub_braille_con troller.h"
45 #include "chrome/browser/extensions/component_loader.h"
46 #include "chrome/browser/extensions/extension_service.h" 43 #include "chrome/browser/extensions/extension_service.h"
47 #include "chrome/browser/extensions/tab_helper.h"
48 #include "chrome/browser/prefs/incognito_mode_prefs.h" 44 #include "chrome/browser/prefs/incognito_mode_prefs.h"
49 #include "chrome/browser/profiles/profile.h" 45 #include "chrome/browser/profiles/profile.h"
50 #include "chrome/browser/profiles/profile_manager.h" 46 #include "chrome/browser/profiles/profile_manager.h"
51 #include "chrome/common/chrome_paths.h" 47 #include "chrome/common/chrome_paths.h"
52 #include "chrome/common/extensions/api/accessibility_private.h" 48 #include "chrome/common/extensions/api/accessibility_private.h"
53 #include "chrome/common/extensions/extension_constants.h" 49 #include "chrome/common/extensions/extension_constants.h"
54 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
55 #include "chrome/common/pref_names.h" 50 #include "chrome/common/pref_names.h"
56 #include "chrome/grit/browser_resources.h" 51 #include "chrome/grit/browser_resources.h"
57 #include "chromeos/audio/audio_a11y_controller.h" 52 #include "chromeos/audio/audio_a11y_controller.h"
58 #include "chromeos/audio/chromeos_sounds.h" 53 #include "chromeos/audio/chromeos_sounds.h"
59 #include "chromeos/login/login_state.h" 54 #include "chromeos/login/login_state.h"
60 #include "components/prefs/pref_member.h" 55 #include "components/prefs/pref_member.h"
61 #include "components/prefs/pref_service.h" 56 #include "components/prefs/pref_service.h"
62 #include "components/user_manager/user_manager.h" 57 #include "components/user_manager/user_manager.h"
63 #include "content/public/browser/browser_accessibility_state.h" 58 #include "content/public/browser/browser_accessibility_state.h"
64 #include "content/public/browser/browser_thread.h" 59 #include "content/public/browser/browser_thread.h"
65 #include "content/public/browser/notification_details.h" 60 #include "content/public/browser/notification_details.h"
66 #include "content/public/browser/notification_service.h" 61 #include "content/public/browser/notification_service.h"
67 #include "content/public/browser/notification_source.h" 62 #include "content/public/browser/notification_source.h"
68 #include "content/public/browser/render_process_host.h"
69 #include "content/public/browser/render_view_host.h" 63 #include "content/public/browser/render_view_host.h"
70 #include "content/public/browser/web_contents.h"
71 #include "content/public/browser/web_ui.h" 64 #include "content/public/browser/web_ui.h"
72 #include "content/public/common/content_switches.h" 65 #include "content/public/common/content_switches.h"
73 #include "extensions/browser/event_router.h" 66 #include "extensions/browser/event_router.h"
74 #include "extensions/browser/extension_api_frame_id_map.h"
75 #include "extensions/browser/extension_registry.h" 67 #include "extensions/browser/extension_registry.h"
76 #include "extensions/browser/extension_system.h" 68 #include "extensions/browser/extension_system.h"
77 #include "extensions/browser/file_reader.h"
78 #include "extensions/browser/script_executor.h"
79 #include "extensions/common/extension.h" 69 #include "extensions/common/extension.h"
80 #include "extensions/common/extension_messages.h" 70 #include "extensions/common/extension_messages.h"
81 #include "extensions/common/extension_resource.h" 71 #include "extensions/common/extension_resource.h"
82 #include "extensions/common/host_id.h" 72 #include "extensions/common/host_id.h"
83 #include "media/audio/sounds/sounds_manager.h" 73 #include "media/audio/sounds/sounds_manager.h"
84 #include "ui/base/ime/chromeos/input_method_manager.h" 74 #include "ui/base/ime/chromeos/input_method_manager.h"
85 #include "ui/base/resource/resource_bundle.h" 75 #include "ui/base/resource/resource_bundle.h"
86 #include "ui/keyboard/keyboard_controller.h" 76 #include "ui/keyboard/keyboard_controller.h"
87 #include "ui/keyboard/keyboard_util.h" 77 #include "ui/keyboard/keyboard_util.h"
88 78
(...skipping 23 matching lines...) Expand all
112 if (g_braille_controller_for_test) 102 if (g_braille_controller_for_test)
113 return g_braille_controller_for_test; 103 return g_braille_controller_for_test;
114 // Don't use the real braille controller for tests to avoid automatically 104 // Don't use the real braille controller for tests to avoid automatically
115 // starting ChromeVox which confuses some tests. 105 // starting ChromeVox which confuses some tests.
116 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 106 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
117 if (command_line->HasSwitch(switches::kTestType)) 107 if (command_line->HasSwitch(switches::kTestType))
118 return StubBrailleController::GetInstance(); 108 return StubBrailleController::GetInstance();
119 return BrailleController::GetInstance(); 109 return BrailleController::GetInstance();
120 } 110 }
121 111
122 base::FilePath GetChromeVoxPath() {
123 base::FilePath path;
124 if (!PathService::Get(chrome::DIR_RESOURCES, &path))
125 NOTREACHED();
126 path = path.Append(extension_misc::kChromeVoxExtensionPath);
127 return path;
128 }
129
130 // Uses the ScriptExecutor associated with the given |render_view_host| to
131 // execute the given |code|.
132 void ExecuteScriptHelper(
133 content::RenderViewHost* render_view_host,
134 const std::string& code,
135 const std::string& extension_id) {
136 content::WebContents* web_contents =
137 content::WebContents::FromRenderViewHost(render_view_host);
138 if (!web_contents)
139 return;
140 if (!extensions::TabHelper::FromWebContents(web_contents))
141 extensions::TabHelper::CreateForWebContents(web_contents);
142 extensions::TabHelper::FromWebContents(web_contents)
143 ->script_executor()
144 ->ExecuteScript(HostID(HostID::EXTENSIONS, extension_id),
145 extensions::ScriptExecutor::JAVASCRIPT, code,
146 extensions::ScriptExecutor::INCLUDE_SUB_FRAMES,
147 extensions::ExtensionApiFrameIdMap::kTopFrameId,
148 extensions::ScriptExecutor::DONT_MATCH_ABOUT_BLANK,
149 extensions::UserScript::DOCUMENT_IDLE,
150 extensions::ScriptExecutor::ISOLATED_WORLD,
151 extensions::ScriptExecutor::DEFAULT_PROCESS,
152 GURL(), // No webview src.
153 GURL(), // No file url.
154 false, // Not user gesture.
155 extensions::ScriptExecutor::NO_RESULT,
156 extensions::ScriptExecutor::ExecuteScriptCallback());
157 }
158
159 // Helper class that directly loads an extension's content scripts into
160 // all of the frames corresponding to a given RenderViewHost.
161 class ContentScriptLoader {
162 public:
163 // Initialize the ContentScriptLoader with the ID of the extension
164 // and the RenderViewHost where the scripts should be loaded.
165 ContentScriptLoader(const std::string& extension_id,
166 int render_process_id,
167 int render_view_id)
168 : extension_id_(extension_id),
169 render_process_id_(render_process_id),
170 render_view_id_(render_view_id) {}
171
172 // Call this once with the ExtensionResource corresponding to each
173 // content script to be loaded.
174 void AppendScript(extensions::ExtensionResource resource) {
175 resources_.push(resource);
176 }
177
178 // Finally, call this method once to fetch all of the resources and
179 // load them. This method will delete this object when done.
180 void Run() {
181 if (resources_.empty()) {
182 delete this;
183 return;
184 }
185
186 extensions::ExtensionResource resource = resources_.front();
187 resources_.pop();
188 scoped_refptr<FileReader> reader(new FileReader(resource, base::Bind(
189 &ContentScriptLoader::OnFileLoaded, base::Unretained(this))));
190 reader->Start();
191 }
192
193 private:
194 void OnFileLoaded(bool success, std::unique_ptr<std::string> data) {
195 if (success) {
196 RenderViewHost* render_view_host =
197 RenderViewHost::FromID(render_process_id_, render_view_id_);
198 if (render_view_host)
199 ExecuteScriptHelper(render_view_host, *data, extension_id_);
200 }
201 Run();
202 }
203
204 std::string extension_id_;
205 int render_process_id_;
206 int render_view_id_;
207 std::queue<extensions::ExtensionResource> resources_;
208 };
209
210 void InjectChromeVoxContentScript(
211 ExtensionService* extension_service,
212 int render_process_id,
213 int render_view_id,
214 const base::Closure& done_cb);
215
216 void AddChromeVoxExtensionToComponentLoader(
217 extensions::ComponentLoader* component_loader,
218 base::Closure done_cb) {
219 component_loader->AddComponentFromDir(
220 GetChromeVoxPath(), extension_misc::kChromeVoxExtensionId, done_cb);
221 }
222
223 void LoadChromeVoxExtension(
224 Profile* profile,
225 RenderViewHost* render_view_host,
226 base::Closure done_cb) {
227 ExtensionService* extension_service =
228 extensions::ExtensionSystem::Get(profile)->extension_service();
229 if (render_view_host) {
230 // Wrap the passed in callback to inject the content script.
231 done_cb = base::Bind(
232 &InjectChromeVoxContentScript,
233 extension_service,
234 render_view_host->GetProcess()->GetID(),
235 render_view_host->GetRoutingID(),
236 done_cb);
237 }
238
239 AddChromeVoxExtensionToComponentLoader(extension_service->component_loader(),
240 done_cb);
241 }
242
243 void InjectChromeVoxContentScript(
244 ExtensionService* extension_service,
245 int render_process_id,
246 int render_view_id,
247 const base::Closure& done_cb) {
248 // Make sure to always run |done_cb|. ChromeVox was loaded even if we end up
249 // not injecting into this particular render view.
250 base::ScopedClosureRunner done_runner(done_cb);
251 RenderViewHost* render_view_host =
252 RenderViewHost::FromID(render_process_id, render_view_id);
253 if (!render_view_host)
254 return;
255 const content::WebContents* web_contents =
256 content::WebContents::FromRenderViewHost(render_view_host);
257 GURL content_url;
258 if (web_contents)
259 content_url = web_contents->GetLastCommittedURL();
260 const extensions::Extension* extension =
261 extensions::ExtensionRegistry::Get(extension_service->profile())
262 ->enabled_extensions()
263 .GetByID(extension_misc::kChromeVoxExtensionId);
264
265 // Set a flag to tell ChromeVox that it's just been enabled,
266 // so that it won't interrupt our speech feedback enabled message.
267 ExecuteScriptHelper(render_view_host, "window.INJECTED_AFTER_LOAD = true;",
268 extension->id());
269
270 // Inject ChromeVox' content scripts.
271 ContentScriptLoader* loader = new ContentScriptLoader(
272 extension->id(), render_view_host->GetProcess()->GetID(),
273 render_view_host->GetRoutingID());
274
275 const extensions::UserScriptList& content_scripts =
276 extensions::ContentScriptsInfo::GetContentScripts(extension);
277 for (const std::unique_ptr<extensions::UserScript>& script :
278 content_scripts) {
279 if (web_contents && !script->MatchesURL(content_url))
280 continue;
281 for (const std::unique_ptr<extensions::UserScript::File>& file :
282 script->js_scripts()) {
283 extensions::ExtensionResource resource =
284 extension->GetResource(file->relative_path());
285 loader->AppendScript(resource);
286 }
287 }
288 loader->Run(); // It cleans itself up when done.
289 }
290
291 void UnloadChromeVoxExtension(Profile* profile) {
292 base::FilePath path = GetChromeVoxPath();
293 ExtensionService* extension_service =
294 extensions::ExtensionSystem::Get(profile)->extension_service();
295 extension_service->component_loader()->Remove(path);
296 }
297
298 } // namespace 112 } // namespace
299 113
300 class ChromeVoxPanelWidgetObserver : public views::WidgetObserver { 114 class ChromeVoxPanelWidgetObserver : public views::WidgetObserver {
301 public: 115 public:
302 ChromeVoxPanelWidgetObserver(views::Widget* widget, 116 ChromeVoxPanelWidgetObserver(views::Widget* widget,
303 AccessibilityManager* manager) 117 AccessibilityManager* manager)
304 : widget_(widget), manager_(manager) { 118 : widget_(widget), manager_(manager) {
305 widget_->AddObserver(this); 119 widget_->AddObserver(this);
306 } 120 }
307 121
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 g_accessibility_manager = NULL; 216 g_accessibility_manager = NULL;
403 } 217 }
404 218
405 // static 219 // static
406 AccessibilityManager* AccessibilityManager::Get() { 220 AccessibilityManager* AccessibilityManager::Get() {
407 return g_accessibility_manager; 221 return g_accessibility_manager;
408 } 222 }
409 223
410 AccessibilityManager::AccessibilityManager() 224 AccessibilityManager::AccessibilityManager()
411 : profile_(NULL), 225 : profile_(NULL),
412 chrome_vox_loaded_on_lock_screen_(false),
413 chrome_vox_loaded_on_user_screen_(false),
414 large_cursor_pref_handler_(prefs::kAccessibilityLargeCursorEnabled), 226 large_cursor_pref_handler_(prefs::kAccessibilityLargeCursorEnabled),
415 spoken_feedback_pref_handler_(prefs::kAccessibilitySpokenFeedbackEnabled), 227 spoken_feedback_pref_handler_(prefs::kAccessibilitySpokenFeedbackEnabled),
416 high_contrast_pref_handler_(prefs::kAccessibilityHighContrastEnabled), 228 high_contrast_pref_handler_(prefs::kAccessibilityHighContrastEnabled),
417 autoclick_pref_handler_(prefs::kAccessibilityAutoclickEnabled), 229 autoclick_pref_handler_(prefs::kAccessibilityAutoclickEnabled),
418 autoclick_delay_pref_handler_(prefs::kAccessibilityAutoclickDelayMs), 230 autoclick_delay_pref_handler_(prefs::kAccessibilityAutoclickDelayMs),
419 virtual_keyboard_pref_handler_( 231 virtual_keyboard_pref_handler_(
420 prefs::kAccessibilityVirtualKeyboardEnabled), 232 prefs::kAccessibilityVirtualKeyboardEnabled),
421 mono_audio_pref_handler_(prefs::kAccessibilityMonoAudioEnabled), 233 mono_audio_pref_handler_(prefs::kAccessibilityMonoAudioEnabled),
422 caret_highlight_pref_handler_(prefs::kAccessibilityCaretHighlightEnabled), 234 caret_highlight_pref_handler_(prefs::kAccessibilityCaretHighlightEnabled),
423 cursor_highlight_pref_handler_( 235 cursor_highlight_pref_handler_(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_ENABLED_WAV)); 283 bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_ENABLED_WAV));
472 manager->Initialize( 284 manager->Initialize(
473 SOUND_SPOKEN_FEEDBACK_DISABLED, 285 SOUND_SPOKEN_FEEDBACK_DISABLED,
474 bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_DISABLED_WAV)); 286 bundle.GetRawDataResource(IDR_SOUND_SPOKEN_FEEDBACK_DISABLED_WAV));
475 manager->Initialize(SOUND_PASSTHROUGH, 287 manager->Initialize(SOUND_PASSTHROUGH,
476 bundle.GetRawDataResource(IDR_SOUND_PASSTHROUGH_WAV)); 288 bundle.GetRawDataResource(IDR_SOUND_PASSTHROUGH_WAV));
477 manager->Initialize(SOUND_EXIT_SCREEN, 289 manager->Initialize(SOUND_EXIT_SCREEN,
478 bundle.GetRawDataResource(IDR_SOUND_EXIT_SCREEN_WAV)); 290 bundle.GetRawDataResource(IDR_SOUND_EXIT_SCREEN_WAV));
479 manager->Initialize(SOUND_ENTER_SCREEN, 291 manager->Initialize(SOUND_ENTER_SCREEN,
480 bundle.GetRawDataResource(IDR_SOUND_ENTER_SCREEN_WAV)); 292 bundle.GetRawDataResource(IDR_SOUND_ENTER_SCREEN_WAV));
293
294 base::FilePath resources_path;
295 if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path))
296 NOTREACHED();
297 chromevox_loader_ = base::WrapUnique(new AccessibilityExtensionLoader(
298 extension_misc::kChromeVoxExtensionId,
299 resources_path.Append(extension_misc::kChromeVoxExtensionPath)));
481 } 300 }
482 301
483 AccessibilityManager::~AccessibilityManager() { 302 AccessibilityManager::~AccessibilityManager() {
484 CHECK(this == g_accessibility_manager); 303 CHECK(this == g_accessibility_manager);
485 AccessibilityStatusEventDetails details(ACCESSIBILITY_MANAGER_SHUTDOWN, false, 304 AccessibilityStatusEventDetails details(ACCESSIBILITY_MANAGER_SHUTDOWN, false,
486 ash::A11Y_NOTIFICATION_NONE); 305 ash::A11Y_NOTIFICATION_NONE);
487 NotifyAccessibilityStatusChanged(details); 306 NotifyAccessibilityStatusChanged(details);
488 input_method::InputMethodManager::Get()->RemoveObserver(this); 307 input_method::InputMethodManager::Get()->RemoveObserver(this);
489 308
490 if (chromevox_panel_) { 309 if (chromevox_panel_) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 434
616 spoken_feedback_notification_ = ash::A11Y_NOTIFICATION_NONE; 435 spoken_feedback_notification_ = ash::A11Y_NOTIFICATION_NONE;
617 } 436 }
618 437
619 void AccessibilityManager::UpdateSpokenFeedbackFromPref() { 438 void AccessibilityManager::UpdateSpokenFeedbackFromPref() {
620 if (!profile_) 439 if (!profile_)
621 return; 440 return;
622 441
623 const bool enabled = profile_->GetPrefs()->GetBoolean( 442 const bool enabled = profile_->GetPrefs()->GetBoolean(
624 prefs::kAccessibilitySpokenFeedbackEnabled); 443 prefs::kAccessibilitySpokenFeedbackEnabled);
625
626 // If ChromeVox was already enabled, but not for this profile,
627 // add it to this profile.
628 auto* extension_service =
629 extensions::ExtensionSystem::Get(profile_)->extension_service();
630 auto* component_loader = extension_service->component_loader();
631 bool is_already_loaded =
632 component_loader->Exists(extension_misc::kChromeVoxExtensionId);
633 if (spoken_feedback_enabled_ && enabled && !is_already_loaded)
634 AddChromeVoxExtensionToComponentLoader(component_loader, base::Closure());
635
636 if (spoken_feedback_enabled_ == enabled) 444 if (spoken_feedback_enabled_ == enabled)
637 return; 445 return;
638 446
639 spoken_feedback_enabled_ = enabled; 447 spoken_feedback_enabled_ = enabled;
640 448
641 AccessibilityStatusEventDetails details( 449 AccessibilityStatusEventDetails details(
642 ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK, 450 ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
643 enabled, 451 enabled,
644 spoken_feedback_notification_); 452 spoken_feedback_notification_);
645 453
646 NotifyAccessibilityStatusChanged(details); 454 NotifyAccessibilityStatusChanged(details);
647 455
648 if (enabled) { 456 if (enabled) {
649 LoadChromeVox(); 457 chromevox_loader_->Load(profile_, "window.INJECTED_AFTER_LOAD = true;",
458 base::Bind(&AccessibilityManager::PostLoadChromeVox,
459 weak_ptr_factory_.GetWeakPtr()));
460
David Tseng 2016/09/08 21:18:42 Remove
dmazzoni 2016/09/13 23:03:19 Done
650 } else { 461 } else {
651 UnloadChromeVox(); 462 chromevox_loader_->Unload();
652 } 463 }
653 UpdateBrailleImeState(); 464 UpdateBrailleImeState();
654 465
655 // ChromeVox focus highlighting overrides the other focus highlighting. 466 // ChromeVox focus highlighting overrides the other focus highlighting.
656 UpdateFocusHighlightFromPref(); 467 UpdateFocusHighlightFromPref();
657 } 468 }
658 469
659 void AccessibilityManager::LoadChromeVox() {
660 base::Closure done_cb = base::Bind(&AccessibilityManager::PostLoadChromeVox,
661 weak_ptr_factory_.GetWeakPtr(),
662 profile_);
663 ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
664 if (screen_locker && screen_locker->locked()) {
665 // If on the lock screen, loads ChromeVox only to the lock screen as for
666 // now. On unlock, it will be loaded to the user screen.
667 // (see. AccessibilityManager::Observe())
668 LoadChromeVoxToLockScreen(done_cb);
669 } else {
670 LoadChromeVoxToUserScreen(done_cb);
671 }
672 }
673
674 void AccessibilityManager::LoadChromeVoxToUserScreen(
675 const base::Closure& done_cb) {
676 if (chrome_vox_loaded_on_user_screen_)
677 return;
678
679 // Determine whether an OOBE screen is currently being shown. If so,
680 // ChromeVox will be injected directly into that screen.
681 content::WebUI* login_web_ui = NULL;
682
683 if (ProfileHelper::IsSigninProfile(profile_)) {
684 LoginDisplayHost* login_display_host = LoginDisplayHost::default_host();
685 if (login_display_host) {
686 WebUILoginView* web_ui_login_view =
687 login_display_host->GetWebUILoginView();
688 if (web_ui_login_view)
689 login_web_ui = web_ui_login_view->GetWebUI();
690 }
691
692 // Lock screen uses the signin progile.
693 chrome_vox_loaded_on_lock_screen_ = true;
694 }
695
696 chrome_vox_loaded_on_user_screen_ = true;
697 LoadChromeVoxExtension(
698 profile_, login_web_ui ?
699 login_web_ui->GetWebContents()->GetRenderViewHost() : NULL,
700 done_cb);
701 }
702
703 void AccessibilityManager::LoadChromeVoxToLockScreen(
704 const base::Closure& done_cb) {
705 if (chrome_vox_loaded_on_lock_screen_)
706 return;
707
708 ScreenLocker* screen_locker = ScreenLocker::default_screen_locker();
709 if (screen_locker && screen_locker->locked()) {
710 content::WebUI* lock_web_ui = screen_locker->GetAssociatedWebUI();
711 if (lock_web_ui) {
712 Profile* profile = Profile::FromWebUI(lock_web_ui);
713 chrome_vox_loaded_on_lock_screen_ = true;
714 LoadChromeVoxExtension(
715 profile,
716 lock_web_ui->GetWebContents()->GetRenderViewHost(),
717 done_cb);
718 }
719 }
720 }
721
722 void AccessibilityManager::UnloadChromeVox() {
723 if (chromevox_panel_) {
724 chromevox_panel_->Close();
725 chromevox_panel_ = nullptr;
726 }
727
728 if (chrome_vox_loaded_on_lock_screen_)
729 UnloadChromeVoxFromLockScreen();
730
731 if (chrome_vox_loaded_on_user_screen_) {
732 UnloadChromeVoxExtension(profile_);
733 chrome_vox_loaded_on_user_screen_ = false;
734 }
735
736 PostUnloadChromeVox(profile_);
737 }
738
739 void AccessibilityManager::UnloadChromeVoxFromLockScreen() {
740 // Lock screen uses the signin progile.
741 Profile* signin_profile = ProfileHelper::GetSigninProfile();
742 UnloadChromeVoxExtension(signin_profile);
743 chrome_vox_loaded_on_lock_screen_ = false;
744 }
745
746 bool AccessibilityManager::IsSpokenFeedbackEnabled() { 470 bool AccessibilityManager::IsSpokenFeedbackEnabled() {
747 return spoken_feedback_enabled_; 471 return spoken_feedback_enabled_;
748 } 472 }
749 473
750 void AccessibilityManager::ToggleSpokenFeedback( 474 void AccessibilityManager::ToggleSpokenFeedback(
751 ash::AccessibilityNotificationVisibility notify) { 475 ash::AccessibilityNotificationVisibility notify) {
752 EnableSpokenFeedback(!IsSpokenFeedbackEnabled(), notify); 476 EnableSpokenFeedback(!IsSpokenFeedbackEnabled(), notify);
753 } 477 }
754 478
755 void AccessibilityManager::EnableHighContrast(bool enabled) { 479 void AccessibilityManager::EnableHighContrast(bool enabled) {
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 local_state_pref_change_registrar_->Init(g_browser_process->local_state()); 981 local_state_pref_change_registrar_->Init(g_browser_process->local_state());
1258 local_state_pref_change_registrar_->Add( 982 local_state_pref_change_registrar_->Add(
1259 prefs::kApplicationLocale, 983 prefs::kApplicationLocale,
1260 base::Bind(&AccessibilityManager::OnLocaleChanged, 984 base::Bind(&AccessibilityManager::OnLocaleChanged,
1261 base::Unretained(this))); 985 base::Unretained(this)));
1262 986
1263 content::BrowserAccessibilityState::GetInstance()->AddHistogramCallback( 987 content::BrowserAccessibilityState::GetInstance()->AddHistogramCallback(
1264 base::Bind( 988 base::Bind(
1265 &AccessibilityManager::UpdateChromeOSAccessibilityHistograms, 989 &AccessibilityManager::UpdateChromeOSAccessibilityHistograms,
1266 base::Unretained(this))); 990 base::Unretained(this)));
991
992 chromevox_loader_->SetProfile(profile);
993
994 extensions::ExtensionRegistry* registry =
995 extensions::ExtensionRegistry::Get(profile);
996 if (!extension_registry_observer_.IsObserving(registry))
997 extension_registry_observer_.Add(registry);
1267 } 998 }
1268 999
1269 large_cursor_pref_handler_.HandleProfileChanged(profile_, profile); 1000 large_cursor_pref_handler_.HandleProfileChanged(profile_, profile);
1270 spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile); 1001 spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile);
1271 high_contrast_pref_handler_.HandleProfileChanged(profile_, profile); 1002 high_contrast_pref_handler_.HandleProfileChanged(profile_, profile);
1272 autoclick_pref_handler_.HandleProfileChanged(profile_, profile); 1003 autoclick_pref_handler_.HandleProfileChanged(profile_, profile);
1273 autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile); 1004 autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile);
1274 virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile); 1005 virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile);
1275 mono_audio_pref_handler_.HandleProfileChanged(profile_, profile); 1006 mono_audio_pref_handler_.HandleProfileChanged(profile_, profile);
1276 caret_highlight_pref_handler_.HandleProfileChanged(profile_, profile); 1007 caret_highlight_pref_handler_.HandleProfileChanged(profile_, profile);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 base::TimeDelta AccessibilityManager::PlayShutdownSound() { 1068 base::TimeDelta AccessibilityManager::PlayShutdownSound() {
1338 if (!system_sounds_enabled_) 1069 if (!system_sounds_enabled_)
1339 return base::TimeDelta(); 1070 return base::TimeDelta();
1340 system_sounds_enabled_ = false; 1071 system_sounds_enabled_ = false;
1341 if (!PlayEarcon(SOUND_SHUTDOWN, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED)) 1072 if (!PlayEarcon(SOUND_SHUTDOWN, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED))
1342 return base::TimeDelta(); 1073 return base::TimeDelta();
1343 return media::SoundsManager::Get()->GetDuration(SOUND_SHUTDOWN); 1074 return media::SoundsManager::Get()->GetDuration(SOUND_SHUTDOWN);
1344 } 1075 }
1345 1076
1346 void AccessibilityManager::InjectChromeVox(RenderViewHost* render_view_host) { 1077 void AccessibilityManager::InjectChromeVox(RenderViewHost* render_view_host) {
1347 LoadChromeVoxExtension(profile_, render_view_host, base::Closure()); 1078 chromevox_loader_->InjectContentScript(render_view_host);
David Tseng 2016/09/08 20:39:31 This doesn't look equivalent.
dmazzoni 2016/09/08 21:00:55 You're right, but I think it was doing extra unnec
David Tseng 2016/09/08 21:18:42 Same comment here -- if you're sure, then that's f
dmazzoni 2016/09/13 23:03:19 Makes sense. Done.
1348 } 1079 }
1349 1080
1350 std::unique_ptr<AccessibilityStatusSubscription> 1081 std::unique_ptr<AccessibilityStatusSubscription>
1351 AccessibilityManager::RegisterCallback(const AccessibilityStatusCallback& cb) { 1082 AccessibilityManager::RegisterCallback(const AccessibilityStatusCallback& cb) {
1352 return callback_list_.Add(cb); 1083 return callback_list_.Add(cb);
1353 } 1084 }
1354 1085
1355 void AccessibilityManager::NotifyAccessibilityStatusChanged( 1086 void AccessibilityManager::NotifyAccessibilityStatusChanged(
1356 AccessibilityStatusEventDetails& details) { 1087 AccessibilityStatusEventDetails& details) {
1357 callback_list_.Notify(details); 1088 callback_list_.Notify(details);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 // Update |profile_| when exiting a session or shutting down. 1168 // Update |profile_| when exiting a session or shutting down.
1438 Profile* profile = content::Source<Profile>(source).ptr(); 1169 Profile* profile = content::Source<Profile>(source).ptr();
1439 if (profile_ == profile) 1170 if (profile_ == profile)
1440 SetProfile(NULL); 1171 SetProfile(NULL);
1441 break; 1172 break;
1442 } 1173 }
1443 case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { 1174 case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: {
1444 bool is_screen_locked = *content::Details<bool>(details).ptr(); 1175 bool is_screen_locked = *content::Details<bool>(details).ptr();
1445 if (spoken_feedback_enabled_) { 1176 if (spoken_feedback_enabled_) {
1446 if (is_screen_locked) 1177 if (is_screen_locked)
1447 LoadChromeVoxToLockScreen(base::Closure()); 1178 chromevox_loader_->LoadToLockScreen(base::Closure());
1448 // If spoken feedback was enabled, make sure it is also enabled on 1179 // If spoken feedback was enabled, make sure it is also enabled on
1449 // the user screen. 1180 // the user screen.
1450 // The status tray gets verbalized by user screen ChromeVox, so we need 1181 // The status tray gets verbalized by user screen ChromeVox, so we need
1451 // to load it on the user screen even if the screen is locked. 1182 // to load it on the user screen even if the screen is locked.
1452 LoadChromeVoxToUserScreen(base::Closure()); 1183 chromevox_loader_->LoadToUserScreen(base::Closure());
1453 } 1184 }
1454 break; 1185 break;
1455 } 1186 }
1456 } 1187 }
1457 } 1188 }
1458 1189
1459 void AccessibilityManager::OnBrailleDisplayStateChanged( 1190 void AccessibilityManager::OnBrailleDisplayStateChanged(
1460 const DisplayState& display_state) { 1191 const DisplayState& display_state) {
1461 braille_display_connected_ = display_state.available; 1192 braille_display_connected_ = display_state.available;
1462 if (braille_display_connected_) { 1193 if (braille_display_connected_) {
(...skipping 19 matching lines...) Expand all
1482 } 1213 }
1483 } 1214 }
1484 1215
1485 void AccessibilityManager::OnExtensionUnloaded( 1216 void AccessibilityManager::OnExtensionUnloaded(
1486 content::BrowserContext* browser_context, 1217 content::BrowserContext* browser_context,
1487 const extensions::Extension* extension, 1218 const extensions::Extension* extension,
1488 extensions::UnloadedExtensionInfo::Reason reason) { 1219 extensions::UnloadedExtensionInfo::Reason reason) {
1489 if (extension->id() == keyboard_listener_extension_id_) { 1220 if (extension->id() == keyboard_listener_extension_id_) {
1490 keyboard_listener_extension_id_ = std::string(); 1221 keyboard_listener_extension_id_ = std::string();
1491 keyboard_listener_capture_ = false; 1222 keyboard_listener_capture_ = false;
1492 extension_registry_observer_.Remove( 1223 }
1493 extensions::ExtensionRegistry::Get(browser_context)); 1224
1225 if (extension->id() == extension_misc::kChromeVoxExtensionId) {
1226 // Do any teardown work needed immediately after ChromeVox actually unloads.
1227 PlayEarcon(SOUND_SPOKEN_FEEDBACK_DISABLED, PlaySoundOption::ALWAYS);
1228 // Clear the accessibility focus ring.
1229 AccessibilityFocusRingController::GetInstance()->SetFocusRing(
1230 std::vector<gfx::Rect>(),
1231 AccessibilityFocusRingController::PERSIST_FOCUS_RING);
1232
1233 if (chromevox_panel_) {
1234 chromevox_panel_->Close();
1235 chromevox_panel_ = nullptr;
1236 }
1494 } 1237 }
1495 } 1238 }
1496 1239
1497 void AccessibilityManager::OnShutdown(extensions::ExtensionRegistry* registry) { 1240 void AccessibilityManager::OnShutdown(extensions::ExtensionRegistry* registry) {
1498 extension_registry_observer_.Remove(registry); 1241 extension_registry_observer_.Remove(registry);
1499 } 1242 }
1500 1243
1501 void AccessibilityManager::PostLoadChromeVox(Profile* profile) { 1244 void AccessibilityManager::PostLoadChromeVox() {
1502 // Do any setup work needed immediately after ChromeVox actually loads. 1245 // Do any setup work needed immediately after ChromeVox actually loads.
1503 PlayEarcon(SOUND_SPOKEN_FEEDBACK_ENABLED, PlaySoundOption::ALWAYS); 1246 PlayEarcon(SOUND_SPOKEN_FEEDBACK_ENABLED, PlaySoundOption::ALWAYS);
1504 1247
1505 if (chrome_vox_loaded_on_lock_screen_ || 1248 if (chromevox_loader_->loaded_on_lock_screen() ||
1506 should_speak_chrome_vox_announcements_on_user_screen_) { 1249 should_speak_chrome_vox_announcements_on_user_screen_) {
1507 extensions::EventRouter* event_router = 1250 extensions::EventRouter* event_router =
1508 extensions::EventRouter::Get(profile); 1251 extensions::EventRouter::Get(profile_);
1509 CHECK(event_router); 1252 CHECK(event_router);
1510 1253
1511 std::unique_ptr<base::ListValue> event_args(new base::ListValue()); 1254 std::unique_ptr<base::ListValue> event_args(new base::ListValue());
1512 std::unique_ptr<extensions::Event> event(new extensions::Event( 1255 std::unique_ptr<extensions::Event> event(new extensions::Event(
1513 extensions::events::ACCESSIBILITY_PRIVATE_ON_INTRODUCE_CHROME_VOX, 1256 extensions::events::ACCESSIBILITY_PRIVATE_ON_INTRODUCE_CHROME_VOX,
1514 extensions::api::accessibility_private::OnIntroduceChromeVox:: 1257 extensions::api::accessibility_private::OnIntroduceChromeVox::
1515 kEventName, 1258 kEventName,
1516 std::move(event_args))); 1259 std::move(event_args)));
1517 event_router->DispatchEventWithLazyListener( 1260 event_router->DispatchEventWithLazyListener(
1518 extension_misc::kChromeVoxExtensionId, std::move(event)); 1261 extension_misc::kChromeVoxExtensionId, std::move(event));
1519 } 1262 }
1520 1263
1521 should_speak_chrome_vox_announcements_on_user_screen_ = 1264 should_speak_chrome_vox_announcements_on_user_screen_ =
1522 chrome_vox_loaded_on_lock_screen_; 1265 chromevox_loader_->loaded_on_lock_screen();
1523 1266
1524 if (!chromevox_panel_) { 1267 if (!chromevox_panel_) {
1525 chromevox_panel_ = new ChromeVoxPanel(profile_); 1268 chromevox_panel_ = new ChromeVoxPanel(profile_);
1526 chromevox_panel_widget_observer_.reset( 1269 chromevox_panel_widget_observer_.reset(
1527 new ChromeVoxPanelWidgetObserver(chromevox_panel_->GetWidget(), this)); 1270 new ChromeVoxPanelWidgetObserver(chromevox_panel_->GetWidget(), this));
1528 } 1271 }
1529 } 1272 }
1530 1273
1531 void AccessibilityManager::PostUnloadChromeVox(Profile* profile) {
1532 // Do any teardown work needed immediately after ChromeVox actually unloads.
1533 PlayEarcon(SOUND_SPOKEN_FEEDBACK_DISABLED, PlaySoundOption::ALWAYS);
1534 // Clear the accessibility focus ring.
1535 AccessibilityFocusRingController::GetInstance()->SetFocusRing(
1536 std::vector<gfx::Rect>(),
1537 AccessibilityFocusRingController::PERSIST_FOCUS_RING);
1538 }
1539
1540 void AccessibilityManager::OnChromeVoxPanelClosing() { 1274 void AccessibilityManager::OnChromeVoxPanelClosing() {
1541 aura::Window* root_window = chromevox_panel_->GetRootWindow(); 1275 aura::Window* root_window = chromevox_panel_->GetRootWindow();
1542 chromevox_panel_widget_observer_.reset(nullptr); 1276 chromevox_panel_widget_observer_.reset(nullptr);
1543 chromevox_panel_ = nullptr; 1277 chromevox_panel_ = nullptr;
1544 1278
1545 ash::WmShelf* shelf = 1279 ash::WmShelf* shelf =
1546 ash::WmShelf::ForWindow(ash::WmWindowAura::Get(root_window)); 1280 ash::WmShelf::ForWindow(ash::WmWindowAura::Get(root_window));
1547 if (!shelf->IsShelfInitialized()) 1281 if (!shelf->IsShelfInitialized())
1548 return; 1282 return;
1549 1283
(...skipping 12 matching lines...) Expand all
1562 content::BrowserContext* context) { 1296 content::BrowserContext* context) {
1563 keyboard_listener_extension_id_ = id; 1297 keyboard_listener_extension_id_ = id;
1564 1298
1565 extensions::ExtensionRegistry* registry = 1299 extensions::ExtensionRegistry* registry =
1566 extensions::ExtensionRegistry::Get(context); 1300 extensions::ExtensionRegistry::Get(context);
1567 if (!extension_registry_observer_.IsObserving(registry) && !id.empty()) 1301 if (!extension_registry_observer_.IsObserving(registry) && !id.empty())
1568 extension_registry_observer_.Add(registry); 1302 extension_registry_observer_.Add(registry);
1569 } 1303 }
1570 1304
1571 } // namespace chromeos 1305 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698