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 @@
namespace content {
// See OnScreenReaderHoneyPotQueried, below.
bool g_screen_reader_honeypot_queried = false;
bool g_acc_name_called = false;
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate& initial_tree,
......@@ -44,7 +40,6 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
load_complete_pending_(false) {
ui::win::CreateATLModuleIfNeeded();
Initialize(initial_tree);
ui::GetIAccessible2UsageObserverList().AddObserver(this);
}
BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
......@@ -52,7 +47,6 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
// destructor, otherwise our overrides of functions like
// OnNodeWillBeDeleted won't be called.
tree_.reset(NULL);
ui::GetIAccessible2UsageObserverList().RemoveObserver(this);
}
// static
......@@ -76,38 +70,6 @@ HWND BrowserAccessibilityManagerWin::GetParentHWND() {
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() {
if (GetRoot())
FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
......
......@@ -18,8 +18,7 @@ class BrowserAccessibilityWin;
// Manages a tree of BrowserAccessibilityWin objects.
class CONTENT_EXPORT BrowserAccessibilityManagerWin
: public BrowserAccessibilityManager,
public ui::IAccessible2UsageObserver {
: public BrowserAccessibilityManager {
public:
BrowserAccessibilityManagerWin(
const ui::AXTreeUpdate& initial_tree,
......@@ -33,11 +32,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// Get the closest containing HWND.
HWND GetParentHWND();
// IAccessible2UsageObserver
void OnIAccessible2Used() override;
void OnScreenReaderHoneyPotQueried() override;
void OnAccNameCalled() override;
// BrowserAccessibilityManager methods
void UserIsReloading() override;
BrowserAccessibility* GetFocus() override;
......
......@@ -168,6 +168,8 @@ ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const {
}
#if !defined(OS_WIN) && !defined(OS_MACOSX)
void BrowserAccessibilityStateImpl::PlatformInitialize() {}
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
}
#endif
......
......@@ -84,6 +84,7 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl
// Leaky singleton, destructor generally won't be called.
~BrowserAccessibilityStateImpl() override;
void PlatformInitialize();
void UpdatePlatformSpecificHistograms();
ui::AXMode accessibility_mode_;
......
......@@ -18,6 +18,8 @@
namespace content {
void BrowserAccessibilityStateImpl::PlatformInitialize() {}
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
// NOTE: This function is running on the file thread.
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
......
......@@ -15,9 +15,65 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
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() {
// 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
......
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