blob: 2c185d0ad170cd1053f0794d57ca39a717299acf [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"
Gabriel Charette44db1422018-08-06 11:19:3311#include "base/task/post_task.h"
avib7348942015-12-25 20:57:1012#include "build/build_config.h"
[email protected]df376972013-05-03 21:45:0313#include "content/browser/renderer_host/render_widget_host_impl.h"
[email protected]95640212014-07-26 18:14:3014#include "content/browser/web_contents/web_contents_impl.h"
Eric Seckler8652dcd52018-09-20 10:42:2815#include "content/public/browser/browser_task_traits.h"
[email protected]18df7362012-10-24 01:29:4016#include "content/public/browser/browser_thread.h"
[email protected]3e3c4522012-04-13 21:16:2917#include "content/public/common/content_switches.h"
Doug Turneraff275f2017-08-15 22:40:3518#include "ui/accessibility/platform/ax_platform_node.h"
mlamouri20bb4c4a2015-07-08 14:30:2219#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2620
[email protected]e6b34872012-10-24 20:51:3221namespace content {
22
dmazzoni368ea132016-12-20 08:22:4223// IMPORTANT!
24// These values are written to logs. Do not renumber or delete
25// existing items; add new entries to the end of the list.
26enum ModeFlagHistogramValue {
dougtcd3dad732017-03-14 03:26:2327 UMA_AX_MODE_NATIVE_APIS = 0,
28 UMA_AX_MODE_WEB_CONTENTS = 1,
29 UMA_AX_MODE_INLINE_TEXT_BOXES = 2,
30 UMA_AX_MODE_SCREEN_READER = 3,
31 UMA_AX_MODE_HTML = 4,
dmazzoni368ea132016-12-20 08:22:4232
33 // This must always be the last enum. It's okay for its value to
34 // increase, but none of the other enum values may change.
dougtcd3dad732017-03-14 03:26:2335 UMA_AX_MODE_MAX
dmazzoni368ea132016-12-20 08:22:4236};
37
38// Record a histograms for an accessibility mode when it's enabled.
39void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
dougtcd3dad732017-03-14 03:26:2340 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag", mode_flag,
41 UMA_AX_MODE_MAX);
dmazzoni368ea132016-12-20 08:22:4242}
43
[email protected]fa4f91682012-02-21 19:53:2644// Update the accessibility histogram 45 seconds after initialization.
dmazzoni368ea132016-12-20 08:22:4245static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;
[email protected]fa4f91682012-02-21 19:53:2646
47// static
48BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
49 return BrowserAccessibilityStateImpl::GetInstance();
50}
51
52// static
53BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2254 return base::Singleton<
55 BrowserAccessibilityStateImpl,
56 base::LeakySingletonTraits<BrowserAccessibilityStateImpl>>::get();
[email protected]fa4f91682012-02-21 19:53:2657}
58
59BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
60 : BrowserAccessibilityState(),
dmazzonidea5ba62015-02-03 19:27:2461 disable_hot_tracking_(false) {
[email protected]1e558fa2014-02-12 23:28:5262 ResetAccessibilityModeValue();
[email protected]882db442012-12-04 16:37:5463
64 // We need to AddRef() the leaky singleton so that Bind doesn't
[email protected]3c17ae742012-10-24 17:37:2665 // delete it prematurely.
66 AddRef();
sebmarchand41f774b2017-05-23 21:50:2167
Doug Turneraff275f2017-08-15 22:40:3568 // Hook ourselves up to observe ax mode changes.
69 ui::AXPlatformNode::AddAXModeObserver(this);
70
Dominic Mazzoni190a6cd2018-09-26 11:24:0871 // Let each platform do its own initialization.
72 PlatformInitialize();
73
sebmarchand41f774b2017-05-23 21:50:2174#if defined(OS_WIN)
75 // The delay is necessary because assistive technology sometimes isn't
76 // detected until after the user interacts in some way, so a reasonable delay
77 // gives us better numbers.
78 base::PostDelayedTaskWithTraits(
Gabriel Charetteb10aeeb2018-07-26 20:15:0079 FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
[email protected]30fdb362013-01-09 02:33:2780 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
dmazzoni368ea132016-12-20 08:22:4281 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
sebmarchand41f774b2017-05-23 21:50:2182#else
83 // On all other platforms, UpdateHistograms should be called on the UI
84 // thread because it needs to be able to access PrefService.
Eric Seckler8652dcd52018-09-20 10:42:2885 base::PostDelayedTaskWithTraits(
86 FROM_HERE, {BrowserThread::UI},
tzik4fea24af2017-08-23 11:41:4787 base::BindOnce(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
sebmarchand41f774b2017-05-23 21:50:2188 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
89#endif
[email protected]fa4f91682012-02-21 19:53:2690}
91
92BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
Doug Turneraff275f2017-08-15 22:40:3593 // Remove ourselves from the AXMode global observer list.
94 ui::AXPlatformNode::RemoveAXModeObserver(this);
[email protected]fa4f91682012-02-21 19:53:2695}
96
97void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:0998 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:2499 switches::kDisableRendererAccessibility)) {
100 return;
101 }
102 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:26103}
104
[email protected]df376972013-05-03 21:45:03105void BrowserAccessibilityStateImpl::EnableAccessibility() {
Doug Turner63f3c7b2017-07-29 05:10:01106 AddAccessibilityModeFlags(ui::kAXModeComplete);
[email protected]fa4f91682012-02-21 19:53:26107}
108
[email protected]df376972013-05-03 21:45:03109void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:52110 ResetAccessibilityMode();
111}
112
James Wallace-Leeeafc94cb92018-07-23 21:35:09113bool BrowserAccessibilityStateImpl::IsRendererAccessibilityEnabled() {
114 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
115 switches::kDisableRendererAccessibility);
116}
117
[email protected]1e558fa2014-02-12 23:28:52118void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
Doug Turner63f3c7b2017-07-29 05:10:01119 accessibility_mode_ = ui::AXMode();
[email protected]479278702014-08-11 20:32:09120 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52121 switches::kForceRendererAccessibility)) {
Doug Turner63f3c7b2017-07-29 05:10:01122 accessibility_mode_ = ui::kAXModeComplete;
[email protected]1e558fa2014-02-12 23:28:52123 }
124}
125
126void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
127 ResetAccessibilityModeValue();
128
[email protected]95640212014-07-26 18:14:30129 std::vector<WebContentsImpl*> web_contents_vector =
130 WebContentsImpl::GetAllWebContents();
131 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09132 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]df376972013-05-03 21:45:03133}
134
[email protected]fa4f91682012-02-21 19:53:26135bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
Doug Turner63f3c7b2017-07-29 05:10:01136 return accessibility_mode_ == ui::kAXModeComplete;
[email protected]fa4f91682012-02-21 19:53:26137}
138
[email protected]89430152012-12-03 19:18:56139void BrowserAccessibilityStateImpl::AddHistogramCallback(
140 base::Closure callback) {
Tommy Nyquist4b749d02018-03-20 21:46:29141 histogram_callbacks_.push_back(std::move(callback));
[email protected]89430152012-12-03 19:18:56142}
143
[email protected]30fdb362013-01-09 02:33:27144void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
145 UpdateHistograms();
146}
147
148void BrowserAccessibilityStateImpl::UpdateHistograms() {
[email protected]18df7362012-10-24 01:29:40149 UpdatePlatformSpecificHistograms();
150
[email protected]89430152012-12-03 19:18:56151 for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
152 histogram_callbacks_[i].Run();
153
dmazzoni368ea132016-12-20 08:22:42154 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
155 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40156 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42157
[email protected]18df7362012-10-24 01:29:40158 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22159 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40160 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09161 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40162 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26163}
[email protected]e2fa1cca42012-08-22 14:07:27164
Doug Turneraff275f2017-08-15 22:40:35165void BrowserAccessibilityStateImpl::OnAXModeAdded(ui::AXMode mode) {
166 AddAccessibilityModeFlags(mode);
167}
168
James Wallace-Leeeafc94cb92018-07-23 21:35:09169ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const {
170 return accessibility_mode_;
171}
172
ellyjonesa577c6cb2016-04-01 22:31:03173#if !defined(OS_WIN) && !defined(OS_MACOSX)
Dominic Mazzoni190a6cd2018-09-26 11:24:08174void BrowserAccessibilityStateImpl::PlatformInitialize() {}
175
[email protected]18df7362012-10-24 01:29:40176void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
177}
178#endif
179
Doug Turner63f3c7b2017-07-29 05:10:01180void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09181 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52182 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03183 return;
[email protected]1e558fa2014-02-12 23:28:52184 }
[email protected]df376972013-05-03 21:45:03185
Doug Turner63f3c7b2017-07-29 05:10:01186 ui::AXMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01187 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42188 if (accessibility_mode_ == previous_mode)
189 return;
190
191 // Retrieve only newly added modes for the purposes of logging.
dougtcd3dad732017-03-14 03:26:23192 int new_mode_flags = mode.mode() & (~previous_mode.mode());
Doug Turner63f3c7b2017-07-29 05:10:01193 if (new_mode_flags & ui::AXMode::kNativeAPIs)
dougtcd3dad732017-03-14 03:26:23194 RecordNewAccessibilityModeFlags(UMA_AX_MODE_NATIVE_APIS);
Doug Turner63f3c7b2017-07-29 05:10:01195 if (new_mode_flags & ui::AXMode::kWebContents)
dougtcd3dad732017-03-14 03:26:23196 RecordNewAccessibilityModeFlags(UMA_AX_MODE_WEB_CONTENTS);
Doug Turner63f3c7b2017-07-29 05:10:01197 if (new_mode_flags & ui::AXMode::kInlineTextBoxes)
dougtcd3dad732017-03-14 03:26:23198 RecordNewAccessibilityModeFlags(UMA_AX_MODE_INLINE_TEXT_BOXES);
Doug Turner63f3c7b2017-07-29 05:10:01199 if (new_mode_flags & ui::AXMode::kScreenReader)
dougtcd3dad732017-03-14 03:26:23200 RecordNewAccessibilityModeFlags(UMA_AX_MODE_SCREEN_READER);
Doug Turner63f3c7b2017-07-29 05:10:01201 if (new_mode_flags & ui::AXMode::kHTML)
dougtcd3dad732017-03-14 03:26:23202 RecordNewAccessibilityModeFlags(UMA_AX_MODE_HTML);
dmazzoni368ea132016-12-20 08:22:42203
dmazzonidd3d51a72016-12-14 18:41:01204 std::vector<WebContentsImpl*> web_contents_vector =
205 WebContentsImpl::GetAllWebContents();
206 for (size_t i = 0; i < web_contents_vector.size(); ++i)
207 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52208}
209
dmazzonidd3d51a72016-12-14 18:41:01210void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
Doug Turner63f3c7b2017-07-29 05:10:01211 ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09212 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52213 switches::kForceRendererAccessibility) &&
Doug Turner63f3c7b2017-07-29 05:10:01214 mode == ui::kAXModeComplete) {
[email protected]1e558fa2014-02-12 23:28:52215 return;
216 }
217
dougtcd3dad732017-03-14 03:26:23218 int raw_flags =
219 accessibility_mode_.mode() ^ (mode.mode() & accessibility_mode_.mode());
220 accessibility_mode_ = raw_flags;
221
[email protected]95640212014-07-26 18:14:30222 std::vector<WebContentsImpl*> web_contents_vector =
223 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01224 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09225 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]e2fa1cca42012-08-22 14:07:27226}
[email protected]e6b34872012-10-24 20:51:32227
228} // namespace content