summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/accessibility/browser_accessibility_state.cc21
-rw-r--r--chrome/browser/accessibility/browser_accessibility_state.h46
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc8
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h4
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc25
-rw-r--r--chrome/browser/views/frame/browser_frame_win.cc6
-rw-r--r--chrome/browser/views/frame/browser_frame_win.h1
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/renderer/render_view.cc1
-rw-r--r--views/widget/widget_win.h2
10 files changed, 104 insertions, 12 deletions
diff --git a/chrome/browser/accessibility/browser_accessibility_state.cc b/chrome/browser/accessibility/browser_accessibility_state.cc
new file mode 100644
index 0000000..4896f91
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_state.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/accessibility/browser_accessibility_state.h"
+#include "chrome/browser/profile.h"
+
+BrowserAccessibilityState::BrowserAccessibilityState()
+ : screen_reader_active_(false) {
+}
+
+BrowserAccessibilityState::~BrowserAccessibilityState() {
+}
+
+void BrowserAccessibilityState::OnScreenReaderDetected() {
+ screen_reader_active_ = true;
+}
+
+bool BrowserAccessibilityState::IsAccessibleBrowser() {
+ return screen_reader_active_;
+}
diff --git a/chrome/browser/accessibility/browser_accessibility_state.h b/chrome/browser/accessibility/browser_accessibility_state.h
new file mode 100644
index 0000000..efcd2dd
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_state.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_STATE_H_
+#define CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_STATE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/singleton.h"
+
+// The BrowserAccessibilityState class is used to determine if Chrome should be
+// customized for users with assistive technology, such as screen readers. We
+// modify the behavior of certain user interfaces to provide a better experience
+// for screen reader users. The way we detect a screen reader program is
+// different for each platform.
+//
+// Screen Reader Detection
+// (1) On windows many screen reader detection mechinisms will give false
+// positives like relying on the SPI_GETSCREENREADER system parameter. In Chrome
+// we attempt to dynamically detect a MSAA client screen reader by calling
+// NotifiyWinEvent in WidgetWin with a custom ID and wait to see if the ID
+// is requested by a subsequent call to WM_GETOBJECT.
+// (2) On mac we detect if VoiceOver is running. This is stored in a preference
+// file for Universal Access with the key "voiceOverOnOffKey".
+class BrowserAccessibilityState {
+ public:
+ ~BrowserAccessibilityState();
+
+ // Called when screen reader client is detected.
+ void OnScreenReaderDetected();
+
+ // Returns true if the Chrome browser should be customized for accessibility.
+ bool IsAccessibleBrowser();
+
+ private:
+ BrowserAccessibilityState();
+ friend struct DefaultSingletonTraits<BrowserAccessibilityState>;
+
+ // Set to true when a screen reader client is detected.
+ bool screen_reader_active_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityState);
+};
+
+#endif // CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_STATE_H_
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 027528e0..f2120cf 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/histogram.h"
#include "base/message_loop.h"
+#include "chrome/browser/accessibility/browser_accessibility_state.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/renderer_host/backing_store.h"
#include "chrome/browser/renderer_host/backing_store_manager.h"
@@ -64,15 +65,13 @@ static const int kHungRendererDelayMs = 20000;
// in trailing scrolls after the user ends their input.
static const int kMaxTimeBetweenWheelMessagesMs = 250;
-// static
-bool RenderWidgetHost::renderer_accessible_ = false;
-
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHost
RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process,
int routing_id)
: renderer_initialized_(false),
+ renderer_accessible_(false),
view_(NULL),
process_(process),
painting_observer_(NULL),
@@ -102,7 +101,8 @@ RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process,
process_->WidgetRestored();
if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceRendererAccessibility)) {
+ switches::kForceRendererAccessibility) ||
+ Singleton<BrowserAccessibilityState>()->IsAccessibleBrowser()) {
EnableRendererAccessibility();
}
}
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index 91215d6..b8acd4e 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -146,7 +146,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
RenderProcessHost* process() const { return process_; }
int routing_id() const { return routing_id_; }
- static bool renderer_accessible() { return renderer_accessible_; }
+ bool renderer_accessible() { return renderer_accessible_; }
// Set the PaintObserver on this object. Takes ownership.
void set_paint_observer(PaintObserver* paint_observer) {
@@ -556,7 +556,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// True if renderer accessibility is enabled. This should only be set when a
// screenreader is detected as it can potentially slow down Chrome.
- static bool renderer_accessible_;
+ bool renderer_accessible_;
// The View associated with the RenderViewHost. The lifetime of this object
// is associated with the lifetime of the Render process. If the Renderer
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index 1444ab5..3c82568 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -16,6 +16,7 @@
#include "base/win_util.h"
#include "chrome/browser/accessibility/browser_accessibility.h"
#include "chrome/browser/accessibility/browser_accessibility_manager.h"
+#include "chrome/browser/accessibility/browser_accessibility_state.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_trial.h"
#include "chrome/browser/chrome_thread.h"
@@ -66,6 +67,10 @@ const int kTooltipMaxWidthPixels = 300;
// Maximum number of characters we allow in a tooltip.
const int kMaxTooltipLength = 1024;
+// A custom MSAA object id used to determine if a screen reader is actively
+// listening for MSAA events.
+const int kIdCustom = 1;
+
const wchar_t* kRenderWidgetHostViewKey = L"__RENDER_WIDGET_HOST_VIEW__";
// A callback function for EnumThreadWindows to enumerate and dismiss
@@ -1541,14 +1546,27 @@ void RenderWidgetHostViewWin::AccessibilityDoDefaultAction(int acc_obj_id) {
LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam,
LPARAM lparam, BOOL& handled) {
+ if (kIdCustom == lparam) {
+ // An MSAA client requestes our custom id. Assume that we have detected an
+ // active windows screen reader.
+ Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected();
+ render_widget_host_->EnableRendererAccessibility();
+
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
if (lparam != OBJID_CLIENT) {
handled = false;
return static_cast<LRESULT>(0L);
}
- if (!browser_accessibility_manager_.get()) {
- render_widget_host_->EnableRendererAccessibility();
+ if (!render_widget_host_->renderer_accessible()) {
+ // Attempt to detect screen readers by sending an event with our custom id.
+ NotifyWinEvent(EVENT_SYSTEM_ALERT, m_hWnd, kIdCustom, CHILDID_SELF);
+ }
+ if (!browser_accessibility_manager_.get()) {
// Return busy document tree while renderer accessibility tree loads.
webkit_glue::WebAccessibility loading_tree;
loading_tree.role = WebAccessibility::ROLE_DOCUMENT;
@@ -1559,9 +1577,8 @@ LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam,
ScopedComPtr<IAccessible> root(
browser_accessibility_manager_->GetRootAccessible());
- if (root.get()) {
+ if (root.get())
return LresultFromObject(IID_IAccessible, wparam, root.Detach());
- }
handled = false;
return static_cast<LRESULT>(0L);
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc
index 5aad9a5..bd5ddca 100644
--- a/chrome/browser/views/frame/browser_frame_win.cc
+++ b/chrome/browser/views/frame/browser_frame_win.cc
@@ -11,6 +11,7 @@
#include "app/win_util.h"
#include "base/win_util.h"
+#include "chrome/browser/accessibility/browser_accessibility_state.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/themes/browser_theme_provider.h"
@@ -243,6 +244,11 @@ ThemeProvider* BrowserFrameWin::GetDefaultThemeProvider() const {
return profile_->GetThemeProvider();
}
+void BrowserFrameWin::OnScreenReaderDetected() {
+ Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected();
+ WindowWin::OnScreenReaderDetected();
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame, views::CustomFrameWindow overrides:
diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h
index fdc5d62..1dbc4dd 100644
--- a/chrome/browser/views/frame/browser_frame_win.h
+++ b/chrome/browser/views/frame/browser_frame_win.h
@@ -66,6 +66,7 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
virtual void OnWindowPosChanged(WINDOWPOS* window_pos);
virtual ThemeProvider* GetThemeProvider() const;
virtual ThemeProvider* GetDefaultThemeProvider() const;
+ virtual void OnScreenReaderDetected();
// Overridden from views::Window:
virtual int GetShowState() const;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index da8472e..88ce45e 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -61,6 +61,8 @@
# mocks.
'browser/accessibility/browser_accessibility.cc',
'browser/accessibility/browser_accessibility.h',
+ 'browser/accessibility/browser_accessibility_state.cc',
+ 'browser/accessibility/browser_accessibility_state.h',
'browser/accessibility/browser_accessibility_manager.cc',
'browser/accessibility/browser_accessibility_manager.h',
'browser/accessibility/browser_accessibility_manager_win.cc',
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 3f881a7..ab4336a 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1473,7 +1473,6 @@ void RenderView::UpdateURL(WebFrame* frame) {
// Check if the navigation was within the same page, in which case we don't
// want to clear the accessibility cache.
if (accessibility_.get() && !navigation_state->was_within_same_page()) {
- accessibility_->clear();
accessibility_.reset();
pending_accessibility_notifications_.clear();
}
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 65047f1..029f34e 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -439,7 +439,7 @@ class WidgetWin : public gfx::WindowImpl,
void LayoutRootView();
// Called when a MSAA screen reader cleint is detected.
- void OnScreenReaderDetected();
+ virtual void OnScreenReaderDetected();
// Returns whether capture should be released on mouse release. The default
// is true.