Commit 33d3164a authored by Dominic Mazzoni's avatar Dominic Mazzoni Committed by Commit Bot

Ensure Windows accessibility is enabled properly.

http://crrev.com/c/1192062 made it so that we don't enable accessibility
as often. The idea was to only enable accessibility if we get a call to
IAccessible2, or to both get_accName and a response to our alert message
on a honeypot window.

However, this only worked if we constructed at least one
BrowserAccessibilityManager. In cases where the external client
never explored and discovered a BrowserAccessibilityManager, the
IAccessible2UsageObserver wasn't registered yet.

As a fix, move the IAccessible2UsageObserver code to part of
BrowserAccessibilityStateImpl.

Bug: 878072
Change-Id: Iadcbd032fa1d6f635bbb99c1e130d384efe0d9b1
Reviewed-on: https://chromium-review.googlesource.com/1234267Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593233}
parent 51c7ec50
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
namespace content { namespace content {
// See OnScreenReaderHoneyPotQueried, below.
bool g_screen_reader_honeypot_queried = false;
bool g_acc_name_called = false;
// static // static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create( BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate& initial_tree, const ui::AXTreeUpdate& initial_tree,
...@@ -44,7 +40,6 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( ...@@ -44,7 +40,6 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
load_complete_pending_(false) { load_complete_pending_(false) {
ui::win::CreateATLModuleIfNeeded(); ui::win::CreateATLModuleIfNeeded();
Initialize(initial_tree); Initialize(initial_tree);
ui::GetIAccessible2UsageObserverList().AddObserver(this);
} }
BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
...@@ -52,7 +47,6 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { ...@@ -52,7 +47,6 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
// destructor, otherwise our overrides of functions like // destructor, otherwise our overrides of functions like
// OnNodeWillBeDeleted won't be called. // OnNodeWillBeDeleted won't be called.
tree_.reset(NULL); tree_.reset(NULL);
ui::GetIAccessible2UsageObserverList().RemoveObserver(this);
} }
// static // static
...@@ -76,38 +70,6 @@ HWND BrowserAccessibilityManagerWin::GetParentHWND() { ...@@ -76,38 +70,6 @@ HWND BrowserAccessibilityManagerWin::GetParentHWND() {
return delegate->AccessibilityGetAcceleratedWidget(); return delegate->AccessibilityGetAcceleratedWidget();
} }
void BrowserAccessibilityManagerWin::OnIAccessible2Used() {
// When IAccessible2 APIs have been used elsewhere in the codebase,
// enable basic web accessibility support. (Full screen reader support is
// detected later when specific more advanced APIs are accessed.)
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
void BrowserAccessibilityManagerWin::OnScreenReaderHoneyPotQueried() {
// We used to trust this as a signal that a screen reader is running,
// but it's been abused. Now only enable accessibility if we also
// detect a call to get_accName.
if (g_screen_reader_honeypot_queried)
return;
g_screen_reader_honeypot_queried = true;
if (g_acc_name_called) {
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
}
void BrowserAccessibilityManagerWin::OnAccNameCalled() {
// See OnScreenReaderHoneyPotQueried, above.
if (g_acc_name_called)
return;
g_acc_name_called = true;
if (g_screen_reader_honeypot_queried) {
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
}
void BrowserAccessibilityManagerWin::UserIsReloading() { void BrowserAccessibilityManagerWin::UserIsReloading() {
if (GetRoot()) if (GetRoot())
FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot()); FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
......
...@@ -18,8 +18,7 @@ class BrowserAccessibilityWin; ...@@ -18,8 +18,7 @@ class BrowserAccessibilityWin;
// Manages a tree of BrowserAccessibilityWin objects. // Manages a tree of BrowserAccessibilityWin objects.
class CONTENT_EXPORT BrowserAccessibilityManagerWin class CONTENT_EXPORT BrowserAccessibilityManagerWin
: public BrowserAccessibilityManager, : public BrowserAccessibilityManager {
public ui::IAccessible2UsageObserver {
public: public:
BrowserAccessibilityManagerWin( BrowserAccessibilityManagerWin(
const ui::AXTreeUpdate& initial_tree, const ui::AXTreeUpdate& initial_tree,
...@@ -33,11 +32,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin ...@@ -33,11 +32,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// Get the closest containing HWND. // Get the closest containing HWND.
HWND GetParentHWND(); HWND GetParentHWND();
// IAccessible2UsageObserver
void OnIAccessible2Used() override;
void OnScreenReaderHoneyPotQueried() override;
void OnAccNameCalled() override;
// BrowserAccessibilityManager methods // BrowserAccessibilityManager methods
void UserIsReloading() override; void UserIsReloading() override;
BrowserAccessibility* GetFocus() override; BrowserAccessibility* GetFocus() override;
......
...@@ -168,6 +168,8 @@ ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const { ...@@ -168,6 +168,8 @@ ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const {
} }
#if !defined(OS_WIN) && !defined(OS_MACOSX) #if !defined(OS_WIN) && !defined(OS_MACOSX)
void BrowserAccessibilityStateImpl::PlatformInitialize() {}
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() { void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
} }
#endif #endif
......
...@@ -84,6 +84,7 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl ...@@ -84,6 +84,7 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl
// Leaky singleton, destructor generally won't be called. // Leaky singleton, destructor generally won't be called.
~BrowserAccessibilityStateImpl() override; ~BrowserAccessibilityStateImpl() override;
void PlatformInitialize();
void UpdatePlatformSpecificHistograms(); void UpdatePlatformSpecificHistograms();
ui::AXMode accessibility_mode_; ui::AXMode accessibility_mode_;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
namespace content { namespace content {
void BrowserAccessibilityStateImpl::PlatformInitialize() {}
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() { void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
// NOTE: This function is running on the file thread. // NOTE: This function is running on the file thread.
NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
......
...@@ -15,9 +15,65 @@ ...@@ -15,9 +15,65 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
namespace content { namespace content {
namespace {
// Enables accessibility based on three possible clues that indicate
// accessibility API usage.
//
// TODO(dmazzoni): Rename IAccessible2UsageObserver to something more general.
class WindowsAccessibilityEnabler : public ui::IAccessible2UsageObserver {
public:
WindowsAccessibilityEnabler() {}
private:
// IAccessible2UsageObserver
void OnIAccessible2Used() override {
// When IAccessible2 APIs have been used elsewhere in the codebase,
// enable basic web accessibility support. (Full screen reader support is
// detected later when specific more advanced APIs are accessed.)
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
void OnScreenReaderHoneyPotQueried() override {
// We used to trust this as a signal that a screen reader is running,
// but it's been abused. Now only enable accessibility if we also
// detect a call to get_accName.
if (screen_reader_honeypot_queried_)
return;
screen_reader_honeypot_queried_ = true;
if (acc_name_called_) {
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
}
void OnAccNameCalled() override {
// See OnScreenReaderHoneyPotQueried, above.
if (acc_name_called_)
return;
acc_name_called_ = true;
if (screen_reader_honeypot_queried_) {
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
}
}
bool screen_reader_honeypot_queried_ = false;
bool acc_name_called_ = false;
};
} // namespace
void BrowserAccessibilityStateImpl::PlatformInitialize() {
ui::GetIAccessible2UsageObserverList().AddObserver(
new WindowsAccessibilityEnabler());
}
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() { void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
// NOTE: this method is run from the file thread to reduce jank, since // NOTE: this method is run from the file thread to reduce jank, since
// there's no guarantee these system calls will return quickly. Be careful // there's no guarantee these system calls will return quickly. Be careful
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment