1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/timer/timer.h"
10 #include "content/browser/accessibility/accessibility_mode_helper.h"
11 #include "content/browser/renderer_host/render_widget_host_impl.h"
12 #include "content/browser/web_contents/web_contents_impl.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/content_switches.h"
15 #include "ui/gfx/sys_color_change_listener.h"
18 #include "base/win/windows_version.h"
23 // Update the accessibility histogram 45 seconds after initialization.
24 static const int kAccessibilityHistogramDelaySecs
= 45;
27 BrowserAccessibilityState
* BrowserAccessibilityState::GetInstance() {
28 return BrowserAccessibilityStateImpl::GetInstance();
32 BrowserAccessibilityStateImpl
* BrowserAccessibilityStateImpl::GetInstance() {
33 return Singleton
<BrowserAccessibilityStateImpl
,
34 LeakySingletonTraits
<BrowserAccessibilityStateImpl
> >::get();
37 BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
38 : BrowserAccessibilityState(),
39 accessibility_mode_(AccessibilityModeOff
) {
40 ResetAccessibilityModeValue();
42 // On Windows, UpdateHistograms calls some system functions with unknown
43 // runtime, so call it on the file thread to ensure there's no jank.
44 // Everything in that method must be safe to call on another thread.
45 BrowserThread::ID update_histogram_thread
= BrowserThread::FILE;
47 // On all other platforms, UpdateHistograms should be called on the main
49 BrowserThread::ID update_histogram_thread
= BrowserThread::UI
;
52 // We need to AddRef() the leaky singleton so that Bind doesn't
53 // delete it prematurely.
55 BrowserThread::PostDelayedTask(
56 update_histogram_thread
, FROM_HERE
,
57 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms
, this),
58 base::TimeDelta::FromSeconds(kAccessibilityHistogramDelaySecs
));
61 BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
64 void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
65 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
66 switches::kDisableRendererAccessibility
)) {
69 EnableAccessibility();
72 void BrowserAccessibilityStateImpl::EnableAccessibility() {
73 AddAccessibilityMode(AccessibilityModeComplete
);
76 void BrowserAccessibilityStateImpl::DisableAccessibility() {
77 ResetAccessibilityMode();
80 void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
81 accessibility_mode_
= AccessibilityModeOff
;
83 // On Windows 8, always enable accessibility for editable text controls
84 // so we can show the virtual keyboard when one is enabled.
85 if (base::win::GetVersion() >= base::win::VERSION_WIN8
&&
86 !base::CommandLine::ForCurrentProcess()->HasSwitch(
87 switches::kDisableRendererAccessibility
)) {
88 accessibility_mode_
= AccessibilityModeEditableTextOnly
;
90 #endif // defined(OS_WIN)
92 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
93 switches::kForceRendererAccessibility
)) {
94 accessibility_mode_
= AccessibilityModeComplete
;
98 void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
99 ResetAccessibilityModeValue();
101 std::vector
<WebContentsImpl
*> web_contents_vector
=
102 WebContentsImpl::GetAllWebContents();
103 for (size_t i
= 0; i
< web_contents_vector
.size(); ++i
)
104 web_contents_vector
[i
]->SetAccessibilityMode(accessibility_mode());
107 bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
108 return ((accessibility_mode_
& AccessibilityModeComplete
) ==
109 AccessibilityModeComplete
);
112 void BrowserAccessibilityStateImpl::AddHistogramCallback(
113 base::Closure callback
) {
114 histogram_callbacks_
.push_back(callback
);
117 void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
121 void BrowserAccessibilityStateImpl::UpdateHistograms() {
122 UpdatePlatformSpecificHistograms();
124 for (size_t i
= 0; i
< histogram_callbacks_
.size(); ++i
)
125 histogram_callbacks_
[i
].Run();
127 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
128 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
129 gfx::IsInvertedColorScheme());
130 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
131 base::CommandLine::ForCurrentProcess()->HasSwitch(
132 switches::kForceRendererAccessibility
));
136 void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
140 void BrowserAccessibilityStateImpl::AddAccessibilityMode(
141 AccessibilityMode mode
) {
142 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
143 switches::kDisableRendererAccessibility
)) {
147 accessibility_mode_
=
148 content::AddAccessibilityModeTo(accessibility_mode_
, mode
);
150 AddOrRemoveFromAllWebContents(mode
, true);
153 void BrowserAccessibilityStateImpl::RemoveAccessibilityMode(
154 AccessibilityMode mode
) {
155 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
156 switches::kForceRendererAccessibility
) &&
157 mode
== AccessibilityModeComplete
) {
161 accessibility_mode_
=
162 content::RemoveAccessibilityModeFrom(accessibility_mode_
, mode
);
164 AddOrRemoveFromAllWebContents(mode
, false);
167 void BrowserAccessibilityStateImpl::AddOrRemoveFromAllWebContents(
168 AccessibilityMode mode
,
170 std::vector
<WebContentsImpl
*> web_contents_vector
=
171 WebContentsImpl::GetAllWebContents();
172 for (size_t i
= 0; i
< web_contents_vector
.size(); ++i
) {
174 web_contents_vector
[i
]->AddAccessibilityMode(mode
);
176 web_contents_vector
[i
]->RemoveAccessibilityMode(mode
);
180 } // namespace content