diff options
-rw-r--r-- | chrome/browser/accessibility/browser_accessibility_state.cc | 21 | ||||
-rw-r--r-- | chrome/browser/accessibility/browser_accessibility_state.h | 46 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.cc | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.h | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_win.cc | 25 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame_win.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame_win.h | 1 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 1 | ||||
-rw-r--r-- | views/widget/widget_win.h | 2 |
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. |