Commit 34ca4db6 authored by Chris Hall's avatar Chris Hall Committed by Commit Bot

Language detection feature flag for experimental rollout.

bumping language detection switch expiry to m87.

AX-Relnotes: Language detection experiment.

Change-Id: I3c836fe0feca9e564afb50eeea9173096443f3de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2355655
Commit-Queue: Chris Hall <chrishall@chromium.org>
Reviewed-by: default avatarAlice Boxhall <aboxhall@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800026}
parent 7d566351
...@@ -1470,12 +1470,12 @@ ...@@ -1470,12 +1470,12 @@
{ {
"name": "enable-experimental-accessibility-language-detection", "name": "enable-experimental-accessibility-language-detection",
"owners": [ "chrishall", "//ui/accessibility/OWNERS" ], "owners": [ "chrishall", "//ui/accessibility/OWNERS" ],
"expiry_milestone": 86 "expiry_milestone": 87
}, },
{ {
"name": "enable-experimental-accessibility-language-detection-dynamic", "name": "enable-experimental-accessibility-language-detection-dynamic",
"owners": [ "chrishall", "//ui/accessibility/OWNERS" ], "owners": [ "chrishall", "//ui/accessibility/OWNERS" ],
"expiry_milestone": 86 "expiry_milestone": 87
}, },
{ {
"name": "enable-experimental-accessibility-switch-access", "name": "enable-experimental-accessibility-switch-access",
......
...@@ -37,6 +37,16 @@ bool IsAccessibilityExposeHTMLElementEnabled() { ...@@ -37,6 +37,16 @@ bool IsAccessibilityExposeHTMLElementEnabled() {
::features::kEnableAccessibilityExposeHTMLElement); ::features::kEnableAccessibilityExposeHTMLElement);
} }
// Enable language detection to determine language used in page text, exposed
// on the browser process AXTree.
const base::Feature kEnableAccessibilityLanguageDetection{
"AccessibilityLanguageDetection", base::FEATURE_DISABLED_BY_DEFAULT};
bool IsAccessibilityLanguageDetectionEnabled() {
return base::FeatureList::IsEnabled(
::features::kEnableAccessibilityLanguageDetection);
}
// Serializes accessibility information from the Views tree and deserializes it // Serializes accessibility information from the Views tree and deserializes it
// into an AXTree in the browser process. // into an AXTree in the browser process.
const base::Feature kEnableAccessibilityTreeForViews{ const base::Feature kEnableAccessibilityTreeForViews{
......
...@@ -30,6 +30,12 @@ AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityExposeHTMLElement; ...@@ -30,6 +30,12 @@ AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityExposeHTMLElement;
// browser process AXTree (as an ignored node). // browser process AXTree (as an ignored node).
AX_BASE_EXPORT bool IsAccessibilityExposeHTMLElementEnabled(); AX_BASE_EXPORT bool IsAccessibilityExposeHTMLElementEnabled();
AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityLanguageDetection;
// Return true if language detection should be used to determine the language
// of text content in page and exposed to the browser process AXTree.
AX_BASE_EXPORT bool IsAccessibilityLanguageDetectionEnabled();
// Serializes accessibility information from the Views tree and deserializes it // Serializes accessibility information from the Views tree and deserializes it
// into an AXTree in the browser process. // into an AXTree in the browser process.
AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityTreeForViews; AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityTreeForViews;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_tree.h" #include "ui/accessibility/ax_tree.h"
...@@ -208,10 +209,28 @@ AXLanguageDetectionManager::AXLanguageDetectionManager(AXTree* tree) ...@@ -208,10 +209,28 @@ AXLanguageDetectionManager::AXLanguageDetectionManager(AXTree* tree)
AXLanguageDetectionManager::~AXLanguageDetectionManager() = default; AXLanguageDetectionManager::~AXLanguageDetectionManager() = default;
bool AXLanguageDetectionManager::IsStaticLanguageDetectionEnabled() {
// Static language detection can be enabled by either:
// 1) The general language detection feature flag which gates both static and
// dynamic language detection (feature flag for experiment), or
// 2) The Static specific flag (user controlled switch).
return features::IsAccessibilityLanguageDetectionEnabled() ||
::switches::IsExperimentalAccessibilityLanguageDetectionEnabled();
}
bool AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled() {
// Dynamic language detection can be enabled by either:
// 1) The general language detection feature flag which gates both static and
// dynamic language detection (feature flag for experiment), or
// 2) The Dynamic specific flag (user controlled switch).
return features::IsAccessibilityLanguageDetectionEnabled() ||
::switches::
IsExperimentalAccessibilityLanguageDetectionDynamicEnabled();
}
void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() { void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() {
// If the dynamic feature flag is not enabled then do nothing. // Do not perform dynamic language detection unless explicitly enabled.
if (!::switches:: if (!IsDynamicLanguageDetectionEnabled()) {
IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()) {
return; return;
} }
...@@ -223,7 +242,8 @@ void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() { ...@@ -223,7 +242,8 @@ void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() {
// Detect languages for each node. // Detect languages for each node.
void AXLanguageDetectionManager::DetectLanguages() { void AXLanguageDetectionManager::DetectLanguages() {
TRACE_EVENT0("accessibility", "AXLanguageInfo::DetectLanguages"); TRACE_EVENT0("accessibility", "AXLanguageInfo::DetectLanguages");
if (!::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()) {
if (!IsStaticLanguageDetectionEnabled()) {
return; return;
} }
...@@ -308,7 +328,7 @@ void AXLanguageDetectionManager::DetectLanguagesForNode(AXNode* node) { ...@@ -308,7 +328,7 @@ void AXLanguageDetectionManager::DetectLanguagesForNode(AXNode* node) {
void AXLanguageDetectionManager::LabelLanguages() { void AXLanguageDetectionManager::LabelLanguages() {
TRACE_EVENT0("accessibility", "AXLanguageInfo::LabelLanguages"); TRACE_EVENT0("accessibility", "AXLanguageInfo::LabelLanguages");
if (!::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()) { if (!IsStaticLanguageDetectionEnabled()) {
return; return;
} }
...@@ -443,8 +463,7 @@ AXLanguageDetectionObserver::AXLanguageDetectionObserver(AXTree* tree) ...@@ -443,8 +463,7 @@ AXLanguageDetectionObserver::AXLanguageDetectionObserver(AXTree* tree)
// We expect the feature flag to have be checked before this Observer is // We expect the feature flag to have be checked before this Observer is
// constructed, this should have been checked by // constructed, this should have been checked by
// RegisterLanguageDetectionObserver. // RegisterLanguageDetectionObserver.
DCHECK( DCHECK(AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled());
::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled());
tree_->AddObserver(this); tree_->AddObserver(this);
} }
......
...@@ -281,6 +281,10 @@ class AX_EXPORT AXLanguageDetectionManager { ...@@ -281,6 +281,10 @@ class AX_EXPORT AXLanguageDetectionManager {
// Allow access from a fixture only used in testing. // Allow access from a fixture only used in testing.
friend class AXLanguageDetectionTestFixture; friend class AXLanguageDetectionTestFixture;
// Helper methods to test if language detection features are enabled.
static bool IsStaticLanguageDetectionEnabled();
static bool IsDynamicLanguageDetectionEnabled();
// Perform detection for subtree rooted at subtree_root. // Perform detection for subtree rooted at subtree_root.
void DetectLanguagesForSubtree(AXNode* subtree_root); void DetectLanguagesForSubtree(AXNode* subtree_root);
// Perform detection for node. Will not descend into children. // Perform detection for node. Will not descend into children.
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_node.h"
...@@ -56,6 +58,14 @@ class AXLanguageDetectionTestFixture : public testing::Test { ...@@ -56,6 +58,14 @@ class AXLanguageDetectionTestFixture : public testing::Test {
const AXLanguageDetectionTestFixture&) = delete; const AXLanguageDetectionTestFixture&) = delete;
protected: protected:
bool IsStaticLanguageDetectionEnabled() {
return AXLanguageDetectionManager::IsStaticLanguageDetectionEnabled();
}
bool IsDynamicLanguageDetectionEnabled() {
return AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled();
}
AXLanguageDetectionObserver* getObserver(AXTree& tree) { AXLanguageDetectionObserver* getObserver(AXTree& tree) {
return tree.language_detection_manager->language_detection_observer_.get(); return tree.language_detection_manager->language_detection_observer_.get();
} }
...@@ -138,28 +148,45 @@ class AXLanguageDetectionTestDynamicContent ...@@ -138,28 +148,45 @@ class AXLanguageDetectionTestDynamicContent
} }
}; };
TEST(AXLanguageDetectionTest, StaticContentFeatureFlag) { TEST_F(AXLanguageDetectionTestFixture, StaticContentFeatureFlag) {
// TODO(crbug/889370): Remove this test once this feature is stable // TODO(crbug/889370): Remove this test once this feature is stable
EXPECT_FALSE( EXPECT_FALSE(
::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()); ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled());
EXPECT_FALSE(IsStaticLanguageDetectionEnabled());
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalAccessibilityLanguageDetection); ::switches::kEnableExperimentalAccessibilityLanguageDetection);
EXPECT_TRUE( EXPECT_TRUE(
::switches::IsExperimentalAccessibilityLanguageDetectionEnabled()); ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled());
EXPECT_TRUE(IsStaticLanguageDetectionEnabled());
} }
TEST(AXLanguageDetectionTest, DynamicContentFeatureFlag) { TEST_F(AXLanguageDetectionTestFixture, DynamicContentFeatureFlag) {
// TODO(crbug/889370): Remove this test once this feature is stable // TODO(crbug/889370): Remove this test once this feature is stable
EXPECT_FALSE( EXPECT_FALSE(
::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()); ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled());
EXPECT_FALSE(IsDynamicLanguageDetectionEnabled());
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic); ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic);
EXPECT_TRUE( EXPECT_TRUE(
::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled()); ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled());
EXPECT_TRUE(IsDynamicLanguageDetectionEnabled());
}
TEST_F(AXLanguageDetectionTestFixture, FeatureFlag) {
// TODO(crbug/889370): Remove this test once this feature is stable
EXPECT_FALSE(IsStaticLanguageDetectionEnabled());
EXPECT_FALSE(IsDynamicLanguageDetectionEnabled());
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kEnableAccessibilityLanguageDetection}, {});
EXPECT_TRUE(IsStaticLanguageDetectionEnabled());
EXPECT_TRUE(IsDynamicLanguageDetectionEnabled());
} }
TEST(AXLanguageDetectionTest, LangAttrInheritanceFeatureFlagOff) { TEST(AXLanguageDetectionTest, LangAttrInheritanceFeatureFlagOff) {
...@@ -840,7 +867,8 @@ TEST_F(AXLanguageDetectionTestStaticContent, kLanguageUntouched) { ...@@ -840,7 +867,8 @@ TEST_F(AXLanguageDetectionTestStaticContent, kLanguageUntouched) {
} }
} }
// Test RegisterLanguageDetectionObserver correctly respects the feature flag. // Test RegisterLanguageDetectionObserver correctly respects the command line
// flags.
TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) { TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) {
// Enable only the flag controlling static language detection. // Enable only the flag controlling static language detection.
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
...@@ -871,6 +899,33 @@ TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) { ...@@ -871,6 +899,33 @@ TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) {
ASSERT_TRUE(tree.HasObserver(getObserver(tree))); ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
} }
// Test RegisterLanguageDetectionObserver correctly respects the feature flag.
TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFeatureFlag) {
// Construct empty tree and check initialisation.
AXTree tree;
ASSERT_NE(tree.language_detection_manager, nullptr);
ASSERT_EQ(getObserver(tree), nullptr);
// Try registration without enabling Dynamic feature flag, should be a no-op.
tree.language_detection_manager->RegisterLanguageDetectionObserver();
ASSERT_EQ(getObserver(tree), nullptr);
// Enable general feature flag which gates both Static and Dynamic features.
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kEnableAccessibilityLanguageDetection}, {});
// Try registration again, this should now construct and register an observer.
tree.language_detection_manager->RegisterLanguageDetectionObserver();
// Check our observer was constructed.
ASSERT_NE(getObserver(tree), nullptr);
// Check our observer was registered in our tree.
ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
}
TEST_F(AXLanguageDetectionTestDynamicContent, Basic) { TEST_F(AXLanguageDetectionTestDynamicContent, Basic) {
// Tree: // Tree:
// 1 // 1
......
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