blob: fcd5ba5e8e8408f6efb2c273382f173031b1044f [file] [log] [blame]
[email protected]fa4f91682012-02-21 19:53:261// 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
avib7348942015-12-25 20:57:107#include <stddef.h>
8
[email protected]3e3c4522012-04-13 21:16:299#include "base/command_line.h"
asvitkine30330812016-08-30 04:01:0810#include "base/metrics/histogram_macros.h"
avib7348942015-12-25 20:57:1011#include "build/build_config.h"
[email protected]df376972013-05-03 21:45:0312#include "content/browser/renderer_host/render_widget_host_impl.h"
[email protected]95640212014-07-26 18:14:3013#include "content/browser/web_contents/web_contents_impl.h"
[email protected]18df7362012-10-24 01:29:4014#include "content/public/browser/browser_thread.h"
[email protected]3e3c4522012-04-13 21:16:2915#include "content/public/common/content_switches.h"
mlamouri20bb4c4a2015-07-08 14:30:2216#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2617
[email protected]e6b34872012-10-24 20:51:3218namespace content {
19
dmazzoni368ea132016-12-20 08:22:4220// IMPORTANT!
21// These values are written to logs. Do not renumber or delete
22// existing items; add new entries to the end of the list.
23enum ModeFlagHistogramValue {
24 UMA_AX_MODE_FLAG_NATIVE_APIS = 0,
25 UMA_AX_MODE_FLAG_WEB_CONTENTS = 1,
26 UMA_AX_MODE_FLAG_INLINE_TEXT_BOXES = 2,
27 UMA_AX_MODE_FLAG_SCREEN_READER = 3,
28 UMA_AX_MODE_FLAG_HTML = 4,
29
30 // This must always be the last enum. It's okay for its value to
31 // increase, but none of the other enum values may change.
32 UMA_AX_MODE_FLAG_MAX
33};
34
35// Record a histograms for an accessibility mode when it's enabled.
36void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
37 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag",
38 mode_flag,
39 UMA_AX_MODE_FLAG_MAX);
40}
41
[email protected]fa4f91682012-02-21 19:53:2642// Update the accessibility histogram 45 seconds after initialization.
dmazzoni368ea132016-12-20 08:22:4243static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;
[email protected]fa4f91682012-02-21 19:53:2644
45// static
46BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
47 return BrowserAccessibilityStateImpl::GetInstance();
48}
49
50// static
51BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2252 return base::Singleton<
53 BrowserAccessibilityStateImpl,
54 base::LeakySingletonTraits<BrowserAccessibilityStateImpl>>::get();
[email protected]fa4f91682012-02-21 19:53:2655}
56
57BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
58 : BrowserAccessibilityState(),
dmazzonidea5ba62015-02-03 19:27:2459 accessibility_mode_(AccessibilityModeOff),
60 disable_hot_tracking_(false) {
[email protected]1e558fa2014-02-12 23:28:5261 ResetAccessibilityModeValue();
[email protected]882db442012-12-04 16:37:5462#if defined(OS_WIN)
[email protected]30fdb362013-01-09 02:33:2763 // On Windows, UpdateHistograms calls some system functions with unknown
[email protected]882db442012-12-04 16:37:5464 // runtime, so call it on the file thread to ensure there's no jank.
65 // Everything in that method must be safe to call on another thread.
66 BrowserThread::ID update_histogram_thread = BrowserThread::FILE;
67#else
[email protected]30fdb362013-01-09 02:33:2768 // On all other platforms, UpdateHistograms should be called on the main
[email protected]882db442012-12-04 16:37:5469 // thread.
70 BrowserThread::ID update_histogram_thread = BrowserThread::UI;
71#endif
72
73 // We need to AddRef() the leaky singleton so that Bind doesn't
[email protected]3c17ae742012-10-24 17:37:2674 // delete it prematurely.
75 AddRef();
[email protected]e6b34872012-10-24 20:51:3276 BrowserThread::PostDelayedTask(
[email protected]882db442012-12-04 16:37:5477 update_histogram_thread, FROM_HERE,
[email protected]30fdb362013-01-09 02:33:2778 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
dmazzoni368ea132016-12-20 08:22:4279 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
[email protected]fa4f91682012-02-21 19:53:2680}
81
82BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
83}
84
85void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:0986 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:2487 switches::kDisableRendererAccessibility)) {
88 return;
89 }
90 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:2691}
92
[email protected]df376972013-05-03 21:45:0393void BrowserAccessibilityStateImpl::EnableAccessibility() {
dmazzonidd3d51a72016-12-14 18:41:0194 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_COMPLETE);
[email protected]fa4f91682012-02-21 19:53:2695}
96
[email protected]df376972013-05-03 21:45:0397void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:5298 ResetAccessibilityMode();
99}
100
101void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
102 accessibility_mode_ = AccessibilityModeOff;
[email protected]479278702014-08-11 20:32:09103 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52104 switches::kForceRendererAccessibility)) {
dmazzonidd3d51a72016-12-14 18:41:01105 accessibility_mode_ = ACCESSIBILITY_MODE_COMPLETE;
[email protected]1e558fa2014-02-12 23:28:52106 }
107}
108
109void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
110 ResetAccessibilityModeValue();
111
[email protected]95640212014-07-26 18:14:30112 std::vector<WebContentsImpl*> web_contents_vector =
113 WebContentsImpl::GetAllWebContents();
114 for (size_t i = 0; i < web_contents_vector.size(); ++i)
115 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode());
[email protected]df376972013-05-03 21:45:03116}
117
[email protected]fa4f91682012-02-21 19:53:26118bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
dmazzonidd3d51a72016-12-14 18:41:01119 return ((accessibility_mode_ & ACCESSIBILITY_MODE_COMPLETE) ==
120 ACCESSIBILITY_MODE_COMPLETE);
[email protected]fa4f91682012-02-21 19:53:26121}
122
[email protected]89430152012-12-03 19:18:56123void BrowserAccessibilityStateImpl::AddHistogramCallback(
124 base::Closure callback) {
125 histogram_callbacks_.push_back(callback);
126}
127
[email protected]30fdb362013-01-09 02:33:27128void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
129 UpdateHistograms();
130}
131
132void BrowserAccessibilityStateImpl::UpdateHistograms() {
[email protected]18df7362012-10-24 01:29:40133 UpdatePlatformSpecificHistograms();
134
[email protected]89430152012-12-03 19:18:56135 for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
136 histogram_callbacks_[i].Run();
137
dmazzoni368ea132016-12-20 08:22:42138 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
139 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40140 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42141
[email protected]18df7362012-10-24 01:29:40142 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22143 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40144 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09145 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40146 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26147}
[email protected]e2fa1cca42012-08-22 14:07:27148
ellyjonesa577c6cb2016-04-01 22:31:03149#if !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]18df7362012-10-24 01:29:40150void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
151}
152#endif
153
dmazzonidd3d51a72016-12-14 18:41:01154void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(
[email protected]e2fa1cca42012-08-22 14:07:27155 AccessibilityMode mode) {
[email protected]479278702014-08-11 20:32:09156 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52157 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03158 return;
[email protected]1e558fa2014-02-12 23:28:52159 }
[email protected]df376972013-05-03 21:45:03160
dmazzoni368ea132016-12-20 08:22:42161 AccessibilityMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01162 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42163 if (accessibility_mode_ == previous_mode)
164 return;
165
166 // Retrieve only newly added modes for the purposes of logging.
167 AccessibilityMode new_mode_flags = accessibility_mode_ & (~previous_mode);
168 if (new_mode_flags & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS)
169 RecordNewAccessibilityModeFlags(UMA_AX_MODE_FLAG_NATIVE_APIS);
170 if (new_mode_flags & ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS)
171 RecordNewAccessibilityModeFlags(UMA_AX_MODE_FLAG_WEB_CONTENTS);
172 if (new_mode_flags & ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES)
173 RecordNewAccessibilityModeFlags(UMA_AX_MODE_FLAG_INLINE_TEXT_BOXES);
174 if (new_mode_flags & ACCESSIBILITY_MODE_FLAG_SCREEN_READER)
175 RecordNewAccessibilityModeFlags(UMA_AX_MODE_FLAG_SCREEN_READER);
176 if (new_mode_flags & ACCESSIBILITY_MODE_FLAG_HTML)
177 RecordNewAccessibilityModeFlags(UMA_AX_MODE_FLAG_HTML);
178
dmazzonidd3d51a72016-12-14 18:41:01179 std::vector<WebContentsImpl*> web_contents_vector =
180 WebContentsImpl::GetAllWebContents();
181 for (size_t i = 0; i < web_contents_vector.size(); ++i)
182 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52183}
184
dmazzonidd3d51a72016-12-14 18:41:01185void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
[email protected]1e558fa2014-02-12 23:28:52186 AccessibilityMode mode) {
[email protected]479278702014-08-11 20:32:09187 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52188 switches::kForceRendererAccessibility) &&
dmazzonidd3d51a72016-12-14 18:41:01189 mode == ACCESSIBILITY_MODE_COMPLETE) {
[email protected]1e558fa2014-02-12 23:28:52190 return;
191 }
192
dmazzonidd3d51a72016-12-14 18:41:01193 accessibility_mode_ = accessibility_mode_ ^ (mode & accessibility_mode_);
[email protected]95640212014-07-26 18:14:30194 std::vector<WebContentsImpl*> web_contents_vector =
195 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01196 for (size_t i = 0; i < web_contents_vector.size(); ++i)
197 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode());
[email protected]e2fa1cca42012-08-22 14:07:27198}
[email protected]e6b34872012-10-24 20:51:32199
200} // namespace content