blob: a496fc4ffcbb3c5126938fe5fbcc5a24b4e9aae2 [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"
sebmarchand41f774b2017-05-23 21:50:2111#include "base/task_scheduler/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"
[email protected]18df7362012-10-24 01:29:4015#include "content/public/browser/browser_thread.h"
[email protected]3e3c4522012-04-13 21:16:2916#include "content/public/common/content_switches.h"
Doug Turneraff275f2017-08-15 22:40:3517#include "ui/accessibility/platform/ax_platform_node.h"
mlamouri20bb4c4a2015-07-08 14:30:2218#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2619
[email protected]e6b34872012-10-24 20:51:3220namespace content {
21
dmazzoni368ea132016-12-20 08:22:4222// IMPORTANT!
23// These values are written to logs. Do not renumber or delete
24// existing items; add new entries to the end of the list.
25enum ModeFlagHistogramValue {
dougtcd3dad732017-03-14 03:26:2326 UMA_AX_MODE_NATIVE_APIS = 0,
27 UMA_AX_MODE_WEB_CONTENTS = 1,
28 UMA_AX_MODE_INLINE_TEXT_BOXES = 2,
29 UMA_AX_MODE_SCREEN_READER = 3,
30 UMA_AX_MODE_HTML = 4,
dmazzoni368ea132016-12-20 08:22:4231
32 // This must always be the last enum. It's okay for its value to
33 // increase, but none of the other enum values may change.
dougtcd3dad732017-03-14 03:26:2334 UMA_AX_MODE_MAX
dmazzoni368ea132016-12-20 08:22:4235};
36
37// Record a histograms for an accessibility mode when it's enabled.
38void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
dougtcd3dad732017-03-14 03:26:2339 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag", mode_flag,
40 UMA_AX_MODE_MAX);
dmazzoni368ea132016-12-20 08:22:4241}
42
[email protected]fa4f91682012-02-21 19:53:2643// Update the accessibility histogram 45 seconds after initialization.
dmazzoni368ea132016-12-20 08:22:4244static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;
[email protected]fa4f91682012-02-21 19:53:2645
46// static
47BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
48 return BrowserAccessibilityStateImpl::GetInstance();
49}
50
51// static
52BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2253 return base::Singleton<
54 BrowserAccessibilityStateImpl,
55 base::LeakySingletonTraits<BrowserAccessibilityStateImpl>>::get();
[email protected]fa4f91682012-02-21 19:53:2656}
57
58BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
59 : BrowserAccessibilityState(),
dmazzonidea5ba62015-02-03 19:27:2460 disable_hot_tracking_(false) {
[email protected]1e558fa2014-02-12 23:28:5261 ResetAccessibilityModeValue();
[email protected]882db442012-12-04 16:37:5462
63 // We need to AddRef() the leaky singleton so that Bind doesn't
[email protected]3c17ae742012-10-24 17:37:2664 // delete it prematurely.
65 AddRef();
sebmarchand41f774b2017-05-23 21:50:2166
Doug Turneraff275f2017-08-15 22:40:3567 // Hook ourselves up to observe ax mode changes.
68 ui::AXPlatformNode::AddAXModeObserver(this);
69
sebmarchand41f774b2017-05-23 21:50:2170#if defined(OS_WIN)
71 // The delay is necessary because assistive technology sometimes isn't
72 // detected until after the user interacts in some way, so a reasonable delay
73 // gives us better numbers.
74 base::PostDelayedTaskWithTraits(
75 FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
[email protected]30fdb362013-01-09 02:33:2776 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
dmazzoni368ea132016-12-20 08:22:4277 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
sebmarchand41f774b2017-05-23 21:50:2178#else
79 // On all other platforms, UpdateHistograms should be called on the UI
80 // thread because it needs to be able to access PrefService.
81 BrowserThread::PostDelayedTask(
82 BrowserThread::UI, FROM_HERE,
tzik4fea24af2017-08-23 11:41:4783 base::BindOnce(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
sebmarchand41f774b2017-05-23 21:50:2184 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
85#endif
[email protected]fa4f91682012-02-21 19:53:2686}
87
88BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
Doug Turneraff275f2017-08-15 22:40:3589 // Remove ourselves from the AXMode global observer list.
90 ui::AXPlatformNode::RemoveAXModeObserver(this);
[email protected]fa4f91682012-02-21 19:53:2691}
92
93void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:0994 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:2495 switches::kDisableRendererAccessibility)) {
96 return;
97 }
98 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:2699}
100
[email protected]df376972013-05-03 21:45:03101void BrowserAccessibilityStateImpl::EnableAccessibility() {
Doug Turner63f3c7b2017-07-29 05:10:01102 AddAccessibilityModeFlags(ui::kAXModeComplete);
[email protected]fa4f91682012-02-21 19:53:26103}
104
[email protected]df376972013-05-03 21:45:03105void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:52106 ResetAccessibilityMode();
107}
108
James Wallace-Leeeafc94cb92018-07-23 21:35:09109bool BrowserAccessibilityStateImpl::IsRendererAccessibilityEnabled() {
110 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
111 switches::kDisableRendererAccessibility);
112}
113
[email protected]1e558fa2014-02-12 23:28:52114void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
Doug Turner63f3c7b2017-07-29 05:10:01115 accessibility_mode_ = ui::AXMode();
[email protected]479278702014-08-11 20:32:09116 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52117 switches::kForceRendererAccessibility)) {
Doug Turner63f3c7b2017-07-29 05:10:01118 accessibility_mode_ = ui::kAXModeComplete;
[email protected]1e558fa2014-02-12 23:28:52119 }
120}
121
122void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
123 ResetAccessibilityModeValue();
124
[email protected]95640212014-07-26 18:14:30125 std::vector<WebContentsImpl*> web_contents_vector =
126 WebContentsImpl::GetAllWebContents();
127 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09128 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]df376972013-05-03 21:45:03129}
130
[email protected]fa4f91682012-02-21 19:53:26131bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
Doug Turner63f3c7b2017-07-29 05:10:01132 return accessibility_mode_ == ui::kAXModeComplete;
[email protected]fa4f91682012-02-21 19:53:26133}
134
[email protected]89430152012-12-03 19:18:56135void BrowserAccessibilityStateImpl::AddHistogramCallback(
136 base::Closure callback) {
Tommy Nyquist4b749d02018-03-20 21:46:29137 histogram_callbacks_.push_back(std::move(callback));
[email protected]89430152012-12-03 19:18:56138}
139
[email protected]30fdb362013-01-09 02:33:27140void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
141 UpdateHistograms();
142}
143
144void BrowserAccessibilityStateImpl::UpdateHistograms() {
[email protected]18df7362012-10-24 01:29:40145 UpdatePlatformSpecificHistograms();
146
[email protected]89430152012-12-03 19:18:56147 for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
148 histogram_callbacks_[i].Run();
149
dmazzoni368ea132016-12-20 08:22:42150 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
151 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40152 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42153
[email protected]18df7362012-10-24 01:29:40154 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22155 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40156 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09157 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40158 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26159}
[email protected]e2fa1cca42012-08-22 14:07:27160
Doug Turneraff275f2017-08-15 22:40:35161void BrowserAccessibilityStateImpl::OnAXModeAdded(ui::AXMode mode) {
162 AddAccessibilityModeFlags(mode);
163}
164
James Wallace-Leeeafc94cb92018-07-23 21:35:09165ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const {
166 return accessibility_mode_;
167}
168
ellyjonesa577c6cb2016-04-01 22:31:03169#if !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]18df7362012-10-24 01:29:40170void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
171}
172#endif
173
Doug Turner63f3c7b2017-07-29 05:10:01174void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09175 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52176 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03177 return;
[email protected]1e558fa2014-02-12 23:28:52178 }
[email protected]df376972013-05-03 21:45:03179
Doug Turner63f3c7b2017-07-29 05:10:01180 ui::AXMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01181 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42182 if (accessibility_mode_ == previous_mode)
183 return;
184
185 // Retrieve only newly added modes for the purposes of logging.
dougtcd3dad732017-03-14 03:26:23186 int new_mode_flags = mode.mode() & (~previous_mode.mode());
Doug Turner63f3c7b2017-07-29 05:10:01187 if (new_mode_flags & ui::AXMode::kNativeAPIs)
dougtcd3dad732017-03-14 03:26:23188 RecordNewAccessibilityModeFlags(UMA_AX_MODE_NATIVE_APIS);
Doug Turner63f3c7b2017-07-29 05:10:01189 if (new_mode_flags & ui::AXMode::kWebContents)
dougtcd3dad732017-03-14 03:26:23190 RecordNewAccessibilityModeFlags(UMA_AX_MODE_WEB_CONTENTS);
Doug Turner63f3c7b2017-07-29 05:10:01191 if (new_mode_flags & ui::AXMode::kInlineTextBoxes)
dougtcd3dad732017-03-14 03:26:23192 RecordNewAccessibilityModeFlags(UMA_AX_MODE_INLINE_TEXT_BOXES);
Doug Turner63f3c7b2017-07-29 05:10:01193 if (new_mode_flags & ui::AXMode::kScreenReader)
dougtcd3dad732017-03-14 03:26:23194 RecordNewAccessibilityModeFlags(UMA_AX_MODE_SCREEN_READER);
Doug Turner63f3c7b2017-07-29 05:10:01195 if (new_mode_flags & ui::AXMode::kHTML)
dougtcd3dad732017-03-14 03:26:23196 RecordNewAccessibilityModeFlags(UMA_AX_MODE_HTML);
dmazzoni368ea132016-12-20 08:22:42197
dmazzonidd3d51a72016-12-14 18:41:01198 std::vector<WebContentsImpl*> web_contents_vector =
199 WebContentsImpl::GetAllWebContents();
200 for (size_t i = 0; i < web_contents_vector.size(); ++i)
201 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52202}
203
dmazzonidd3d51a72016-12-14 18:41:01204void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
Doug Turner63f3c7b2017-07-29 05:10:01205 ui::AXMode mode) {
[email protected]479278702014-08-11 20:32:09206 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52207 switches::kForceRendererAccessibility) &&
Doug Turner63f3c7b2017-07-29 05:10:01208 mode == ui::kAXModeComplete) {
[email protected]1e558fa2014-02-12 23:28:52209 return;
210 }
211
dougtcd3dad732017-03-14 03:26:23212 int raw_flags =
213 accessibility_mode_.mode() ^ (mode.mode() & accessibility_mode_.mode());
214 accessibility_mode_ = raw_flags;
215
[email protected]95640212014-07-26 18:14:30216 std::vector<WebContentsImpl*> web_contents_vector =
217 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01218 for (size_t i = 0; i < web_contents_vector.size(); ++i)
James Wallace-Leeeafc94cb92018-07-23 21:35:09219 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode_);
[email protected]e2fa1cca42012-08-22 14:07:27220}
[email protected]e6b34872012-10-24 20:51:32221
222} // namespace content