- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / accessibility / browser_accessibility_state_impl.cc
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.
4
5 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
6
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"
16
17 #if defined(OS_WIN)
18 #include "base/win/windows_version.h"
19 #endif
20
21 namespace content {
22
23 // Update the accessibility histogram 45 seconds after initialization.
24 static const int kAccessibilityHistogramDelaySecs = 45;
25
26 // static
27 BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
28   return BrowserAccessibilityStateImpl::GetInstance();
29 }
30
31 // static
32 BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
33   return Singleton<BrowserAccessibilityStateImpl,
34                    LeakySingletonTraits<BrowserAccessibilityStateImpl> >::get();
35 }
36
37 BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
38     : BrowserAccessibilityState(),
39       accessibility_mode_(AccessibilityModeOff) {
40 #if defined(OS_WIN)
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;
47   }
48 #endif  // defined(OS_WIN)
49
50   if (CommandLine::ForCurrentProcess()->HasSwitch(
51           switches::kForceRendererAccessibility)) {
52     accessibility_mode_ = AccessibilityModeComplete;
53   }
54
55 #if defined(OS_WIN)
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;
60 #else
61   // On all other platforms, UpdateHistograms should be called on the main
62   // thread.
63   BrowserThread::ID update_histogram_thread = BrowserThread::UI;
64 #endif
65
66   // We need to AddRef() the leaky singleton so that Bind doesn't
67   // delete it prematurely.
68   AddRef();
69   BrowserThread::PostDelayedTask(
70       update_histogram_thread, FROM_HERE,
71       base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
72       base::TimeDelta::FromSeconds(kAccessibilityHistogramDelaySecs));
73 }
74
75 BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
76 }
77
78 void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
79   if (CommandLine::ForCurrentProcess()->HasSwitch(
80           switches::kDisableRendererAccessibility)) {
81     return;
82   }
83   SetAccessibilityMode(AccessibilityModeComplete);
84 }
85
86 void BrowserAccessibilityStateImpl::EnableAccessibility() {
87   // We may want to do something different with this later.
88   SetAccessibilityMode(AccessibilityModeComplete);
89 }
90
91 void BrowserAccessibilityStateImpl::DisableAccessibility() {
92   SetAccessibilityMode(AccessibilityModeOff);
93 }
94
95 bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
96   return (accessibility_mode_ == AccessibilityModeComplete);
97 }
98
99 void BrowserAccessibilityStateImpl::AddHistogramCallback(
100     base::Closure callback) {
101   histogram_callbacks_.push_back(callback);
102 }
103
104 void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
105   UpdateHistograms();
106 }
107
108 void BrowserAccessibilityStateImpl::UpdateHistograms() {
109   UpdatePlatformSpecificHistograms();
110
111   for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
112     histogram_callbacks_[i].Run();
113
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));
120 }
121
122 #if !defined(OS_WIN)
123 void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
124 }
125 #endif
126
127 void BrowserAccessibilityStateImpl::SetAccessibilityMode(
128     AccessibilityMode mode) {
129   if (accessibility_mode_ == mode)
130     return;
131   accessibility_mode_ = mode;
132
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())
140       continue;
141     if (!widget->IsRenderView())
142       continue;
143
144     RenderWidgetHostImpl::From(widget)->SetAccessibilityMode(mode);
145   }
146 }
147
148 }  // namespace content