Revert "[A11yPerformance] Clean up BrowserAccessibilityState"
This reverts commit 8c794f38d3
.
Reason for revert: breaks test on multiple Mac bots crbug.com/404576872
Original change's description:
> [A11yPerformance] Clean up BrowserAccessibilityState
>
> 1. Clarify which methods/variables are related to Auto Disable as
> opposed to just Disable (manually disabling of a11y), so that
> it's no longer confusing what belongs to what intention.
>
> 2. Rename some methods to accurately reflect what they do,
> and add comments:
> * IsRendererAccessibilityEnabled() -> IsAccessibilityAllowed().
> This was not specific to renderers, or whether a11y was enabled.
> It returned true if a11y was not disallowed via the command line.
> * EnableAccessibility() -> EnableCompleteAccessibility().
> This turns on kAXModeComplete.
>
> 3. Remove some poorly named and redundant methods that are not
> actually needed:
> * ResetAccessibilityMode() -- the same as DisableAccessibility().
> * OnScreenReaderDetected() -- did not actually reflect screen
> reader detection and was just a way to EnableAccessibility(), so
> is redundant with that. Any remaining methods and modes with
> "screen reader" in the name will now make sense.
> * OnScreenReaderStopped() -- did not actually reflect the stoppage
> of a screen reader and callers are better off using
> DisableAccessibility().
>
> 4. The new UMA Accessibility.EngineUse.TimeUntilStart that was just
> added was not working on all platforms, because some platforms
> use AddAccessibilityModeFlags() and others use
> EnableAccessibility(). Move the UMA code to
> OnAccessibilityAPIUsage() where it will always be hit.
>
> This relates to a11y performance because it helps build the
> foundation for the auto disable refresh by clarifying what
> different pieces do and cleaning up code paths.
>
> Follow-ups:
> - Audit calls to OnAccessibilityAPIUsed(), such as from
> AXPlatformNodeDelegate::GetRole(). If we don't change that, we'll
> always think that there's new API usage every time we Unserialize
> from a renderer, which breaks the auto-disable heuristic.
> - Use ScopedAccessibilityMode for chrome/browser/apps/app_shim/app_shim_host_mac.cc.
>
> Bug: 401232343
> Change-Id: Id386c378812484aae01e2a93dac90336c0aa7ae3
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6333854
> Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
> Reviewed-by: Greg Thompson <grt@chromium.org>
> Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
> Reviewed-by: Nasko Oskov <nasko@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1434483}
Bug: 401232343,404576872
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Change-Id: I6d43b0fa9d36b7ee0adeaf38b2b04e2b044eea60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6367795
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Takuto Ikuta <tikuta@chromium.org>
Commit-Queue: Ming-Ying Chung <mych@chromium.org>
Owners-Override: Ming-Ying Chung <mych@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1434613}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
0f626f2376
commit
8565da3d27
chrome/browser
content
browser
accessibility
public
shell
@ -948,11 +948,9 @@ AccessibilityPrivateSetNativeAccessibilityEnabledFunction::Run() {
|
||||
EXTENSION_FUNCTION_VALIDATE(args()[0].is_bool());
|
||||
bool enabled = args()[0].GetBool();
|
||||
if (enabled) {
|
||||
content::BrowserAccessibilityState::GetInstance()
|
||||
->EnableProcessAccessibility();
|
||||
content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
|
||||
} else {
|
||||
content::BrowserAccessibilityState::GetInstance()
|
||||
->DisableProcessAccessibility();
|
||||
content::BrowserAccessibilityState::GetInstance()->DisableAccessibility();
|
||||
}
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
@ -265,13 +265,14 @@ void AppShimHost::EnableAccessibilitySupport(
|
||||
content::BrowserAccessibilityState::GetInstance();
|
||||
switch (mode) {
|
||||
case chrome::mojom::AppShimScreenReaderSupportMode::kComplete: {
|
||||
process_accessibility_mode_ =
|
||||
accessibility_state->CreateScopedModeForProcess(ui::kAXModeComplete);
|
||||
accessibility_state->OnScreenReaderDetected();
|
||||
break;
|
||||
}
|
||||
case chrome::mojom::AppShimScreenReaderSupportMode::kPartial: {
|
||||
process_accessibility_mode_ =
|
||||
accessibility_state->CreateScopedModeForProcess(ui::kAXModeBasic);
|
||||
if (!accessibility_state->GetAccessibilityMode().has_mode(
|
||||
ui::kAXModeBasic.flags())) {
|
||||
accessibility_state->AddAccessibilityModeFlags(ui::kAXModeBasic);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "chrome/browser/web_applications/os_integration/mac/app_shim_launch.h"
|
||||
#include "chrome/common/mac/app_shim.mojom.h"
|
||||
#include "components/metrics/histogram_child_process.h"
|
||||
#include "content/public/browser/scoped_accessibility_mode.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@ -206,10 +205,6 @@ class AppShimHost : public chrome::mojom::AppShimHost,
|
||||
// This class is only ever to be used on the UI thread.
|
||||
THREAD_CHECKER(thread_checker_);
|
||||
|
||||
// Will be created if accessibility APIs are needed, e.g. if the VoiceOver
|
||||
// screen reader is enabled.
|
||||
std::unique_ptr<content::ScopedAccessibilityMode> process_accessibility_mode_;
|
||||
|
||||
// This weak factory is used for launch callbacks only.
|
||||
base::WeakPtrFactory<AppShimHost> launch_weak_factory_;
|
||||
};
|
||||
|
@ -460,9 +460,9 @@ std::string DescriptionForNSEvent(NSEvent* event) {
|
||||
content::BrowserAccessibilityState::GetInstance();
|
||||
|
||||
if (enable) {
|
||||
accessibility_state->EnableProcessAccessibility();
|
||||
accessibility_state->OnScreenReaderDetected();
|
||||
} else {
|
||||
accessibility_state->DisableProcessAccessibility();
|
||||
accessibility_state->OnScreenReaderStopped();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,8 +195,8 @@ void HandleAccessibilityRequestCallback(
|
||||
PrefService* pref = Profile::FromBrowserContext(current_context)->GetPrefs();
|
||||
ui::AXMode mode =
|
||||
content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
|
||||
bool is_a11y_allowed = content::BrowserAccessibilityState::GetInstance()
|
||||
->IsAccessibilityAllowed();
|
||||
bool is_native_enabled = content::BrowserAccessibilityState::GetInstance()
|
||||
->IsRendererAccessibilityEnabled();
|
||||
bool native = mode.has_mode(ui::AXMode::kNativeAPIs);
|
||||
bool web = mode.has_mode(ui::AXMode::kWebContents);
|
||||
bool text = mode.has_mode(ui::AXMode::kInlineTextBoxes);
|
||||
@ -206,12 +206,12 @@ void HandleAccessibilityRequestCallback(
|
||||
|
||||
// The "native" and "web" flags are disabled if
|
||||
// --disable-renderer-accessibility is set.
|
||||
data.Set(kNative, is_a11y_allowed ? (native ? kOn : kOff) : kDisabled);
|
||||
data.Set(kWeb, is_a11y_allowed ? (web ? kOn : kOff) : kDisabled);
|
||||
data.Set(kNative, is_native_enabled ? (native ? kOn : kOff) : kDisabled);
|
||||
data.Set(kWeb, is_native_enabled ? (web ? kOn : kOff) : kDisabled);
|
||||
|
||||
// The "text", "extendedProperties" and "html" flags are only
|
||||
// meaningful if "web" is enabled.
|
||||
bool is_web_enabled = is_a11y_allowed && web;
|
||||
bool is_web_enabled = is_native_enabled && web;
|
||||
data.Set(kText, is_web_enabled ? (text ? kOn : kOff) : kDisabled);
|
||||
data.Set(kExtendedProperties,
|
||||
is_web_enabled ? (extendedProperties ? kOn : kOff) : kDisabled);
|
||||
@ -280,7 +280,7 @@ void HandleAccessibilityRequestCallback(
|
||||
}
|
||||
|
||||
base::Value::Dict descriptor = BuildTargetDescriptor(rvh);
|
||||
descriptor.Set(kNative, is_a11y_allowed);
|
||||
descriptor.Set(kNative, is_native_enabled);
|
||||
descriptor.Set(kExtendedProperties, is_web_enabled && extendedProperties);
|
||||
descriptor.Set(kWeb, is_web_enabled);
|
||||
page_list.Append(std::move(descriptor));
|
||||
|
@ -335,7 +335,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, ReEnablingDoesNotAlterUniqueIds) {
|
||||
int32_t unique_id_2 = button_2->GetAXPlatformNode()->GetUniqueId();
|
||||
|
||||
// Turn accessibility off again.
|
||||
BrowserAccessibilityState::GetInstance()->DisableProcessAccessibility();
|
||||
BrowserAccessibilityState::GetInstance()->ResetAccessibilityMode();
|
||||
accessibility_mode = web_contents()->GetAccessibilityMode();
|
||||
ASSERT_TRUE(accessibility_mode.is_mode_off());
|
||||
EXPECT_EQ(nullptr, GetManager());
|
||||
|
@ -2342,8 +2342,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
|
||||
EXPECT_TRUE(found);
|
||||
|
||||
// Remove all accessibility modes.
|
||||
content::BrowserAccessibilityState::GetInstance()
|
||||
->DisableProcessAccessibility();
|
||||
content::BrowserAccessibilityState::GetInstance()->ResetAccessibilityMode();
|
||||
|
||||
// Ensure accessibility is not enabled before we begin the test.
|
||||
EXPECT_TRUE(content::BrowserAccessibilityStateImpl::GetInstance()
|
||||
@ -6556,7 +6555,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
|
||||
|
||||
WebContentsImpl* web_contents =
|
||||
static_cast<WebContentsImpl*>(shell()->web_contents());
|
||||
BrowserAccessibilityState::GetInstance()->DisableProcessAccessibility();
|
||||
BrowserAccessibilityState::GetInstance()->ResetAccessibilityMode();
|
||||
auto accessibility_mode = web_contents->GetAccessibilityMode();
|
||||
ASSERT_TRUE(accessibility_mode.is_mode_off());
|
||||
EXPECT_EQ(nullptr, GetManager());
|
||||
@ -6584,7 +6583,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
|
||||
int32_t unique_id_2 = button_2->GetAXPlatformNode()->GetUniqueId();
|
||||
|
||||
// Turn accessibility off again.
|
||||
BrowserAccessibilityState::GetInstance()->DisableProcessAccessibility();
|
||||
BrowserAccessibilityState::GetInstance()->ResetAccessibilityMode();
|
||||
accessibility_mode = web_contents->GetAccessibilityMode();
|
||||
ASSERT_TRUE(accessibility_mode.is_mode_off());
|
||||
EXPECT_EQ(nullptr, GetManager());
|
||||
|
@ -50,6 +50,13 @@ constexpr int kAutoDisableAccessibilityEventCount = 3;
|
||||
// good for perf. Instead, delay the update task.
|
||||
constexpr int kOnAccessibilityUsageUpdateDelaySecs = 5;
|
||||
|
||||
// How long to wait after `OnScreenReaderStopped` was called before actually
|
||||
// disabling accessibility support. The main use case is when a screen reader
|
||||
// or other client is toggled off and on in rapid succession. We don't want to
|
||||
// destroy the full accessibility tree only to immediately recreate it because
|
||||
// doing so is bad for performance.
|
||||
constexpr int kDisableAccessibilitySupportDelaySecs = 2;
|
||||
|
||||
// Used for validating the 'basic' bundle parameter for
|
||||
// --force-renderer-accessibility.
|
||||
const char kAXModeBundleBasic[] = "basic";
|
||||
@ -267,6 +274,32 @@ BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() {
|
||||
g_instance = nullptr;
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::OnScreenReaderDetected() {
|
||||
// Clear any previous, now obsolete, request to disable support.
|
||||
disable_accessibility_request_time_ = base::TimeTicks();
|
||||
|
||||
if (!allow_ax_mode_changes_) {
|
||||
return;
|
||||
}
|
||||
EnableAccessibility();
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::OnScreenReaderStopped() {
|
||||
disable_accessibility_request_time_ = ui::EventTimeForNow();
|
||||
|
||||
// If a screen reader or other client using accessibility API is toggled off
|
||||
// and on in short succession, we risk destroying and recreating large
|
||||
// accessibility trees unnecessarily which is bad for performance. So we post
|
||||
// a delayed task here, and only reset accessibility mode if nothing has
|
||||
// requested accessibility support be re-enabled after that delay has passed.
|
||||
GetUIThreadTaskRunner({})->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
&BrowserAccessibilityStateImpl::MaybeResetAccessibilityMode,
|
||||
weak_factory_.GetWeakPtr()),
|
||||
base::Seconds(kDisableAccessibilitySupportDelaySecs));
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::OnAssistiveTechFound(
|
||||
ui::AssistiveTech assistive_tech) {
|
||||
ax_platform_.NotifyAssistiveTechChanged(assistive_tech);
|
||||
@ -281,16 +314,66 @@ ui::AssistiveTech BrowserAccessibilityStateImpl::ActiveAssistiveTech() const {
|
||||
return ui::AXPlatform::GetInstance().active_assistive_tech();
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::EnableProcessAccessibility() {
|
||||
SetProcessMode(ui::kAXModeComplete);
|
||||
void BrowserAccessibilityStateImpl::EnableAccessibility() {
|
||||
if (!allow_ax_mode_changes_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Track the time since start-up before the kWebContents mode was enabled,
|
||||
// ensuring we record this value only one time.
|
||||
if (!has_enabled_accessibility_in_session_ &&
|
||||
GetAccessibilityMode().has_mode(ui::AXMode::kWebContents)) {
|
||||
has_enabled_accessibility_in_session_ = true;
|
||||
UMA_HISTOGRAM_LONG_TIMES_100("Accessibility.EngineUse.TimeUntilStart",
|
||||
timer_.Elapsed());
|
||||
}
|
||||
|
||||
// Enabling accessibility is generally the result of an accessibility API
|
||||
// call, so we should also reset the auto-disable accessibility code. The only
|
||||
// exception is in tests or when a user manually toggles accessibility flags
|
||||
// in chrome://accessibility.
|
||||
OnAccessibilityApiUsage();
|
||||
|
||||
const ui::AXMode previous_mode = process_accessibility_mode_->mode();
|
||||
|
||||
// First disable any non-additive modes that restrict or filter the
|
||||
// information available in the tree.
|
||||
const ui::AXMode new_mode =
|
||||
(previous_mode & ~ui::kAXModeFormControls) | ui::kAXModeComplete;
|
||||
|
||||
process_accessibility_mode_ = CreateScopedModeForProcess(new_mode);
|
||||
}
|
||||
|
||||
bool BrowserAccessibilityStateImpl::IsAccessibilityAllowed() {
|
||||
void BrowserAccessibilityStateImpl::DisableAccessibility() {
|
||||
ResetAccessibilityMode();
|
||||
}
|
||||
|
||||
bool BrowserAccessibilityStateImpl::IsRendererAccessibilityEnabled() {
|
||||
return !base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableRendererAccessibility);
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::DisableProcessAccessibility() {
|
||||
void BrowserAccessibilityStateImpl::MaybeResetAccessibilityMode() {
|
||||
// `OnScreenReaderStopped` sets `disable_accessibility_request_time_`, and
|
||||
// `OnScreenReaderDetected` clears it. If we no longer have a request time
|
||||
// to disable accessibility, this delayed task is obsolete.
|
||||
if (disable_accessibility_request_time_.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// `OnScreenReaderStopped` could be called multiple times prior to the delay
|
||||
// expiring. The value of `disable_accessibility_request_time_` is updated
|
||||
// for every call. If we're running this task prior to the delay expiring,
|
||||
// this request time to disable accessibility is obsolete.
|
||||
if ((base::TimeTicks::Now() - disable_accessibility_request_time_) <
|
||||
base::Seconds(kDisableAccessibilitySupportDelaySecs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetAccessibilityMode();
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::ResetAccessibilityMode() {
|
||||
SetProcessMode(ui::AXMode());
|
||||
}
|
||||
|
||||
@ -438,7 +521,7 @@ void BrowserAccessibilityStateImpl::OnUserInputEvent() {
|
||||
now - accessibility_enabled_time_);
|
||||
|
||||
accessibility_disabled_time_ = now;
|
||||
DisableProcessAccessibility();
|
||||
DisableAccessibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -460,6 +543,16 @@ void BrowserAccessibilityStateImpl::NotifyWebContentsPreferencesChanged()
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
|
||||
if (!allow_ax_mode_changes_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Adding an accessibility mode flag is generally the result of an
|
||||
// accessibility API call, so we should also reset the auto-disable
|
||||
// accessibility code. The only exception is in tests or when a user manually
|
||||
// toggles accessibility flags in chrome://accessibility.
|
||||
OnAccessibilityApiUsage();
|
||||
|
||||
// Update process_accessibility_mode_ via SetProcessMode so that the remainder
|
||||
// of processing is identical to when AXPlatformNode::NotifyAddAXModeFlags()
|
||||
// is called -- it will defer to AXPlatform::SetMode() to update the global
|
||||
@ -473,7 +566,15 @@ void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {
|
||||
|
||||
void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(
|
||||
ui::AXMode mode) {
|
||||
SetProcessMode(process_accessibility_mode_->mode() & ~mode);
|
||||
// Turning off accessibility or changing the mode will not be allowed if the
|
||||
// --force-renderer-accessibility or --disable-renderer-accessibility command
|
||||
// line flags are present, or during testing
|
||||
if (!allow_ax_mode_changes_) {
|
||||
return;
|
||||
}
|
||||
|
||||
process_accessibility_mode_ =
|
||||
CreateScopedModeForProcess(process_accessibility_mode_->mode() & ~mode);
|
||||
}
|
||||
|
||||
base::CallbackListSubscription
|
||||
@ -491,21 +592,10 @@ ui::AXMode BrowserAccessibilityStateImpl::GetProcessMode() {
|
||||
// Replaces the scoper that backs the legacy process-wide mode with one applying
|
||||
// `new_mode`.
|
||||
void BrowserAccessibilityStateImpl::SetProcessMode(ui::AXMode new_mode) {
|
||||
UMA_HISTOGRAM_BOOLEAN(
|
||||
"Accessibility.ManuallyEnabled",
|
||||
!GetAccessibilityMode().is_mode_off() && !allow_ax_mode_changes_);
|
||||
|
||||
if (!allow_ax_mode_changes_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!new_mode.is_mode_off()) {
|
||||
// Unless the mode is being turned off, setting accessibility flags is
|
||||
// generally caused by accessibility API call, so we should also reset the
|
||||
// auto-disable accessibility code.
|
||||
OnAccessibilityApiUsage();
|
||||
}
|
||||
|
||||
const ui::AXMode previous_mode = GetAccessibilityMode();
|
||||
if (new_mode == previous_mode) {
|
||||
return;
|
||||
@ -535,15 +625,6 @@ void BrowserAccessibilityStateImpl::OnAccessibilityApiUsage() {
|
||||
base::Unretained(this)),
|
||||
base::Seconds(kOnAccessibilityUsageUpdateDelaySecs));
|
||||
}
|
||||
|
||||
// Track the time since start-up before the kWebContents mode was enabled,
|
||||
// ensuring we record this value only one time.
|
||||
if (!has_enabled_accessibility_in_session_ &&
|
||||
GetAccessibilityMode().has_mode(ui::AXMode::kWebContents)) {
|
||||
has_enabled_accessibility_in_session_ = true;
|
||||
UMA_HISTOGRAM_LONG_TIMES_100("Accessibility.EngineUse.TimeUntilStart",
|
||||
timer_.Elapsed());
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserAccessibilityStateImpl::OnInputEvent(
|
||||
|
@ -68,15 +68,22 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl
|
||||
virtual void InitBackgroundTasks();
|
||||
|
||||
// BrowserAccessibilityState implementation.
|
||||
void EnableProcessAccessibility() override;
|
||||
void DisableProcessAccessibility() override;
|
||||
bool IsAccessibilityAllowed() override;
|
||||
void EnableAccessibility() override;
|
||||
void DisableAccessibility() override;
|
||||
bool IsRendererAccessibilityEnabled() override;
|
||||
ui::AXMode GetAccessibilityMode() override;
|
||||
ui::AXMode GetAccessibilityModeForBrowserContext(
|
||||
BrowserContext* browser_context) override;
|
||||
// TODO(aleventhal): Rename this to Add/RemoveProcessAccessibilityFlags()
|
||||
void AddAccessibilityModeFlags(ui::AXMode mode) override;
|
||||
void RemoveAccessibilityModeFlags(ui::AXMode mode) override;
|
||||
void ResetAccessibilityMode() override;
|
||||
// These methods indicate the presence of AXMode::kAllProperties, which is
|
||||
// a misnomer because it is used by many clients, and not just screen readers.
|
||||
// Methods with "AssistiveTech" in the name deal with actual
|
||||
// screen reader usage.
|
||||
// TODO(accessibility) Rename these methods to fix the misnomer.
|
||||
void OnScreenReaderDetected() override;
|
||||
void OnScreenReaderStopped() override;
|
||||
// Some platforms have a strong signal indicating the presence of a
|
||||
// screen reader and can call in to let us know when one has
|
||||
// been enabled/disabled.
|
||||
@ -244,6 +251,8 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl
|
||||
// ResetAccessibilityMode(); and applies them to all WebContentses in the
|
||||
// process. Guaranteed to hold at least an instance with no mode flags set.
|
||||
std::unique_ptr<ScopedAccessibilityMode> process_accessibility_mode_;
|
||||
|
||||
base::WeakPtrFactory<BrowserAccessibilityStateImpl> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
|
@ -42,7 +42,7 @@ class BrowserAccessibilityStateImplTest : public ::testing::Test {
|
||||
|
||||
void TearDown() override {
|
||||
// Disable accessibility so that it does not impact subsequent tests.
|
||||
state_->DisableProcessAccessibility();
|
||||
state_->DisableAccessibility();
|
||||
}
|
||||
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
@ -63,7 +63,7 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::AXMode());
|
||||
|
||||
// Enable accessibility based on usage of accessibility APIs.
|
||||
state_->EnableProcessAccessibility();
|
||||
state_->EnableAccessibility();
|
||||
// Indicate that an actual screen reader is not running (a screen reader
|
||||
// will prevent auto-disable from taking place).
|
||||
state_->SetScreenReaderAppActive(false);
|
||||
@ -98,7 +98,7 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::AXMode());
|
||||
|
||||
// Enable accessibility based on usage of accessibility APIs.
|
||||
state_->EnableProcessAccessibility();
|
||||
state_->OnScreenReaderDetected();
|
||||
// Indicate that an actual screen reader is not running (a screen reader
|
||||
// will prevent auto-disable from taking place).
|
||||
state_->SetScreenReaderAppActive(false);
|
||||
@ -144,10 +144,7 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::AXMode());
|
||||
|
||||
// Enable accessibility.
|
||||
state_->EnableProcessAccessibility();
|
||||
// Indicate that an actual screen reader is not running (a screen reader
|
||||
// will prevent auto-disable from taking place).
|
||||
state_->SetScreenReaderAppActive(false);
|
||||
state_->OnScreenReaderDetected();
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::kAXModeComplete);
|
||||
|
||||
@ -193,7 +190,7 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::AXMode());
|
||||
|
||||
// Enable accessibility.
|
||||
state_->EnableProcessAccessibility();
|
||||
state_->OnScreenReaderDetected();
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::kAXModeComplete);
|
||||
|
||||
@ -210,6 +207,55 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EXPECT_EQ(ui::AXPlatform::GetInstance().GetMode(), ui::kAXModeComplete);
|
||||
}
|
||||
|
||||
TEST_F(BrowserAccessibilityStateImplTest, DisableAccessibilityHasADelay) {
|
||||
// Initially accessibility should be disabled.
|
||||
EXPECT_FALSE(state_->IsAccessibleBrowser());
|
||||
|
||||
// Enable accessibility.
|
||||
state_->OnScreenReaderDetected();
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
|
||||
// After 10 seconds, disable accessibility in response to client being quit.
|
||||
task_environment_.FastForwardBy(base::Seconds(10));
|
||||
state_->OnScreenReaderStopped();
|
||||
|
||||
// After one second, accessibility support should still be enabled. This is
|
||||
// because we delay disabling accessibility support in response to the client
|
||||
// being quit just in case it is about to be toggled back on.
|
||||
task_environment_.FastForwardBy(base::Seconds(1));
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
|
||||
// After the delay has passed without support being re-enabled, accessibility
|
||||
// should now be disabled.
|
||||
task_environment_.FastForwardBy(base::Seconds(10));
|
||||
EXPECT_FALSE(state_->IsAccessibleBrowser());
|
||||
}
|
||||
|
||||
TEST_F(BrowserAccessibilityStateImplTest,
|
||||
EnableImmediatelyAfterDisablePreventsDisable) {
|
||||
// Initially accessibility should be disabled.
|
||||
EXPECT_FALSE(state_->IsAccessibleBrowser());
|
||||
|
||||
// Enable accessibility.
|
||||
state_->OnScreenReaderDetected();
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
|
||||
// After 10 seconds, disable accessibility in response to client being quit.
|
||||
// Then re-enable it immediately. Accessibility support should never get
|
||||
// disabled because it was re-enabled before the delay to disable support
|
||||
// had passed.
|
||||
task_environment_.FastForwardBy(base::Seconds(10));
|
||||
state_->OnScreenReaderStopped();
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
|
||||
task_environment_.FastForwardBy(base::Milliseconds(10));
|
||||
state_->OnScreenReaderDetected();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
task_environment_.FastForwardBy(base::Seconds(i));
|
||||
EXPECT_TRUE(state_->IsAccessibleBrowser());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
using ::testing::_;
|
||||
|
||||
@ -232,11 +278,11 @@ TEST_F(BrowserAccessibilityStateImplTest,
|
||||
|
||||
// Enable accessibility.
|
||||
EXPECT_CALL(mock_observer, OnAXModeAdded(ui::kAXModeComplete));
|
||||
state_->EnableProcessAccessibility();
|
||||
state_->OnScreenReaderDetected();
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_observer);
|
||||
|
||||
// A second call should be a no-op.
|
||||
state_->EnableProcessAccessibility();
|
||||
state_->OnScreenReaderDetected();
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_observer);
|
||||
}
|
||||
|
||||
|
@ -481,7 +481,7 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
|
||||
// Start with no AXMode, so that in case the test was run with
|
||||
// --force-renderer-accessibility, we can still set the correct mode for the
|
||||
// test, e.g. form controls mode.
|
||||
BrowserAccessibilityState::GetInstance()->DisableProcessAccessibility();
|
||||
BrowserAccessibilityState::GetInstance()->DisableAccessibility();
|
||||
|
||||
if (enable_accessibility_after_navigating_ &&
|
||||
web_contents->GetAccessibilityMode().is_mode_off()) {
|
||||
|
@ -586,7 +586,7 @@ void WebContentsAccessibilityAndroid::DisableRendererAccessibility(
|
||||
// Turn off accessibility on the renderer side by resetting the AXMode.
|
||||
BrowserAccessibilityStateImpl* accessibility_state =
|
||||
BrowserAccessibilityStateImpl::GetInstance();
|
||||
accessibility_state->DisableProcessAccessibility();
|
||||
accessibility_state->ResetAccessibilityMode();
|
||||
}
|
||||
|
||||
void WebContentsAccessibilityAndroid::ReEnableRendererAccessibility(
|
||||
@ -2209,7 +2209,7 @@ void JNI_WebContentsAccessibilityImpl_SetBrowserAXMode(
|
||||
// When the browser is not yet accessible, then set the AXMode to
|
||||
// |ui::kAXModeComplete| for all web contents.
|
||||
if (!accessibility_state->IsAccessibleBrowser()) {
|
||||
accessibility_state->EnableProcessAccessibility();
|
||||
accessibility_state->OnScreenReaderDetected();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -32,24 +32,15 @@ class CONTENT_EXPORT BrowserAccessibilityState {
|
||||
static BrowserAccessibilityState* GetInstance();
|
||||
|
||||
// Enables accessibility for all running tabs.
|
||||
// Called when an accessibility client is detected.
|
||||
// It is often preferable to use ScopedAccessibilityMode.
|
||||
// The process AXMode is the default used for new WebContents and pages.
|
||||
// When no mode argument is passed, ui::kAXModeComplete is assumed.
|
||||
virtual void EnableProcessAccessibility() = 0;
|
||||
virtual void EnableAccessibility() = 0;
|
||||
|
||||
// Disables accessibility for all running tabs. (Only if accessibility is not
|
||||
// required by a command line flag or by a platform requirement.)
|
||||
// Called when all AXModes should be turned off.
|
||||
// By default, new WebContents and pages will not have accessibility on.
|
||||
virtual void DisableProcessAccessibility() = 0;
|
||||
virtual void DisableAccessibility() = 0;
|
||||
|
||||
// Returns true if accessibility is not disallowed via
|
||||
// Returns true if renderer accessibility is not disabled via
|
||||
// --disable-renderer-accessibility on the process's command line.
|
||||
// Note: the command line flag --disable-renderer-accessibility is a misnomer
|
||||
// because it also disables accessibility in non-renderer contexts, such as
|
||||
// UI.
|
||||
virtual bool IsAccessibilityAllowed() = 0;
|
||||
virtual bool IsRendererAccessibilityEnabled() = 0;
|
||||
|
||||
// Returns the effective accessibility mode for the process. Individual
|
||||
// WebContentses may have an effective mode that is a superset of this as a
|
||||
@ -91,6 +82,22 @@ class CONTENT_EXPORT BrowserAccessibilityState {
|
||||
// accessibility mode bitmap.
|
||||
virtual void RemoveAccessibilityModeFlags(ui::AXMode mode) = 0;
|
||||
|
||||
// DEPRECATED. Resets accessibility to the platform default for all running
|
||||
// tabs. This is probably off, but may be on, if
|
||||
// --force_renderer_accessibility is passed, or EditableTextOnly if this is
|
||||
// Win7.
|
||||
virtual void ResetAccessibilityMode() = 0;
|
||||
|
||||
// Called when an accessibility client is detected, using a heuristic.
|
||||
// These methods indicate the presence of AXMode::kExtendedProperties.
|
||||
// The current method name is a misnomer because it is used by many clients,
|
||||
// and not just screen readers.
|
||||
// TODO(accessibility) Remove this method.
|
||||
virtual void OnScreenReaderDetected() = 0;
|
||||
|
||||
// Called when kExtendedProperties mode should be turned off.
|
||||
virtual void OnScreenReaderStopped() = 0;
|
||||
|
||||
// Some platforms have a strong signal indicating the presence of a
|
||||
// screen reader and can call in to let us know when one has
|
||||
// been enabled/disabled. This should be called for screen readers only.
|
||||
|
@ -237,8 +237,7 @@ static const char kAllTracingCategories[] = "*";
|
||||
|
||||
// Enable Accessibility if VoiceOver is already running.
|
||||
if (UIAccessibilityIsVoiceOverRunning()) {
|
||||
content::BrowserAccessibilityState::GetInstance()
|
||||
->EnableProcessAccessibility();
|
||||
content::BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
|
||||
}
|
||||
|
||||
// Register for VoiceOver notifications.
|
||||
@ -422,11 +421,9 @@ static const char kAllTracingCategories[] = "*";
|
||||
content::BrowserAccessibilityState* accessibility_state =
|
||||
content::BrowserAccessibilityState::GetInstance();
|
||||
if (UIAccessibilityIsVoiceOverRunning()) {
|
||||
accessibility_state->EnableProcessAccessibility();
|
||||
accessibility_state->SetScreenReaderAppActive(true);
|
||||
accessibility_state->OnScreenReaderDetected();
|
||||
} else {
|
||||
accessibility_state->DisableProcessAccessibility();
|
||||
accessibility_state->SetScreenReaderAppActive(false);
|
||||
accessibility_state->OnScreenReaderStopped();
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
Reference in New Issue
Block a user