blob: 6a8924bc3382b146d97adc561bca612f5f71dd30 [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
Sebastien Marchandf8cbfab2019-01-25 16:02:309#include "base/bind.h"
[email protected]3e3c4522012-04-13 21:16:2910#include "base/command_line.h"
asvitkine30330812016-08-30 04:01:0811#include "base/metrics/histogram_macros.h"
Gabriel Charette44db1422018-08-06 11:19:3312#include "base/task/post_task.h"
avib7348942015-12-25 20:57:1013#include "build/build_config.h"
[email protected]df376972013-05-03 21:45:0314#include "content/browser/renderer_host/render_widget_host_impl.h"
[email protected]95640212014-07-26 18:14:3015#include "content/browser/web_contents/web_contents_impl.h"
Eric Seckler8652dcd52018-09-20 10:42:2816#include "content/public/browser/browser_task_traits.h"
[email protected]18df7362012-10-24 01:29:4017#include "content/public/browser/browser_thread.h"
[email protected]3e3c4522012-04-13 21:16:2918#include "content/public/common/content_switches.h"
Doug Turneraff275f2017-08-15 22:40:3519#include "ui/accessibility/platform/ax_platform_node.h"
mlamouri20bb4c4a2015-07-08 14:30:2220#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2621
[email protected]e6b34872012-10-24 20:51:3222namespace content {
23
dmazzoni368ea132016-12-20 08:22:4224// IMPORTANT!
25// These values are written to logs. Do not renumber or delete
26// existing items; add new entries to the end of the list.
27enum ModeFlagHistogramValue {
dougtcd3dad732017-03-14 03:26:2328 UMA_AX_MODE_NATIVE_APIS = 0,
29 UMA_AX_MODE_WEB_CONTENTS = 1,
30 UMA_AX_MODE_INLINE_TEXT_BOXES = 2,
31 UMA_AX_MODE_SCREEN_READER = 3,
32 UMA_AX_MODE_HTML = 4,
dmazzoni368ea132016-12-20 08:22:4233
34 // This must always be the last enum. It's okay for its value to
35 // increase, but none of the other enum values may change.
dougtcd3dad732017-03-14 03:26:2336 UMA_AX_MODE_MAX
dmazzoni368ea132016-12-20 08:22:4237};
38
39// Record a histograms for an accessibility mode when it's enabled.
40void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
dougtcd3dad732017-03-14 03:26:2341 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag", mode_flag,
42 UMA_AX_MODE_MAX);
dmazzoni368ea132016-12-20 08:22:4243}
44
[email protected]fa4f91682012-02-21 19:53:2645// Update the accessibility histogram 45 seconds after initialization.
dmazzoni368ea132016-12-20 08:22:4246static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;
[email protected]fa4f91682012-02-21 19:53:2647
48// static
49BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
50 return BrowserAccessibilityStateImpl::GetInstance();
51}
52
53// static
54BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2255 return base::Singleton<
56 BrowserAccessibilityStateImpl,
57 base::LeakySingletonTraits<BrowserAccessibilityStateImpl>>::get();
[email protected]fa4f91682012-02-21 19:53:2658}
59
60BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
Aran Gilman0bdeadbf2019-03-05 01:15:4161 : BrowserAccessibilityState(), 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
Dominic Mazzonic8cece522019-04-16 21:30:3574 // Schedule calls to update histograms after a delay.
75 //
sebmarchand41f774b2017-05-23 21:50:2176 // The delay is necessary because assistive technology sometimes isn't
77 // detected until after the user interacts in some way, so a reasonable delay
78 // gives us better numbers.
Dominic Mazzonic8cece522019-04-16 21:30:3579
80 // Some things can be done on another thread safely.
sebmarchand41f774b2017-05-23 21:50:2181 base::PostDelayedTaskWithTraits(
Gabriel Charetteb10aeeb2018-07-26 20:15:0082 FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
Dominic Mazzonic8cece522019-04-16 21:30:3583 base::BindOnce(
84 &BrowserAccessibilityStateImpl::UpdateHistogramsOnOtherThread, this),
dmazzoni368ea132016-12-20 08:22:4285 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
Dominic Mazzonic8cece522019-04-16 21:30:3586
87 // Other things must be done on the UI thread (e.g. to access PrefService).
Eric Seckler8652dcd52018-09-20 10:42:2888 base::PostDelayedTaskWithTraits(
89 FROM_HERE, {BrowserThread::UI},
Dominic Mazzonic8cece522019-04-16 21:30:3590 base::BindOnce(&BrowserAccessibilityStateImpl::UpdateHistogramsOnUIThread,
91 this),
sebmarchand41f774b2017-05-23 21:50:2192 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
[email protected]fa4f91682012-02-21 19:53:2693}
94
95BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
Doug Turneraff275f2017-08-15 22:40:3596 // Remove ourselves from the AXMode global observer list.
97 ui::AXPlatformNode::RemoveAXModeObserver(this);
[email protected]fa4f91682012-02-21 19:53:2698}
99
100void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:09101 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:24102 switches::kDisableRendererAccessibility)) {
103 return;
104 }
105 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:26106}
107
[email protected]df376972013-05-03 21:45:03108void BrowserAccessibilityStateImpl::EnableAccessibility() {
Doug Turner63f3c7b2017-07-29 05:10:01109 AddAccessibilityModeFlags(ui::kAXModeComplete);
[email protected]fa4f91682012-02-21 19:53:26110}
111
[email protected]df376972013-05-03 21:45:03112void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:52113 ResetAccessibilityMode();
114}
115
James Wallace-Leeeafc94cb92018-07-23 21:35:09116bool BrowserAccessibilityStateImpl::IsRendererAccessibilityEnabled() {
117 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kDisableRendererAccessibility);
119}
120
[email protected]1e558fa2014-02-12 23:28:52121void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
Doug Turner63f3c7b2017-07-29 05:10:01122 accessibility_mode_ = ui::AXMode();
[email protected]479278702014-08-11 20:32:09123 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52124 switches::kForceRendererAccessibility)) {
Doug Turner63f3c7b2017-07-29 05:10:01125 accessibility_mode_ = ui::kAXModeComplete;
[email protected]1e558fa2014-02-12 23:28:52126 }
127}
128
129void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
130 ResetAccessibilityModeValue();
131
[email protected]95640212014-07-26 18:14:30132 std::vector<WebContentsImpl*> web_contents_vector =
133 WebContentsImpl::GetAllWebContents();
134 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09135 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]df376972013-05-03 21:45:03136}
137
[email protected]fa4f91682012-02-21 19:53:26138bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
Doug Turner63f3c7b2017-07-29 05:10:01139 return accessibility_mode_ == ui::kAXModeComplete;
[email protected]fa4f91682012-02-21 19:53:26140}
141
Dominic Mazzonic8cece522019-04-16 21:30:35142void BrowserAccessibilityStateImpl::AddUIThreadHistogramCallback(
143 base::OnceClosure callback) {
144 ui_thread_histogram_callbacks_.push_back(std::move(callback));
145}
146
147void BrowserAccessibilityStateImpl::AddOtherThreadHistogramCallback(
148 base::OnceClosure callback) {
149 other_thread_histogram_callbacks_.push_back(std::move(callback));
[email protected]89430152012-12-03 19:18:56150}
151
[email protected]30fdb362013-01-09 02:33:27152void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
Dominic Mazzonic8cece522019-04-16 21:30:35153 UpdateHistogramsOnUIThread();
154 UpdateHistogramsOnOtherThread();
[email protected]30fdb362013-01-09 02:33:27155}
156
Dominic Mazzonic8cece522019-04-16 21:30:35157void BrowserAccessibilityStateImpl::UpdateHistogramsOnUIThread() {
158 UpdatePlatformSpecificHistogramsOnUIThread();
[email protected]18df7362012-10-24 01:29:40159
Dominic Mazzonic8cece522019-04-16 21:30:35160 for (auto& callback : ui_thread_histogram_callbacks_)
161 std::move(callback).Run();
162 ui_thread_histogram_callbacks_.clear();
[email protected]89430152012-12-03 19:18:56163
dmazzoni368ea132016-12-20 08:22:42164 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
165 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40166 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42167
[email protected]18df7362012-10-24 01:29:40168 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22169 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40170 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09171 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40172 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26173}
[email protected]e2fa1cca42012-08-22 14:07:27174
Dominic Mazzonic8cece522019-04-16 21:30:35175void BrowserAccessibilityStateImpl::UpdateHistogramsOnOtherThread() {
176 UpdatePlatformSpecificHistogramsOnOtherThread();
177
178 for (auto& callback : other_thread_histogram_callbacks_)
179 std::move(callback).Run();
180 other_thread_histogram_callbacks_.clear();
181}
182
Doug Turneraff275f2017-08-15 22:40:35183void BrowserAccessibilityStateImpl::OnAXModeAdded(ui::AXMode mode) {
184 AddAccessibilityModeFlags(mode);
185}
186
Lucas Furukawa Gadanid726e1e2019-05-08 16:20:03187ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() {
James Wallace-Leeeafc94cb92018-07-23 21:35:09188 return accessibility_mode_;
189}
190
Stephen McGruera73dfdb2018-11-14 18:19:47191#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_MACOSX)
Dominic Mazzoni190a6cd2018-09-26 11:24:08192void BrowserAccessibilityStateImpl::PlatformInitialize() {}
193
Dominic Mazzonic8cece522019-04-16 21:30:35194void BrowserAccessibilityStateImpl::
195 UpdatePlatformSpecificHistogramsOnUIThread() {}
196void BrowserAccessibilityStateImpl::
197 UpdatePlatformSpecificHistogramsOnOtherThread() {}
[email protected]18df7362012-10-24 01:29:40198#endif
199
Doug Turner63f3c7b2017-07-29 05:10:01200void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09201 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52202 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03203 return;
[email protected]1e558fa2014-02-12 23:28:52204 }
[email protected]df376972013-05-03 21:45:03205
Doug Turner63f3c7b2017-07-29 05:10:01206 ui::AXMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01207 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42208 if (accessibility_mode_ == previous_mode)
209 return;
210
211 // Retrieve only newly added modes for the purposes of logging.
dougtcd3dad732017-03-14 03:26:23212 int new_mode_flags = mode.mode() & (~previous_mode.mode());
Doug Turner63f3c7b2017-07-29 05:10:01213 if (new_mode_flags & ui::AXMode::kNativeAPIs)
dougtcd3dad732017-03-14 03:26:23214 RecordNewAccessibilityModeFlags(UMA_AX_MODE_NATIVE_APIS);
Doug Turner63f3c7b2017-07-29 05:10:01215 if (new_mode_flags & ui::AXMode::kWebContents)
dougtcd3dad732017-03-14 03:26:23216 RecordNewAccessibilityModeFlags(UMA_AX_MODE_WEB_CONTENTS);
Doug Turner63f3c7b2017-07-29 05:10:01217 if (new_mode_flags & ui::AXMode::kInlineTextBoxes)
dougtcd3dad732017-03-14 03:26:23218 RecordNewAccessibilityModeFlags(UMA_AX_MODE_INLINE_TEXT_BOXES);
Doug Turner63f3c7b2017-07-29 05:10:01219 if (new_mode_flags & ui::AXMode::kScreenReader)
dougtcd3dad732017-03-14 03:26:23220 RecordNewAccessibilityModeFlags(UMA_AX_MODE_SCREEN_READER);
Doug Turner63f3c7b2017-07-29 05:10:01221 if (new_mode_flags & ui::AXMode::kHTML)
dougtcd3dad732017-03-14 03:26:23222 RecordNewAccessibilityModeFlags(UMA_AX_MODE_HTML);
dmazzoni368ea132016-12-20 08:22:42223
dmazzonidd3d51a72016-12-14 18:41:01224 std::vector<WebContentsImpl*> web_contents_vector =
225 WebContentsImpl::GetAllWebContents();
226 for (size_t i = 0; i < web_contents_vector.size(); ++i)
227 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52228}
229
dmazzonidd3d51a72016-12-14 18:41:01230void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
Doug Turner63f3c7b2017-07-29 05:10:01231 ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09232 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52233 switches::kForceRendererAccessibility) &&
Doug Turner63f3c7b2017-07-29 05:10:01234 mode == ui::kAXModeComplete) {
[email protected]1e558fa2014-02-12 23:28:52235 return;
236 }
237
dougtcd3dad732017-03-14 03:26:23238 int raw_flags =
239 accessibility_mode_.mode() ^ (mode.mode() & accessibility_mode_.mode());
240 accessibility_mode_ = raw_flags;
241
[email protected]95640212014-07-26 18:14:30242 std::vector<WebContentsImpl*> web_contents_vector =
243 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01244 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09245 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]e2fa1cca42012-08-22 14:07:27246}
[email protected]e6b34872012-10-24 20:51:32247
248} // namespace content