blob: 73a764269ee6da779b351c69c5e64d23ab961b7c [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"
Aaron Leventhal30b2ceb2019-08-09 19:05:4111#include "base/metrics/histogram_functions.h"
asvitkine30330812016-08-30 04:01:0812#include "base/metrics/histogram_macros.h"
Gabriel Charette44db1422018-08-06 11:19:3313#include "base/task/post_task.h"
avib7348942015-12-25 20:57:1014#include "build/build_config.h"
[email protected]df376972013-05-03 21:45:0315#include "content/browser/renderer_host/render_widget_host_impl.h"
[email protected]95640212014-07-26 18:14:3016#include "content/browser/web_contents/web_contents_impl.h"
Eric Seckler8652dcd52018-09-20 10:42:2817#include "content/public/browser/browser_task_traits.h"
[email protected]18df7362012-10-24 01:29:4018#include "content/public/browser/browser_thread.h"
[email protected]3e3c4522012-04-13 21:16:2919#include "content/public/common/content_switches.h"
Doug Turneraff275f2017-08-15 22:40:3520#include "ui/accessibility/platform/ax_platform_node.h"
mlamouri20bb4c4a2015-07-08 14:30:2221#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2622
[email protected]e6b34872012-10-24 20:51:3223namespace content {
24
dmazzoni368ea132016-12-20 08:22:4225// IMPORTANT!
26// These values are written to logs. Do not renumber or delete
27// existing items; add new entries to the end of the list.
28enum ModeFlagHistogramValue {
dougtcd3dad732017-03-14 03:26:2329 UMA_AX_MODE_NATIVE_APIS = 0,
30 UMA_AX_MODE_WEB_CONTENTS = 1,
31 UMA_AX_MODE_INLINE_TEXT_BOXES = 2,
32 UMA_AX_MODE_SCREEN_READER = 3,
33 UMA_AX_MODE_HTML = 4,
dmazzoni368ea132016-12-20 08:22:4234
35 // This must always be the last enum. It's okay for its value to
36 // increase, but none of the other enum values may change.
dougtcd3dad732017-03-14 03:26:2337 UMA_AX_MODE_MAX
dmazzoni368ea132016-12-20 08:22:4238};
39
40// Record a histograms for an accessibility mode when it's enabled.
41void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
dougtcd3dad732017-03-14 03:26:2342 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag", mode_flag,
43 UMA_AX_MODE_MAX);
dmazzoni368ea132016-12-20 08:22:4244}
45
[email protected]fa4f91682012-02-21 19:53:2646// Update the accessibility histogram 45 seconds after initialization.
dmazzoni368ea132016-12-20 08:22:4247static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;
[email protected]fa4f91682012-02-21 19:53:2648
49// static
50BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
51 return BrowserAccessibilityStateImpl::GetInstance();
52}
53
54// static
55BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2256 return base::Singleton<
57 BrowserAccessibilityStateImpl,
58 base::LeakySingletonTraits<BrowserAccessibilityStateImpl>>::get();
[email protected]fa4f91682012-02-21 19:53:2659}
60
61BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
Aran Gilman0bdeadbf2019-03-05 01:15:4162 : BrowserAccessibilityState(), disable_hot_tracking_(false) {
[email protected]1e558fa2014-02-12 23:28:5263 ResetAccessibilityModeValue();
[email protected]882db442012-12-04 16:37:5464
65 // We need to AddRef() the leaky singleton so that Bind doesn't
[email protected]3c17ae742012-10-24 17:37:2666 // delete it prematurely.
67 AddRef();
sebmarchand41f774b2017-05-23 21:50:2168
Doug Turneraff275f2017-08-15 22:40:3569 // Hook ourselves up to observe ax mode changes.
70 ui::AXPlatformNode::AddAXModeObserver(this);
71
Dominic Mazzoni190a6cd2018-09-26 11:24:0872 // Let each platform do its own initialization.
73 PlatformInitialize();
74
Dominic Mazzonic8cece522019-04-16 21:30:3575 // Schedule calls to update histograms after a delay.
76 //
sebmarchand41f774b2017-05-23 21:50:2177 // The delay is necessary because assistive technology sometimes isn't
78 // detected until after the user interacts in some way, so a reasonable delay
79 // gives us better numbers.
Dominic Mazzonic8cece522019-04-16 21:30:3580
81 // Some things can be done on another thread safely.
sebmarchand41f774b2017-05-23 21:50:2182 base::PostDelayedTaskWithTraits(
Gabriel Charetteb10aeeb2018-07-26 20:15:0083 FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
Dominic Mazzonic8cece522019-04-16 21:30:3584 base::BindOnce(
85 &BrowserAccessibilityStateImpl::UpdateHistogramsOnOtherThread, this),
dmazzoni368ea132016-12-20 08:22:4286 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
Dominic Mazzonic8cece522019-04-16 21:30:3587
88 // Other things must be done on the UI thread (e.g. to access PrefService).
Eric Seckler8652dcd52018-09-20 10:42:2889 base::PostDelayedTaskWithTraits(
90 FROM_HERE, {BrowserThread::UI},
Dominic Mazzonic8cece522019-04-16 21:30:3591 base::BindOnce(&BrowserAccessibilityStateImpl::UpdateHistogramsOnUIThread,
92 this),
sebmarchand41f774b2017-05-23 21:50:2193 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
[email protected]fa4f91682012-02-21 19:53:2694}
95
96BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
Doug Turneraff275f2017-08-15 22:40:3597 // Remove ourselves from the AXMode global observer list.
98 ui::AXPlatformNode::RemoveAXModeObserver(this);
[email protected]fa4f91682012-02-21 19:53:2699}
100
101void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:09102 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:24103 switches::kDisableRendererAccessibility)) {
104 return;
105 }
106 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:26107}
108
[email protected]df376972013-05-03 21:45:03109void BrowserAccessibilityStateImpl::EnableAccessibility() {
Doug Turner63f3c7b2017-07-29 05:10:01110 AddAccessibilityModeFlags(ui::kAXModeComplete);
[email protected]fa4f91682012-02-21 19:53:26111}
112
[email protected]df376972013-05-03 21:45:03113void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:52114 ResetAccessibilityMode();
115}
116
James Wallace-Leeeafc94cb92018-07-23 21:35:09117bool BrowserAccessibilityStateImpl::IsRendererAccessibilityEnabled() {
118 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
119 switches::kDisableRendererAccessibility);
120}
121
[email protected]1e558fa2014-02-12 23:28:52122void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
Doug Turner63f3c7b2017-07-29 05:10:01123 accessibility_mode_ = ui::AXMode();
[email protected]479278702014-08-11 20:32:09124 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52125 switches::kForceRendererAccessibility)) {
Doug Turner63f3c7b2017-07-29 05:10:01126 accessibility_mode_ = ui::kAXModeComplete;
[email protected]1e558fa2014-02-12 23:28:52127 }
128}
129
130void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
131 ResetAccessibilityModeValue();
132
[email protected]95640212014-07-26 18:14:30133 std::vector<WebContentsImpl*> web_contents_vector =
134 WebContentsImpl::GetAllWebContents();
135 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09136 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]df376972013-05-03 21:45:03137}
138
[email protected]fa4f91682012-02-21 19:53:26139bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
Doug Turner63f3c7b2017-07-29 05:10:01140 return accessibility_mode_ == ui::kAXModeComplete;
[email protected]fa4f91682012-02-21 19:53:26141}
142
Dominic Mazzonic8cece522019-04-16 21:30:35143void BrowserAccessibilityStateImpl::AddUIThreadHistogramCallback(
144 base::OnceClosure callback) {
145 ui_thread_histogram_callbacks_.push_back(std::move(callback));
146}
147
148void BrowserAccessibilityStateImpl::AddOtherThreadHistogramCallback(
149 base::OnceClosure callback) {
150 other_thread_histogram_callbacks_.push_back(std::move(callback));
[email protected]89430152012-12-03 19:18:56151}
152
[email protected]30fdb362013-01-09 02:33:27153void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
Dominic Mazzonic8cece522019-04-16 21:30:35154 UpdateHistogramsOnUIThread();
155 UpdateHistogramsOnOtherThread();
[email protected]30fdb362013-01-09 02:33:27156}
157
Dominic Mazzonic8cece522019-04-16 21:30:35158void BrowserAccessibilityStateImpl::UpdateHistogramsOnUIThread() {
159 UpdatePlatformSpecificHistogramsOnUIThread();
[email protected]18df7362012-10-24 01:29:40160
Dominic Mazzonic8cece522019-04-16 21:30:35161 for (auto& callback : ui_thread_histogram_callbacks_)
162 std::move(callback).Run();
163 ui_thread_histogram_callbacks_.clear();
[email protected]89430152012-12-03 19:18:56164
dmazzoni368ea132016-12-20 08:22:42165 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
166 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40167 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42168
[email protected]18df7362012-10-24 01:29:40169 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22170 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40171 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09172 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40173 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26174}
[email protected]e2fa1cca42012-08-22 14:07:27175
Dominic Mazzonic8cece522019-04-16 21:30:35176void BrowserAccessibilityStateImpl::UpdateHistogramsOnOtherThread() {
177 UpdatePlatformSpecificHistogramsOnOtherThread();
178
179 for (auto& callback : other_thread_histogram_callbacks_)
180 std::move(callback).Run();
181 other_thread_histogram_callbacks_.clear();
182}
183
Doug Turneraff275f2017-08-15 22:40:35184void BrowserAccessibilityStateImpl::OnAXModeAdded(ui::AXMode mode) {
185 AddAccessibilityModeFlags(mode);
186}
187
Lucas Furukawa Gadanid726e1e2019-05-08 16:20:03188ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() {
James Wallace-Leeeafc94cb92018-07-23 21:35:09189 return accessibility_mode_;
190}
191
Stephen McGruera73dfdb2018-11-14 18:19:47192#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_MACOSX)
Dominic Mazzoni190a6cd2018-09-26 11:24:08193void BrowserAccessibilityStateImpl::PlatformInitialize() {}
194
Dominic Mazzonic8cece522019-04-16 21:30:35195void BrowserAccessibilityStateImpl::
196 UpdatePlatformSpecificHistogramsOnUIThread() {}
197void BrowserAccessibilityStateImpl::
198 UpdatePlatformSpecificHistogramsOnOtherThread() {}
Aaron Leventhal30b2ceb2019-08-09 19:05:41199void BrowserAccessibilityStateImpl::UpdateUniqueUserHistograms() {}
[email protected]18df7362012-10-24 01:29:40200#endif
201
Doug Turner63f3c7b2017-07-29 05:10:01202void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09203 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52204 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03205 return;
[email protected]1e558fa2014-02-12 23:28:52206 }
[email protected]df376972013-05-03 21:45:03207
Doug Turner63f3c7b2017-07-29 05:10:01208 ui::AXMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01209 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42210 if (accessibility_mode_ == previous_mode)
211 return;
212
213 // Retrieve only newly added modes for the purposes of logging.
dougtcd3dad732017-03-14 03:26:23214 int new_mode_flags = mode.mode() & (~previous_mode.mode());
Doug Turner63f3c7b2017-07-29 05:10:01215 if (new_mode_flags & ui::AXMode::kNativeAPIs)
dougtcd3dad732017-03-14 03:26:23216 RecordNewAccessibilityModeFlags(UMA_AX_MODE_NATIVE_APIS);
Doug Turner63f3c7b2017-07-29 05:10:01217 if (new_mode_flags & ui::AXMode::kWebContents)
dougtcd3dad732017-03-14 03:26:23218 RecordNewAccessibilityModeFlags(UMA_AX_MODE_WEB_CONTENTS);
Doug Turner63f3c7b2017-07-29 05:10:01219 if (new_mode_flags & ui::AXMode::kInlineTextBoxes)
dougtcd3dad732017-03-14 03:26:23220 RecordNewAccessibilityModeFlags(UMA_AX_MODE_INLINE_TEXT_BOXES);
Doug Turner63f3c7b2017-07-29 05:10:01221 if (new_mode_flags & ui::AXMode::kScreenReader)
dougtcd3dad732017-03-14 03:26:23222 RecordNewAccessibilityModeFlags(UMA_AX_MODE_SCREEN_READER);
Doug Turner63f3c7b2017-07-29 05:10:01223 if (new_mode_flags & ui::AXMode::kHTML)
dougtcd3dad732017-03-14 03:26:23224 RecordNewAccessibilityModeFlags(UMA_AX_MODE_HTML);
dmazzoni368ea132016-12-20 08:22:42225
dmazzonidd3d51a72016-12-14 18:41:01226 std::vector<WebContentsImpl*> web_contents_vector =
227 WebContentsImpl::GetAllWebContents();
228 for (size_t i = 0; i < web_contents_vector.size(); ++i)
229 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52230}
231
dmazzonidd3d51a72016-12-14 18:41:01232void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
Doug Turner63f3c7b2017-07-29 05:10:01233 ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09234 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52235 switches::kForceRendererAccessibility) &&
Doug Turner63f3c7b2017-07-29 05:10:01236 mode == ui::kAXModeComplete) {
[email protected]1e558fa2014-02-12 23:28:52237 return;
238 }
239
dougtcd3dad732017-03-14 03:26:23240 int raw_flags =
241 accessibility_mode_.mode() ^ (mode.mode() & accessibility_mode_.mode());
242 accessibility_mode_ = raw_flags;
243
[email protected]95640212014-07-26 18:14:30244 std::vector<WebContentsImpl*> web_contents_vector =
245 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01246 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09247 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]e2fa1cca42012-08-22 14:07:27248}
[email protected]e6b34872012-10-24 20:51:32249
250} // namespace content