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/renderer_host/render_widget_host_impl.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/render_widget_host_iterator.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
) {
41 // On Windows 8, always enable accessibility for editable text controls
42 // so we can show the virtual keyboard when one is enabled.
43 if (base::win::GetVersion() >= base::win::VERSION_WIN8
&&
44 !CommandLine::ForCurrentProcess()->HasSwitch(
45 switches::kDisableRendererAccessibility
)) {
46 accessibility_mode_
= AccessibilityModeEditableTextOnly
;
48 #endif // defined(OS_WIN)
50 if (CommandLine::ForCurrentProcess()->HasSwitch(
51 switches::kForceRendererAccessibility
)) {
52 accessibility_mode_
= AccessibilityModeComplete
;
56 // On Windows, UpdateHistograms calls some system functions with unknown
57 // runtime, so call it on the file thread to ensure there's no jank.
58 // Everything in that method must be safe to call on another thread.
59 BrowserThread::ID update_histogram_thread
= BrowserThread::FILE;
61 // On all other platforms, UpdateHistograms should be called on the main
63 BrowserThread::ID update_histogram_thread
= BrowserThread::UI
;
66 // We need to AddRef() the leaky singleton so that Bind doesn't
67 // delete it prematurely.
69 BrowserThread::PostDelayedTask(
70 update_histogram_thread
, FROM_HERE
,
71 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms
, this),
72 base::TimeDelta::FromSeconds(kAccessibilityHistogramDelaySecs
));
75 BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
78 void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
79 if (CommandLine::ForCurrentProcess()->HasSwitch(
80 switches::kDisableRendererAccessibility
)) {
83 SetAccessibilityMode(AccessibilityModeComplete
);
86 void BrowserAccessibilityStateImpl::EnableAccessibility() {
87 // We may want to do something different with this later.
88 SetAccessibilityMode(AccessibilityModeComplete
);
91 void BrowserAccessibilityStateImpl::DisableAccessibility() {
92 SetAccessibilityMode(AccessibilityModeOff
);
95 bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
96 return (accessibility_mode_
== AccessibilityModeComplete
);
99 void BrowserAccessibilityStateImpl::AddHistogramCallback(
100 base::Closure callback
) {
101 histogram_callbacks_
.push_back(callback
);
104 void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
108 void BrowserAccessibilityStateImpl::UpdateHistograms() {
109 UpdatePlatformSpecificHistograms();
111 for (size_t i
= 0; i
< histogram_callbacks_
.size(); ++i
)
112 histogram_callbacks_
[i
].Run();
114 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
115 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
116 gfx::IsInvertedColorScheme());
117 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
118 CommandLine::ForCurrentProcess()->HasSwitch(
119 switches::kForceRendererAccessibility
));
123 void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
127 void BrowserAccessibilityStateImpl::SetAccessibilityMode(
128 AccessibilityMode mode
) {
129 if (accessibility_mode_
== mode
)
131 accessibility_mode_
= mode
;
133 // Iterate over all RenderWidgetHosts, even swapped out ones in case
134 // they become active again.
135 scoped_ptr
<RenderWidgetHostIterator
> widgets(
136 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
137 while (RenderWidgetHost
* widget
= widgets
->GetNextHost()) {
138 // Ignore processes that don't have a connection, such as crashed tabs.
139 if (!widget
->GetProcess()->HasConnection())
141 if (!widget
->IsRenderView())
144 RenderWidgetHostImpl::From(widget
)->SetAccessibilityMode(mode
);
148 } // namespace content