blob: f55c5b9e150e7b19c0583fe549c63bb100aa7a12 [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"
mlamouri20bb4c4a2015-07-08 14:30:2217#include "ui/gfx/color_utils.h"
[email protected]fa4f91682012-02-21 19:53:2618
[email protected]e6b34872012-10-24 20:51:3219namespace content {
20
dmazzoni368ea132016-12-20 08:22:4221// IMPORTANT!
22// These values are written to logs. Do not renumber or delete
23// existing items; add new entries to the end of the list.
24enum ModeFlagHistogramValue {
dougtcd3dad732017-03-14 03:26:2325 UMA_AX_MODE_NATIVE_APIS = 0,
26 UMA_AX_MODE_WEB_CONTENTS = 1,
27 UMA_AX_MODE_INLINE_TEXT_BOXES = 2,
28 UMA_AX_MODE_SCREEN_READER = 3,
29 UMA_AX_MODE_HTML = 4,
dmazzoni368ea132016-12-20 08:22:4230
31 // This must always be the last enum. It's okay for its value to
32 // increase, but none of the other enum values may change.
dougtcd3dad732017-03-14 03:26:2333 UMA_AX_MODE_MAX
dmazzoni368ea132016-12-20 08:22:4234};
35
36// Record a histograms for an accessibility mode when it's enabled.
37void RecordNewAccessibilityModeFlags(ModeFlagHistogramValue mode_flag) {
dougtcd3dad732017-03-14 03:26:2338 UMA_HISTOGRAM_ENUMERATION("Accessibility.ModeFlag", mode_flag,
39 UMA_AX_MODE_MAX);
dmazzoni368ea132016-12-20 08:22:4240}
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 disable_hot_tracking_(false) {
[email protected]1e558fa2014-02-12 23:28:5260 ResetAccessibilityModeValue();
[email protected]882db442012-12-04 16:37:5461
62 // We need to AddRef() the leaky singleton so that Bind doesn't
[email protected]3c17ae742012-10-24 17:37:2663 // delete it prematurely.
64 AddRef();
sebmarchand41f774b2017-05-23 21:50:2165
66#if defined(OS_WIN)
67 // The delay is necessary because assistive technology sometimes isn't
68 // detected until after the user interacts in some way, so a reasonable delay
69 // gives us better numbers.
70 base::PostDelayedTaskWithTraits(
71 FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
[email protected]30fdb362013-01-09 02:33:2772 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
dmazzoni368ea132016-12-20 08:22:4273 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
sebmarchand41f774b2017-05-23 21:50:2174#else
75 // On all other platforms, UpdateHistograms should be called on the UI
76 // thread because it needs to be able to access PrefService.
77 BrowserThread::PostDelayedTask(
78 BrowserThread::UI, FROM_HERE,
79 base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
80 base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
81#endif
[email protected]fa4f91682012-02-21 19:53:2682}
83
84BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
85}
86
87void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
[email protected]479278702014-08-11 20:32:0988 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bfa71242014-03-27 21:10:2489 switches::kDisableRendererAccessibility)) {
90 return;
91 }
92 EnableAccessibility();
[email protected]fa4f91682012-02-21 19:53:2693}
94
[email protected]df376972013-05-03 21:45:0395void BrowserAccessibilityStateImpl::EnableAccessibility() {
dougtcd3dad732017-03-14 03:26:2396 AddAccessibilityModeFlags(kAccessibilityModeComplete);
[email protected]fa4f91682012-02-21 19:53:2697}
98
[email protected]df376972013-05-03 21:45:0399void BrowserAccessibilityStateImpl::DisableAccessibility() {
[email protected]1e558fa2014-02-12 23:28:52100 ResetAccessibilityMode();
101}
102
103void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
dougtcd3dad732017-03-14 03:26:23104 accessibility_mode_ = AccessibilityMode();
[email protected]479278702014-08-11 20:32:09105 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52106 switches::kForceRendererAccessibility)) {
dougtcd3dad732017-03-14 03:26:23107 accessibility_mode_ = kAccessibilityModeComplete;
[email protected]1e558fa2014-02-12 23:28:52108 }
109}
110
111void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
112 ResetAccessibilityModeValue();
113
[email protected]95640212014-07-26 18:14:30114 std::vector<WebContentsImpl*> web_contents_vector =
115 WebContentsImpl::GetAllWebContents();
116 for (size_t i = 0; i < web_contents_vector.size(); ++i)
117 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode());
[email protected]df376972013-05-03 21:45:03118}
119
[email protected]fa4f91682012-02-21 19:53:26120bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
dougtcd3dad732017-03-14 03:26:23121 return accessibility_mode_ == kAccessibilityModeComplete;
[email protected]fa4f91682012-02-21 19:53:26122}
123
[email protected]89430152012-12-03 19:18:56124void BrowserAccessibilityStateImpl::AddHistogramCallback(
125 base::Closure callback) {
126 histogram_callbacks_.push_back(callback);
127}
128
[email protected]30fdb362013-01-09 02:33:27129void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
130 UpdateHistograms();
131}
132
133void BrowserAccessibilityStateImpl::UpdateHistograms() {
[email protected]18df7362012-10-24 01:29:40134 UpdatePlatformSpecificHistograms();
135
[email protected]89430152012-12-03 19:18:56136 for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
137 histogram_callbacks_[i].Run();
138
dmazzoni368ea132016-12-20 08:22:42139 // TODO(dmazzoni): remove this in M59 since Accessibility.ModeFlag
140 // supercedes it. http://crbug.com/672205
[email protected]18df7362012-10-24 01:29:40141 UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
dmazzoni368ea132016-12-20 08:22:42142
[email protected]18df7362012-10-24 01:29:40143 UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
mlamouri20bb4c4a2015-07-08 14:30:22144 color_utils::IsInvertedColorScheme());
[email protected]18df7362012-10-24 01:29:40145 UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
[email protected]479278702014-08-11 20:32:09146 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]18df7362012-10-24 01:29:40147 switches::kForceRendererAccessibility));
[email protected]fa4f91682012-02-21 19:53:26148}
[email protected]e2fa1cca42012-08-22 14:07:27149
ellyjonesa577c6cb2016-04-01 22:31:03150#if !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]18df7362012-10-24 01:29:40151void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
152}
153#endif
154
dmazzonidd3d51a72016-12-14 18:41:01155void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(
[email protected]e2fa1cca42012-08-22 14:07:27156 AccessibilityMode mode) {
[email protected]479278702014-08-11 20:32:09157 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52158 switches::kDisableRendererAccessibility)) {
[email protected]df376972013-05-03 21:45:03159 return;
[email protected]1e558fa2014-02-12 23:28:52160 }
[email protected]df376972013-05-03 21:45:03161
dmazzoni368ea132016-12-20 08:22:42162 AccessibilityMode previous_mode = accessibility_mode_;
dmazzonidd3d51a72016-12-14 18:41:01163 accessibility_mode_ |= mode;
dmazzoni368ea132016-12-20 08:22:42164 if (accessibility_mode_ == previous_mode)
165 return;
166
167 // Retrieve only newly added modes for the purposes of logging.
dougtcd3dad732017-03-14 03:26:23168 int new_mode_flags = mode.mode() & (~previous_mode.mode());
169 if (new_mode_flags & AccessibilityMode::kNativeAPIs)
170 RecordNewAccessibilityModeFlags(UMA_AX_MODE_NATIVE_APIS);
171 if (new_mode_flags & AccessibilityMode::kWebContents)
172 RecordNewAccessibilityModeFlags(UMA_AX_MODE_WEB_CONTENTS);
173 if (new_mode_flags & AccessibilityMode::kInlineTextBoxes)
174 RecordNewAccessibilityModeFlags(UMA_AX_MODE_INLINE_TEXT_BOXES);
175 if (new_mode_flags & AccessibilityMode::kScreenReader)
176 RecordNewAccessibilityModeFlags(UMA_AX_MODE_SCREEN_READER);
177 if (new_mode_flags & AccessibilityMode::kHTML)
178 RecordNewAccessibilityModeFlags(UMA_AX_MODE_HTML);
dmazzoni368ea132016-12-20 08:22:42179
dmazzonidd3d51a72016-12-14 18:41:01180 std::vector<WebContentsImpl*> web_contents_vector =
181 WebContentsImpl::GetAllWebContents();
182 for (size_t i = 0; i < web_contents_vector.size(); ++i)
183 web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_);
[email protected]1e558fa2014-02-12 23:28:52184}
185
dmazzonidd3d51a72016-12-14 18:41:01186void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
[email protected]1e558fa2014-02-12 23:28:52187 AccessibilityMode mode) {
[email protected]479278702014-08-11 20:32:09188 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]1e558fa2014-02-12 23:28:52189 switches::kForceRendererAccessibility) &&
dougtcd3dad732017-03-14 03:26:23190 mode == kAccessibilityModeComplete) {
[email protected]1e558fa2014-02-12 23:28:52191 return;
192 }
193
dougtcd3dad732017-03-14 03:26:23194 int raw_flags =
195 accessibility_mode_.mode() ^ (mode.mode() & accessibility_mode_.mode());
196 accessibility_mode_ = raw_flags;
197
[email protected]95640212014-07-26 18:14:30198 std::vector<WebContentsImpl*> web_contents_vector =
199 WebContentsImpl::GetAllWebContents();
dmazzonidd3d51a72016-12-14 18:41:01200 for (size_t i = 0; i < web_contents_vector.size(); ++i)
201 web_contents_vector[i]->SetAccessibilityMode(accessibility_mode());
[email protected]e2fa1cca42012-08-22 14:07:27202}
[email protected]e6b34872012-10-24 20:51:32203
204} // namespace content