Skip to content

Commit

Permalink
Add experimental flag to AXMode for filtering to Form Controls
Browse files Browse the repository at this point in the history
The experimental flag field will be used for a form controls
AXMode and potential new future AXModes.

The experimental flag will indicate to the accessibility
engine what information to potentially filter out of the
accessibility tree.

AX-Relnotes: N/A
Bug: 1411856
Change-Id: I85e4ad2d9cd8ee3121750a3c56cd782ebd035ffc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4220172
Reviewed-by: David Tseng <dtseng@chromium.org>
Reviewed-by: Chris Bookholt <bookholt@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Amanda Lin Dietz <aldietz@google.com>
Cr-Commit-Position: refs/heads/main@{#1103956}
  • Loading branch information
aldietz authored and Chromium LUCI CQ committed Feb 10, 2023
1 parent 71bcbcd commit e44a1e4
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 17 deletions.
54 changes: 44 additions & 10 deletions content/browser/accessibility/browser_accessibility_state_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,21 @@ constexpr int kOnAccessibilityUsageUpdateDelaySecs = 5;
// doing so is bad for performance.
constexpr int kDisableAccessibilitySupportDelaySecs = 2;

// Record a histograms for an accessibility mode when it's enabled.
// Record a histogram for an accessibility mode when it is enabled.
void RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue mode_flag) {
UMA_HISTOGRAM_ENUMERATION(
"Accessibility.ModeFlag", mode_flag,
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_MAX);
}

// Record a histogram for an experimental accessibility mode when it is enabled.
void RecordNewExperimentalAccessibilityModeFlags(
ui::AXMode::ExperimentalModeFlagHistogramValue experimental_mode_flag) {
// TODO(aldietz): Add histogram enumeration for
// "Accessibility.ExperimentalModeFlag"
}

// Update the accessibility histogram 45 seconds after initialization.
static const int ACCESSIBILITY_HISTOGRAM_DELAY_SECS = 45;

Expand Down Expand Up @@ -399,30 +406,54 @@ void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags(ui::AXMode mode) {

// Retrieve only newly added modes for the purposes of logging.
int new_mode_flags = mode.flags() & (~previous_mode.flags());
if (new_mode_flags & ui::AXMode::kNativeAPIs)
if (new_mode_flags & ui::AXMode::kNativeAPIs) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_NATIVE_APIS);
if (new_mode_flags & ui::AXMode::kWebContents)
}

if (new_mode_flags & ui::AXMode::kWebContents) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_WEB_CONTENTS);
if (new_mode_flags & ui::AXMode::kInlineTextBoxes)
}

if (new_mode_flags & ui::AXMode::kInlineTextBoxes) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_INLINE_TEXT_BOXES);
if (new_mode_flags & ui::AXMode::kScreenReader)
}

if (new_mode_flags & ui::AXMode::kScreenReader) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_SCREEN_READER);
if (new_mode_flags & ui::AXMode::kHTML)
}

if (new_mode_flags & ui::AXMode::kHTML) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_HTML);
if (new_mode_flags & ui::AXMode::kHTMLMetadata)
}

if (new_mode_flags & ui::AXMode::kHTMLMetadata) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_HTML_METADATA);
if (new_mode_flags & ui::AXMode::kLabelImages)
}

if (new_mode_flags & ui::AXMode::kLabelImages) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_LABEL_IMAGES);
if (new_mode_flags & ui::AXMode::kPDF)
}

if (new_mode_flags & ui::AXMode::kPDF) {
RecordNewAccessibilityModeFlags(
ui::AXMode::ModeFlagHistogramValue::UMA_AX_MODE_PDF);
}

// Retrieve only newly added experimental modes for the purposes of logging.
int new_experimental_mode_flags =
mode.experimental_flags() & (~previous_mode.experimental_flags());
if (new_experimental_mode_flags & ui::AXMode::kExperimentalFormControls) {
RecordNewExperimentalAccessibilityModeFlags(
ui::AXMode::ExperimentalModeFlagHistogramValue::
UMA_AX_EXPERIMENTAL_MODE_FORM_CONTROLS);
}

std::vector<WebContentsImpl*> web_contents_vector =
WebContentsImpl::GetAllWebContents();
Expand All @@ -447,7 +478,10 @@ void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags(

int raw_flags = accessibility_mode_.flags() ^
(mode.flags() & accessibility_mode_.flags());
accessibility_mode_ = raw_flags;
int raw_experimental_flags =
accessibility_mode_.experimental_flags() ^
(mode.experimental_flags() & accessibility_mode_.experimental_flags());
accessibility_mode_ = ui::AXMode(raw_flags, raw_experimental_flags);

// Proxy the new AXMode to AXPlatformNode.
ui::AXPlatformNode::SetAXMode(accessibility_mode_);
Expand Down
2 changes: 1 addition & 1 deletion content/browser/renderer_host/render_frame_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9866,7 +9866,7 @@ void RenderFrameHostImpl::UpdateAccessibilityMode() {
GetRemoteAssociatedInterfaces()->GetInterface(&render_accessibility_);
DCHECK(render_accessibility_);
}
render_accessibility_->SetMode(ax_mode.flags());
render_accessibility_->SetMode(ax_mode);
} else {
// Resetting the Remote signals the renderer to shutdown accessibility
// in the renderer.
Expand Down
3 changes: 2 additions & 1 deletion content/browser/web_contents/web_contents_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,7 @@ void WebContentsImpl::SetAccessibilityMode(ui::AXMode mode) {
return;

accessibility_mode_ = mode;

// Update state for all frames in this tree and inner trees. Should also
// include speculative frame hosts.
GetPrimaryMainFrame()->ForEachRenderFrameHostIncludingSpeculative(
Expand Down Expand Up @@ -4628,7 +4629,7 @@ void WebContentsImpl::RecordAccessibilityEvents(
DCHECK_EQ(start_recording, callback.has_value());
if (start_recording) {
BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
ui::kAXModeBasic.flags());
ui::kAXModeBasic);
auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager();
CHECK(ax_mgr);
base::ProcessId pid = base::Process::Current().Pid();
Expand Down
3 changes: 3 additions & 0 deletions ui/accessibility/PRESUBMIT.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ def CheckModesMatch(input_api, output_api):
'kAXModeWebContentsOnly',
'kAXModeComplete',
'kAXModeCompleteNoHTML',
'kExperimentalFirstFlag',
'kExperimentalFormControls',
'kExperimentalLastFlag',
]

for value in ax_modes_in_header:
Expand Down
27 changes: 27 additions & 0 deletions ui/accessibility/ax_mode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ std::ostream& operator<<(std::ostream& stream, const AXMode& mode) {
return stream << mode.ToString();
}

bool AXMode::HasExperimentalFlags(uint32_t experimental_flag) const {
return (experimental_flags_ & experimental_flag) == experimental_flag;
}

void AXMode::SetExperimentalFlags(uint32_t experimental_flag, bool value) {
experimental_flags_ = value ? (experimental_flags_ | experimental_flag)
: (experimental_flags_ & ~experimental_flag);
}

std::string AXMode::ToString() const {
std::vector<base::StringPiece> tokens;

Expand Down Expand Up @@ -55,6 +64,24 @@ std::string AXMode::ToString() const {
if (has_mode(mode_flag))
tokens.push_back(flag_name);
}

for (uint32_t experimental_mode_flag = AXMode::kExperimentalFirstFlag;
experimental_mode_flag <= AXMode::kExperimentalLastFlag;
experimental_mode_flag = experimental_mode_flag << 1) {
base::StringPiece flag_name;
switch (experimental_mode_flag) {
case AXMode::kExperimentalFormControls:
flag_name = "kExperimentalFormControls";
break;
}

DCHECK(!flag_name.empty());

if (HasExperimentalFlags(experimental_mode_flag)) {
tokens.push_back(flag_name);
}
}

return base::JoinString(tokens, " | ");
}

Expand Down
42 changes: 37 additions & 5 deletions ui/accessibility/ax_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,11 @@ class AX_BASE_EXPORT AXMode {
// related metrics callsites, see: |ModeFlagHistogramValue|).
static constexpr uint32_t kLastModeFlag = 1 << 7;

constexpr AXMode() : flags_(kNone) {}
constexpr AXMode(uint32_t flags) : flags_(flags) {}
constexpr AXMode() : flags_(kNone), experimental_flags_(kNone) {}
constexpr AXMode(uint32_t flags)
: flags_(flags), experimental_flags_(kNone) {}
constexpr AXMode(uint32_t flags, uint32_t experimental_flags)
: flags_(flags), experimental_flags_(experimental_flags) {}

bool has_mode(uint32_t flag) const { return (flags_ & flag) == flag; }

Expand All @@ -89,20 +92,27 @@ class AX_BASE_EXPORT AXMode {

uint32_t flags() const { return flags_; }

bool operator==(AXMode rhs) const { return flags_ == rhs.flags_; }
uint32_t experimental_flags() const { return experimental_flags_; }

bool operator==(AXMode rhs) const {
return flags_ == rhs.flags_ &&
experimental_flags_ == rhs.experimental_flags_;
}

bool is_mode_off() const { return flags_ == 0; }

bool operator!=(AXMode rhs) const { return !(*this == rhs); }

AXMode& operator|=(const AXMode& rhs) {
flags_ |= rhs.flags_;
experimental_flags_ |= rhs.experimental_flags_;
return *this;
}

std::string ToString() const;
bool HasExperimentalFlags(uint32_t experimental_flag) const;
void SetExperimentalFlags(uint32_t experimental_flag, bool value);

uint32_t flags_ = 0U;
std::string ToString() const;

// IMPORTANT!
// These values are written to logs. Do not renumber or delete
Expand All @@ -121,6 +131,28 @@ class AX_BASE_EXPORT AXMode {
// increase, but none of the other enum values may change.
UMA_AX_MODE_MAX
};

// Experimental Flags
// These are currently defined separately from existing flags to avoid
// making temporary changes to the defined enums until they are ready
// for production release.
static constexpr uint32_t kExperimentalFirstFlag = 1 << 0;
static constexpr uint32_t kExperimentalFormControls = 1 << 0;
static constexpr uint32_t kExperimentalLastFlag = 1 << 0;

// IMPORTANT!
// These values are written to logs. Do not renumber or delete
// existing items; add new entries to the end of the list.
enum class ExperimentalModeFlagHistogramValue {
UMA_AX_EXPERIMENTAL_MODE_FORM_CONTROLS = 0,

// This must always be the last enum. It's okay for its value to
// increase, but none of the other enum values may change.
UMA_AX_EXPERIMENTAL_MODE_MAX
};

uint32_t flags_ = 0U;
uint32_t experimental_flags_ = 0U;
};

// Used when an AT that only require basic accessibility information, such as
Expand Down
1 change: 1 addition & 0 deletions ui/accessibility/mojom/ax_mode.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ module ax.mojom;
// See ui::AXMode for additional documentation about individual flags and modes.
struct AXMode {
uint32 flags;
uint32 experimental_flags;
};
7 changes: 7 additions & 0 deletions ui/accessibility/mojom/ax_mode_mojom_traits.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ bool StructTraits<ax::mojom::AXModeDataView, ui::AXMode>::Read(
}

out->flags_ = data.flags();

// This is a bit field. Check that flags fall within accepted bounds.
if (data.experimental_flags() >= ui::AXMode::kLastModeFlag * 2) {
return false;
}

out->experimental_flags_ = data.experimental_flags();
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions ui/accessibility/mojom/ax_mode_mojom_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ namespace mojo {
template <>
struct StructTraits<ax::mojom::AXModeDataView, ui::AXMode> {
static uint32_t flags(const ui::AXMode& p) { return p.flags(); }
static uint32_t experimental_flags(const ui::AXMode& p) {
return p.experimental_flags();
}

static bool Read(ax::mojom::AXModeDataView data, ui::AXMode* out);
};
Expand Down

0 comments on commit e44a1e4

Please sign in to comment.