Update accessibility mode when image labeling pref changes

crrev.com/c/1394314 introduced a new user preference for
image labeling, and subsequent changes added UI to allow
the user to enable it. crrev.com/c/1466025 introduced an
accessibility mode for a renderer with image labeling
enabled, and a way for the renderer to annotate the
accessibility tree with image labels.

This change hooks these pieces together by setting the
image labeling accessibility mode on all relevant tab
contents when the corresponding pref is set.

Bug: 905419

Change-Id: Ifcc528fc49109d5c64684b5a60142a34fca0ddbe
Reviewed-on: https://chromium-review.googlesource.com/c/1462658
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#631805}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index b3d6339..2ce0072 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -84,8 +84,10 @@
   sources = [
     "about_flags.cc",
     "about_flags.h",
-    "accessibility/accessibility_labels_prefs.cc",
-    "accessibility/accessibility_labels_prefs.h",
+    "accessibility/accessibility_labels_service.cc",
+    "accessibility/accessibility_labels_service.h",
+    "accessibility/accessibility_labels_service_factory.cc",
+    "accessibility/accessibility_labels_service_factory.h",
     "accessibility/accessibility_permission_context.cc",
     "accessibility/accessibility_permission_context.h",
     "accessibility/accessibility_state_utils.cc",
diff --git a/chrome/browser/accessibility/accessibility_labels_prefs.cc b/chrome/browser/accessibility/accessibility_labels_prefs.cc
deleted file mode 100644
index 5cf704f..0000000
--- a/chrome/browser/accessibility/accessibility_labels_prefs.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/accessibility/accessibility_labels_prefs.h"
-
-#include "chrome/common/pref_names.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-
-namespace accessibility_prefs {
-
-void RegisterAccessibilityLabelsProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterBooleanPref(prefs::kAccessibilityImageLabelsEnabled, false);
-}
-
-}  // namespace accessibility_prefs
diff --git a/chrome/browser/accessibility/accessibility_labels_prefs.h b/chrome/browser/accessibility/accessibility_labels_prefs.h
deleted file mode 100644
index fd7471f..0000000
--- a/chrome/browser/accessibility/accessibility_labels_prefs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_PREFS_H_
-#define CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_PREFS_H_
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
-namespace accessibility_prefs {
-
-// The accessibility labels preference should be registered on a user profile.
-void RegisterAccessibilityLabelsProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry);
-
-}  // namespace accessibility_prefs
-
-#endif  // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_PREFS_H_
diff --git a/chrome/browser/accessibility/accessibility_labels_service.cc b/chrome/browser/accessibility/accessibility_labels_service.cc
new file mode 100644
index 0000000..7648199
--- /dev/null
+++ b/chrome/browser/accessibility/accessibility_labels_service.cc
@@ -0,0 +1,75 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/accessibility/accessibility_labels_service.h"
+
+#include "base/command_line.h"
+#include "build/build_config.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
+#include "chrome/common/pref_names.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_accessibility_state.h"
+#include "ui/accessibility/accessibility_switches.h"
+
+AccessibilityLabelsService::~AccessibilityLabelsService() {}
+
+// static
+void AccessibilityLabelsService::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterBooleanPref(prefs::kAccessibilityImageLabelsEnabled, false);
+}
+
+void AccessibilityLabelsService::Init() {
+  // Hidden behind a feature flag.
+  base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+  if (!cmd.HasSwitch(::switches::kEnableExperimentalAccessibilityLabels))
+    return;
+
+  pref_change_registrar_.Init(profile_->GetPrefs());
+  pref_change_registrar_.Add(
+      prefs::kAccessibilityImageLabelsEnabled,
+      base::BindRepeating(
+          &AccessibilityLabelsService::OnImageLabelsEnabledChanged,
+          weak_factory_.GetWeakPtr()));
+}
+
+AccessibilityLabelsService::AccessibilityLabelsService(Profile* profile)
+    : profile_(profile), weak_factory_(this) {}
+
+ui::AXMode AccessibilityLabelsService::GetAXMode() {
+  ui::AXMode ax_mode =
+      content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
+
+  // Hidden behind a feature flag.
+  base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+  if (cmd.HasSwitch(::switches::kEnableExperimentalAccessibilityLabels)) {
+    bool enabled = profile_->GetPrefs()->GetBoolean(
+        prefs::kAccessibilityImageLabelsEnabled);
+    ax_mode.set_mode(ui::AXMode::kLabelImages, enabled);
+  }
+
+  return ax_mode;
+}
+
+void AccessibilityLabelsService::OnImageLabelsEnabledChanged() {
+  // TODO(dmazzoni) Implement for Android, which doesn't support
+  // AllTabContentses(). crbug.com/905419
+#if !defined(OS_ANDROID)
+  bool enabled =
+      profile_->GetPrefs()->GetBoolean(prefs::kAccessibilityImageLabelsEnabled);
+
+  for (auto* web_contents : AllTabContentses()) {
+    if (web_contents->GetBrowserContext() != profile_)
+      continue;
+
+    ui::AXMode ax_mode = web_contents->GetAccessibilityMode();
+    ax_mode.set_mode(ui::AXMode::kLabelImages, enabled);
+    web_contents->SetAccessibilityMode(ax_mode);
+  }
+#endif
+}
diff --git a/chrome/browser/accessibility/accessibility_labels_service.h b/chrome/browser/accessibility/accessibility_labels_service.h
new file mode 100644
index 0000000..fe197d7
--- /dev/null
+++ b/chrome/browser/accessibility/accessibility_labels_service.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_H_
+#define CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_H_
+
+#include "base/memory/weak_ptr.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "ui/accessibility/ax_mode.h"
+
+class Profile;
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// Manages the feature that generates automatic image labels for accessibility.
+// Tracks the per-profile preference and updates the accessibility mode of
+// WebContents when it changes, provided image labeling is not disabled via
+// command-line switch.
+class AccessibilityLabelsService : public KeyedService {
+ public:
+  ~AccessibilityLabelsService() override;
+
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+  void Init();
+
+  ui::AXMode GetAXMode();
+
+ private:
+  friend class AccessibilityLabelsServiceFactory;
+
+  // Use |AccessibilityLabelsServiceFactory::GetForProfile(..)| to get
+  // an instance of this service.
+  explicit AccessibilityLabelsService(Profile* profile);
+
+  void OnImageLabelsEnabledChanged();
+
+  // Owns us via the KeyedService mechanism.
+  Profile* profile_;
+
+  PrefChangeRegistrar pref_change_registrar_;
+
+  base::WeakPtrFactory<AccessibilityLabelsService> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AccessibilityLabelsService);
+};
+
+#endif  // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_H_
diff --git a/chrome/browser/accessibility/accessibility_labels_service_browsertest.cc b/chrome/browser/accessibility/accessibility_labels_service_browsertest.cc
new file mode 100644
index 0000000..6abf7cb0
--- /dev/null
+++ b/chrome/browser/accessibility/accessibility_labels_service_browsertest.cc
@@ -0,0 +1,78 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_accessibility_state.h"
+#include "ui/accessibility/accessibility_switches.h"
+
+class AccessibilityLabelsBrowserTest : public InProcessBrowserTest {
+ public:
+  AccessibilityLabelsBrowserTest() {}
+
+  // InProcessBrowserTest overrides:
+  void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
+    command_line->AppendSwitch(
+        switches::kEnableExperimentalAccessibilityLabels);
+  }
+};
+
+// Changing the kAccessibilityImageLabelsEnabled pref should affect the
+// accessibility mode of a new WebContents for this profile.
+IN_PROC_BROWSER_TEST_F(AccessibilityLabelsBrowserTest, NewWebContents) {
+  ui::AXMode ax_mode =
+      content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
+  EXPECT_FALSE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+
+  chrome::NewTab(browser());
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_FALSE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+
+  browser()->profile()->GetPrefs()->SetBoolean(
+      prefs::kAccessibilityImageLabelsEnabled, true);
+
+  chrome::NewTab(browser());
+  web_contents = browser()->tab_strip_model()->GetActiveWebContents();
+  ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_TRUE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+
+  browser()->profile()->GetPrefs()->SetBoolean(
+      prefs::kAccessibilityImageLabelsEnabled, false);
+
+  chrome::NewTab(browser());
+  web_contents = browser()->tab_strip_model()->GetActiveWebContents();
+  ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_FALSE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+}
+
+// Changing the kAccessibilityImageLabelsEnabled pref should affect the
+// accessibility mode of existing WebContents in this profile.
+IN_PROC_BROWSER_TEST_F(AccessibilityLabelsBrowserTest, ExistingWebContents) {
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ui::AXMode ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_FALSE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+
+  browser()->profile()->GetPrefs()->SetBoolean(
+      prefs::kAccessibilityImageLabelsEnabled, true);
+
+  ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_TRUE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+
+  browser()->profile()->GetPrefs()->SetBoolean(
+      prefs::kAccessibilityImageLabelsEnabled, false);
+
+  ax_mode = web_contents->GetAccessibilityMode();
+  EXPECT_FALSE(ax_mode.has_mode(ui::AXMode::kLabelImages));
+}
diff --git a/chrome/browser/accessibility/accessibility_labels_service_factory.cc b/chrome/browser/accessibility/accessibility_labels_service_factory.cc
new file mode 100644
index 0000000..91d0e5d7
--- /dev/null
+++ b/chrome/browser/accessibility/accessibility_labels_service_factory.cc
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
+
+#include "chrome/browser/accessibility/accessibility_labels_service.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+// static
+AccessibilityLabelsService* AccessibilityLabelsServiceFactory::GetForProfile(
+    Profile* profile) {
+  return static_cast<AccessibilityLabelsService*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+AccessibilityLabelsService*
+AccessibilityLabelsServiceFactory::GetForProfileIfExists(Profile* profile) {
+  return static_cast<AccessibilityLabelsService*>(
+      GetInstance()->GetServiceForBrowserContext(profile, /*create=*/false));
+}
+
+// static
+AccessibilityLabelsServiceFactory*
+AccessibilityLabelsServiceFactory::GetInstance() {
+  return base::Singleton<AccessibilityLabelsServiceFactory>::get();
+}
+
+// static
+KeyedService* AccessibilityLabelsServiceFactory::BuildInstanceFor(
+    Profile* profile) {
+  return new AccessibilityLabelsService(profile);
+}
+
+AccessibilityLabelsServiceFactory::AccessibilityLabelsServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "AccessibilityLabelsService",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+AccessibilityLabelsServiceFactory::~AccessibilityLabelsServiceFactory() {}
+
+content::BrowserContext*
+AccessibilityLabelsServiceFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return chrome::GetBrowserContextRedirectedInIncognito(context);
+}
+
+KeyedService* AccessibilityLabelsServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* profile) const {
+  return BuildInstanceFor(static_cast<Profile*>(profile));
+}
diff --git a/chrome/browser/accessibility/accessibility_labels_service_factory.h b/chrome/browser/accessibility/accessibility_labels_service_factory.h
new file mode 100644
index 0000000..f8ac1521
--- /dev/null
+++ b/chrome/browser/accessibility/accessibility_labels_service_factory.h
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+class AccessibilityLabelsService;
+
+// Factory to get or create an instance of AccessibilityLabelsService from
+// a Profile.
+class AccessibilityLabelsServiceFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  static AccessibilityLabelsService* GetForProfile(Profile* profile);
+
+  static AccessibilityLabelsService* GetForProfileIfExists(Profile* profile);
+
+  static AccessibilityLabelsServiceFactory* GetInstance();
+
+  // Used to create instances for testing.
+  static KeyedService* BuildInstanceFor(Profile* profile);
+
+ private:
+  friend struct base::DefaultSingletonTraits<AccessibilityLabelsServiceFactory>;
+
+  AccessibilityLabelsServiceFactory();
+  ~AccessibilityLabelsServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+};
+
+#endif  // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_LABELS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 11daea22..e8be85e 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -37,6 +37,8 @@
 #include "chrome/app/chrome_content_utility_overlay_manifest.h"
 #include "chrome/app/chrome_packaged_service_manifests.h"
 #include "chrome/app/chrome_renderer_manifest.h"
+#include "chrome/browser/accessibility/accessibility_labels_service.h"
+#include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
 #include "chrome/browser/after_startup_task_utils.h"
 #include "chrome/browser/browser_about_handler.h"
 #include "chrome/browser/browser_process.h"
@@ -5556,3 +5558,9 @@
   URLBlacklistState blacklist_state = service->GetURLBlacklistState(url);
   return blacklist_state == URLBlacklistState::URL_IN_BLACKLIST;
 }
+
+ui::AXMode ChromeContentBrowserClient::GetAXModeForBrowserContext(
+    content::BrowserContext* browser_context) {
+  Profile* profile = Profile::FromBrowserContext(browser_context);
+  return AccessibilityLabelsServiceFactory::GetForProfile(profile)->GetAXMode();
+}
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 1a863bab..4f7e87d 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -564,6 +564,9 @@
   bool IsRendererDebugURLBlacklisted(const GURL& url,
                                      content::BrowserContext* context) override;
 
+  ui::AXMode GetAXModeForBrowserContext(
+      content::BrowserContext* browser_context) override;
+
   // Determines the committed previews state for the passed in params.
   static content::PreviewsState DetermineCommittedPreviewsForURL(
       const GURL& url,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index fad6a6b..c6f5e5a 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -10,7 +10,7 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "chrome/browser/about_flags.h"
-#include "chrome/browser/accessibility/accessibility_labels_prefs.h"
+#include "chrome/browser/accessibility/accessibility_labels_service.h"
 #include "chrome/browser/accessibility/accessibility_ui.h"
 #include "chrome/browser/accessibility/invert_bubble_prefs.h"
 #include "chrome/browser/browser_process_impl.h"
@@ -574,7 +574,7 @@
   TRACE_EVENT0("browser", "chrome::RegisterProfilePrefs");
   SCOPED_UMA_HISTOGRAM_TIMER("Settings.RegisterProfilePrefsTime");
   // User prefs. Please keep this list alphabetized.
-  accessibility_prefs::RegisterAccessibilityLabelsProfilePrefs(registry);
+  AccessibilityLabelsService::RegisterProfilePrefs(registry);
   AccessibilityUIMessageHandler::RegisterProfilePrefs(registry);
   autofill::prefs::RegisterProfilePrefs(registry);
   browsing_data::prefs::RegisterBrowserUserPrefs(registry);
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 5a4a96c..9ab37ce 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -30,6 +30,8 @@
 #include "base/trace_event/trace_event.h"
 #include "base/value_conversions.h"
 #include "build/build_config.h"
+#include "chrome/browser/accessibility/accessibility_labels_service.h"
+#include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/startup_task_runner_service_factory.h"
 #include "chrome/browser/browser_process.h"
@@ -1363,6 +1365,8 @@
 #if defined(OS_WIN) && BUILDFLAG(ENABLE_DICE_SUPPORT)
   signin_util::SigninWithCredentialProviderIfPossible(profile);
 #endif
+
+  AccessibilityLabelsServiceFactory::GetForProfile(profile)->Init();
 }
 
 void ProfileManager::DoFinalInitLogging(Profile* profile) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 30e9d34..5fd776c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -571,6 +571,7 @@
       "../../apps/app_restore_service_browsertest.cc",
       "../../apps/load_and_launch_browsertest.cc",
       "../app/chrome_version.rc.version",
+      "../browser/accessibility/accessibility_labels_service_browsertest.cc",
       "../browser/accessibility/browser_accessibility_state_browsertest.cc",
       "../browser/accessibility/interstitial_accessibility_browsertest.cc",
       "../browser/app_controller_mac_browsertest.mm",
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4c68f6e..613d5ff1 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -42,7 +42,6 @@
 #include "components/url_formatter/url_formatter.h"
 #include "content/browser/accessibility/accessibility_tree_formatter.h"
 #include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
-#include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/bad_message.h"
 #include "content/browser/browser_main_loop.h"
 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
@@ -589,7 +588,8 @@
       force_disable_overscroll_content_(false),
       last_dialog_suppressed_(false),
       accessibility_mode_(
-          BrowserAccessibilityStateImpl::GetInstance()->GetAccessibilityMode()),
+          GetContentClient()->browser()->GetAXModeForBrowserContext(
+              browser_context)),
       audio_stream_monitor_(this),
       bluetooth_connected_device_count_(0),
       media_device_group_id_salt_base_(
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index ff27bb1..2fff2ecd 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -13,6 +13,7 @@
 #include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "content/public/browser/authenticator_request_client_delegate.h"
+#include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/login_delegate.h"
 #include "content/public/browser/navigation_ui_data.h"
@@ -945,4 +946,9 @@
   return false;
 }
 
+ui::AXMode ContentBrowserClient::GetAXModeForBrowserContext(
+    BrowserContext* browser_context) {
+  return BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
+}
+
 }  // namespace content
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 1b49a64..a013031 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -56,6 +56,7 @@
 #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom-forward.h"
 #include "third_party/blink/public/platform/web_feature.mojom-forward.h"
 #include "third_party/blink/public/web/window_features.mojom-forward.h"
+#include "ui/accessibility/ax_mode.h"
 #include "ui/base/page_transition_types.h"
 #include "ui/base/window_open_disposition.h"
 
@@ -1476,6 +1477,10 @@
   // blacklist policies are applied there.
   virtual bool IsRendererDebugURLBlacklisted(const GURL& url,
                                              BrowserContext* context);
+
+  // Returns the default accessibility mode for the given browser context.
+  virtual ui::AXMode GetAXModeForBrowserContext(
+      BrowserContext* browser_context);
 };
 
 }  // namespace content