[A11y] UKM for non-trivial canvas fallbacks
UKM approval doc:
https://docs.google.com/document/d/1DgYoGRSS--kCJyf5BsG8FzlvKInBJDT8yukrTJOq72k/edit?pli=1&tab=t.0
Bug: 371512570
Change-Id: Ia51d0754d036a3258f7fb2185a23fd98b7ce43ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5904351
Reviewed-by: Sun Yueru <yrsun@chromium.org>
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1368967}
diff --git a/third_party/blink/renderer/modules/accessibility/BUILD.gn b/third_party/blink/renderer/modules/accessibility/BUILD.gn
index 01a34ce4..2e763c7 100644
--- a/third_party/blink/renderer/modules/accessibility/BUILD.gn
+++ b/third_party/blink/renderer/modules/accessibility/BUILD.gn
@@ -50,6 +50,7 @@
deps = [
"//build:chromeos_buildflags",
+ "//services/metrics/public/cpp:ukm_builders",
"//third_party/blink/public/strings:strings_grit",
"//third_party/blink/renderer/modules/media_controls:media_controls",
"//third_party/blink/renderer/modules/permissions:permissions",
diff --git a/third_party/blink/renderer/modules/accessibility/DEPS b/third_party/blink/renderer/modules/accessibility/DEPS
index 26b977ea..39caa2e 100644
--- a/third_party/blink/renderer/modules/accessibility/DEPS
+++ b/third_party/blink/renderer/modules/accessibility/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"-third_party/blink/renderer/modules",
"+base/containers/fixed_flat_set.h",
+ "+services/metrics/public/cpp",
"+third_party/blink/renderer/modules/accessibility",
"+third_party/blink/renderer/modules/media_controls",
"+third_party/blink/renderer/modules/modules_export.h",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 93cef4d..d608057 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -37,6 +37,8 @@
#include "base/metrics/histogram_macros.h"
#include "base/ranges/algorithm.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "third_party/blink/public/mojom/render_accessibility.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -5386,6 +5388,36 @@
}
}
+void AXObjectCacheImpl::MaybeSendCanvasHasNonTrivialFallbackUKM(
+ const AXObject* ax_canvas) {
+ if (!ax_canvas->ChildCountIncludingIgnored()) {
+ // Canvas does not have fallback.
+ return;
+ }
+
+ if (ax_canvas->ChildCountIncludingIgnored() == 1 &&
+ ui::IsText(ax_canvas->FirstChildIncludingIgnored()->RoleValue())) {
+ // Ignore a fallback if it's just a single piece of text, as we are
+ // looking for advanced uses of canvas fallbacks.
+ return;
+ }
+
+ HTMLCanvasElement* canvas = To<HTMLCanvasElement>(ax_canvas->GetNode());
+ if (!canvas->HasPlacedElements()) {
+ // If it has placed elements, then the descendents are not a fallback.
+ return;
+ }
+
+ has_emitted_canvas_fallback_ukm_ = true; // Stop checking.
+
+ ukm::UkmRecorder* ukm_recorder = GetDocument().UkmRecorder();
+ DCHECK(ukm_recorder);
+ ukm::builders::Accessibility_CanvasHasNonTrivialFallback(
+ GetDocument().UkmSourceID())
+ .SetSeen(true)
+ .Record(ukm_recorder);
+}
+
void AXObjectCacheImpl::GetUpdatesAndEventsForSerialization(
std::vector<ui::AXTreeUpdate>& updates,
std::vector<ui::AXEvent>& events,
@@ -5463,6 +5495,12 @@
// node from changed_bounds_ids_ to avoid sending it in
// SerializeLocationChanges() later.
changed_bounds_ids_.erase(id);
+
+ // Record advanced uses of canvas fallbacks.
+ if (!has_emitted_canvas_fallback_ukm_ &&
+ node_data.role == ax::mojom::blink::Role::kCanvas) {
+ MaybeSendCanvasHasNonTrivialFallbackUKM(ObjectFromAXID(node_data.id));
+ }
}
DCHECK(already_serialized_ids.Contains(obj->AXObjectID()))
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 661ab77..99157b0 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -1126,6 +1126,10 @@
// `processing_deferred_events_` for more details.
void NotifyParentChildrenChanged(AXObject* parent);
+ void MaybeSendCanvasHasNonTrivialFallbackUKM(const AXObject* canvas);
+
+ void IncrementGenerationalCacheId() { ++generational_cache_id_; }
+
// Queued callbacks.
TreeUpdateCallbackQueue tree_update_callback_queue_main_;
TreeUpdateCallbackQueue tree_update_callback_queue_popup_;
@@ -1291,7 +1295,7 @@
// Whether or not the load event was sent in a previous serialization.
bool load_sent_ = false;
- void IncrementGenerationalCacheId() { ++generational_cache_id_; }
+ bool has_emitted_canvas_fallback_ukm_ = false;
// Used to determine if a previously computed attribute is from the same
// serialization update.
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 0850d4d..7fcd7591 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -260,6 +260,21 @@
</metric>
</event>
+<event name="Accessibility.CanvasHasNonTrivialFallback">
+ <owner>aleventhal@chromium.org</owner>
+ <owner>aleventhal@google.com</owner>
+ <summary>
+ Recorded once for any page that had a canvas element with non-trivial
+ fallback content beyond plain text. Only recorded if a11y is turned on (~10%
+ of users).
+ </summary>
+ <metric name="Seen" enum="Boolean">
+ <summary>
+ Only ever set to true, thus serving as a counter.
+ </summary>
+ </metric>
+</event>
+
<event name="Accessibility.ImageDescriptions">
<owner>dtseng@chromium.org</owner>
<owner>nektar@chromium.org</owner>