• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/timer/timer.h"
10 #include "content/browser/accessibility/accessibility_mode_helper.h"
11 #include "content/browser/renderer_host/render_widget_host_impl.h"
12 #include "content/browser/web_contents/web_contents_impl.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/content_switches.h"
15 #include "ui/gfx/sys_color_change_listener.h"
16 
17 namespace content {
18 
19 // Update the accessibility histogram 45 seconds after initialization.
20 static const int kAccessibilityHistogramDelaySecs = 45;
21 
22 // static
GetInstance()23 BrowserAccessibilityState* BrowserAccessibilityState::GetInstance() {
24   return BrowserAccessibilityStateImpl::GetInstance();
25 }
26 
27 // static
GetInstance()28 BrowserAccessibilityStateImpl* BrowserAccessibilityStateImpl::GetInstance() {
29   return Singleton<BrowserAccessibilityStateImpl,
30                    LeakySingletonTraits<BrowserAccessibilityStateImpl> >::get();
31 }
32 
BrowserAccessibilityStateImpl()33 BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
34     : BrowserAccessibilityState(),
35       accessibility_mode_(AccessibilityModeOff) {
36   ResetAccessibilityModeValue();
37 #if defined(OS_WIN)
38   // On Windows, UpdateHistograms calls some system functions with unknown
39   // runtime, so call it on the file thread to ensure there's no jank.
40   // Everything in that method must be safe to call on another thread.
41   BrowserThread::ID update_histogram_thread = BrowserThread::FILE;
42 #else
43   // On all other platforms, UpdateHistograms should be called on the main
44   // thread.
45   BrowserThread::ID update_histogram_thread = BrowserThread::UI;
46 #endif
47 
48   // We need to AddRef() the leaky singleton so that Bind doesn't
49   // delete it prematurely.
50   AddRef();
51   BrowserThread::PostDelayedTask(
52       update_histogram_thread, FROM_HERE,
53       base::Bind(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
54       base::TimeDelta::FromSeconds(kAccessibilityHistogramDelaySecs));
55 }
56 
~BrowserAccessibilityStateImpl()57 BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
58 }
59 
OnScreenReaderDetected()60 void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
61   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
62           switches::kDisableRendererAccessibility)) {
63     return;
64   }
65   EnableAccessibility();
66 }
67 
EnableAccessibility()68 void BrowserAccessibilityStateImpl::EnableAccessibility() {
69   AddAccessibilityMode(AccessibilityModeComplete);
70 }
71 
DisableAccessibility()72 void BrowserAccessibilityStateImpl::DisableAccessibility() {
73   ResetAccessibilityMode();
74 }
75 
ResetAccessibilityModeValue()76 void BrowserAccessibilityStateImpl::ResetAccessibilityModeValue() {
77   accessibility_mode_ = AccessibilityModeOff;
78   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
79           switches::kForceRendererAccessibility)) {
80     accessibility_mode_ = AccessibilityModeComplete;
81   }
82 }
83 
ResetAccessibilityMode()84 void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
85   ResetAccessibilityModeValue();
86 
87   std::vector<WebContentsImpl*> web_contents_vector =
88       WebContentsImpl::GetAllWebContents();
89   for (size_t i = 0; i < web_contents_vector.size(); ++i)
90     web_contents_vector[i]->SetAccessibilityMode(accessibility_mode());
91 }
92 
IsAccessibleBrowser()93 bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
94   return ((accessibility_mode_ & AccessibilityModeComplete) ==
95           AccessibilityModeComplete);
96 }
97 
AddHistogramCallback(base::Closure callback)98 void BrowserAccessibilityStateImpl::AddHistogramCallback(
99     base::Closure callback) {
100   histogram_callbacks_.push_back(callback);
101 }
102 
UpdateHistogramsForTesting()103 void BrowserAccessibilityStateImpl::UpdateHistogramsForTesting() {
104   UpdateHistograms();
105 }
106 
UpdateHistograms()107 void BrowserAccessibilityStateImpl::UpdateHistograms() {
108   UpdatePlatformSpecificHistograms();
109 
110   for (size_t i = 0; i < histogram_callbacks_.size(); ++i)
111     histogram_callbacks_[i].Run();
112 
113   UMA_HISTOGRAM_BOOLEAN("Accessibility.State", IsAccessibleBrowser());
114   UMA_HISTOGRAM_BOOLEAN("Accessibility.InvertedColors",
115                         gfx::IsInvertedColorScheme());
116   UMA_HISTOGRAM_BOOLEAN("Accessibility.ManuallyEnabled",
117                         base::CommandLine::ForCurrentProcess()->HasSwitch(
118                             switches::kForceRendererAccessibility));
119 }
120 
121 #if !defined(OS_WIN)
UpdatePlatformSpecificHistograms()122 void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
123 }
124 #endif
125 
AddAccessibilityMode(AccessibilityMode mode)126 void BrowserAccessibilityStateImpl::AddAccessibilityMode(
127     AccessibilityMode mode) {
128   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
129           switches::kDisableRendererAccessibility)) {
130     return;
131   }
132 
133   accessibility_mode_ =
134       content::AddAccessibilityModeTo(accessibility_mode_, mode);
135 
136   AddOrRemoveFromAllWebContents(mode, true);
137 }
138 
RemoveAccessibilityMode(AccessibilityMode mode)139 void BrowserAccessibilityStateImpl::RemoveAccessibilityMode(
140     AccessibilityMode mode) {
141   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
142           switches::kForceRendererAccessibility) &&
143       mode == AccessibilityModeComplete) {
144     return;
145   }
146 
147   accessibility_mode_ =
148       content::RemoveAccessibilityModeFrom(accessibility_mode_, mode);
149 
150   AddOrRemoveFromAllWebContents(mode, false);
151 }
152 
AddOrRemoveFromAllWebContents(AccessibilityMode mode,bool add)153 void BrowserAccessibilityStateImpl::AddOrRemoveFromAllWebContents(
154     AccessibilityMode mode,
155     bool add) {
156   std::vector<WebContentsImpl*> web_contents_vector =
157       WebContentsImpl::GetAllWebContents();
158   for (size_t i = 0; i < web_contents_vector.size(); ++i) {
159     if (add)
160       web_contents_vector[i]->AddAccessibilityMode(mode);
161     else
162       web_contents_vector[i]->RemoveAccessibilityMode(mode);
163   }
164 }
165 
166 }  // namespace content
167