refactor: address changes and fix errors in chrome://accessibility
(#41948)
refactor: address changes and fix errors in chrome://accessibility Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
parent
9437dd3ea8
commit
773777f209
6 changed files with 243 additions and 191 deletions
|
@ -52,7 +52,7 @@ crash_allow_setting_more_options.patch
|
|||
upload_list_add_loadsync_method.patch
|
||||
allow_setting_secondary_label_via_simplemenumodel.patch
|
||||
feat_add_streaming-protocol_registry_to_multibuffer_data_source.patch
|
||||
fix_patch_out_profile_refs_in_accessibility_ui.patch
|
||||
adjust_accessibility_ui_for_electron.patch
|
||||
skip_atk_toolchain_check.patch
|
||||
worker_feat_add_hook_to_notify_script_ready.patch
|
||||
chore_provide_iswebcontentscreationoverridden_with_full_params.patch
|
||||
|
|
|
@ -1,47 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 6 Jul 2020 13:46:06 -0700
|
||||
Subject: fix: patch out Profile refs in accessibility_ui
|
||||
Subject: Adjust accessibility_ui for Electron
|
||||
|
||||
This tweaks Chrome's Accessibility support at chrome://accessibility
|
||||
to make it usable from Electron by removing Profile references.
|
||||
to make it usable from Electron by replacing use of the Profile PrefService
|
||||
with Electron's own PrefService in ElectronBrowserContext. It also removes
|
||||
usage of BrowserList and Browser as we subclass related methods and use our
|
||||
WindowList.
|
||||
|
||||
diff --git a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
index 45b085ebb5096b2cdd083337371539a249c7a0a8..404a0a8d99eb68a35c0c06fe1b1dbfa3086e8794 100644
|
||||
index 45b085ebb5096b2cdd083337371539a249c7a0a8..9a0a6cb8b37c60641c2c51aa489fbf22cdb123cb 100644
|
||||
--- a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
+++ b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
|
||||
@@ -23,7 +23,10 @@
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
+#if 0
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
+#endif
|
||||
+#include "chrome/common/chrome_features.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
#include "chrome/grit/accessibility_resources.h"
|
||||
@@ -33,6 +36,7 @@
|
||||
#include "content/public/browser/ax_event_notification_details.h"
|
||||
#include "content/public/browser/ax_inspect_factory.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
+#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
@@ -52,9 +56,11 @@
|
||||
#include "ui/views/accessibility/view_accessibility.h"
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
+#if 0
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/browser_list.h"
|
||||
#include "chrome/browser/ui/browser_window.h"
|
||||
+#endif
|
||||
#include "ui/views/accessibility/widget_ax_tree_id_map.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
@@ -169,7 +175,7 @@ base::Value::Dict BuildTargetDescriptor(content::RenderViewHost* rvh) {
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
+#include "electron/shell/browser/electron_browser_context.h"
|
||||
#include "ui/accessibility/accessibility_features.h"
|
||||
#include "ui/accessibility/platform/ax_platform_node.h"
|
||||
#include "ui/accessibility/platform/ax_platform_node_delegate.h"
|
||||
@@ -169,7 +170,7 @@ base::Value::Dict BuildTargetDescriptor(content::RenderViewHost* rvh) {
|
||||
accessibility_mode);
|
||||
}
|
||||
|
||||
|
@ -50,27 +30,25 @@ index 45b085ebb5096b2cdd083337371539a249c7a0a8..404a0a8d99eb68a35c0c06fe1b1dbfa3
|
|||
base::Value::Dict BuildTargetDescriptor(Browser* browser) {
|
||||
base::Value::Dict target_data;
|
||||
target_data.Set(kSessionIdField, browser->session_id().id());
|
||||
@@ -203,7 +209,9 @@ void HandleAccessibilityRequestCallback(
|
||||
@@ -203,7 +204,7 @@ void HandleAccessibilityRequestCallback(
|
||||
DCHECK(ShouldHandleAccessibilityRequestCallback(path));
|
||||
|
||||
base::Value::Dict data;
|
||||
+#if 0
|
||||
PrefService* pref = Profile::FromBrowserContext(current_context)->GetPrefs();
|
||||
+#endif
|
||||
- PrefService* pref = Profile::FromBrowserContext(current_context)->GetPrefs();
|
||||
+ PrefService* pref = static_cast<electron::ElectronBrowserContext*>(current_context)->prefs();
|
||||
ui::AXMode mode =
|
||||
content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
|
||||
bool is_native_enabled = content::BrowserAccessibilityState::GetInstance()
|
||||
@@ -235,8 +243,7 @@ void HandleAccessibilityRequestCallback(
|
||||
// enabled.
|
||||
@@ -236,7 +237,7 @@ void HandleAccessibilityRequestCallback(
|
||||
data.Set(kViewsAccessibility, features::IsAccessibilityTreeForViewsEnabled());
|
||||
|
||||
- std::string pref_api_type =
|
||||
std::string pref_api_type =
|
||||
- pref->GetString(prefs::kShownAccessibilityApiType);
|
||||
+ std::string pref_api_type = "blink";
|
||||
+ std::string(pref->GetString(prefs::kShownAccessibilityApiType));
|
||||
bool pref_api_type_supported = false;
|
||||
|
||||
std::vector<ui::AXApiType::Type> supported_api_types =
|
||||
@@ -303,11 +310,11 @@ void HandleAccessibilityRequestCallback(
|
||||
@@ -303,11 +304,11 @@ void HandleAccessibilityRequestCallback(
|
||||
data.Set(kPagesField, std::move(page_list));
|
||||
|
||||
base::Value::List browser_list;
|
||||
|
@ -80,36 +58,31 @@ index 45b085ebb5096b2cdd083337371539a249c7a0a8..404a0a8d99eb68a35c0c06fe1b1dbfa3
|
|||
browser_list.Append(BuildTargetDescriptor(browser));
|
||||
}
|
||||
-#endif // !BUILDFLAG(IS_ANDROID)
|
||||
+#endif // !BUILDFLAG(IS_ANDROID)
|
||||
+#endif
|
||||
data.Set(kBrowsersField, std::move(browser_list));
|
||||
|
||||
base::Value::List widgets_list;
|
||||
@@ -647,8 +654,10 @@ void AccessibilityUIMessageHandler::SetGlobalString(
|
||||
@@ -647,7 +648,8 @@ void AccessibilityUIMessageHandler::SetGlobalString(
|
||||
const std::string value = CheckJSValue(data.FindString(kValueField));
|
||||
|
||||
if (string_name == kApiTypeField) {
|
||||
+#if 0
|
||||
PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
- PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
+ PrefService* pref = static_cast<electron::ElectronBrowserContext*>(
|
||||
+ web_ui()->GetWebContents()->GetBrowserContext())->prefs();
|
||||
pref->SetString(prefs::kShownAccessibilityApiType, value);
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,9 +709,13 @@ void AccessibilityUIMessageHandler::RequestWebContentsTree(
|
||||
@@ -700,7 +702,8 @@ void AccessibilityUIMessageHandler::RequestWebContentsTree(
|
||||
AXPropertyFilter::ALLOW_EMPTY);
|
||||
AddPropertyFilters(property_filters, deny, AXPropertyFilter::DENY);
|
||||
|
||||
+#if 0
|
||||
PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
- PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
+ PrefService* pref = static_cast<electron::ElectronBrowserContext*>(
|
||||
+ web_contents->GetBrowserContext())->prefs();
|
||||
ui::AXApiType::Type api_type =
|
||||
ui::AXApiType::From(pref->GetString(prefs::kShownAccessibilityApiType));
|
||||
+#else
|
||||
+ ui::AXApiType::Type api_type = ui::AXApiType::kBlink;
|
||||
+#endif
|
||||
std::string accessibility_contents =
|
||||
web_contents->DumpAccessibilityTree(api_type, property_filters);
|
||||
result.Set(kTreeField, accessibility_contents);
|
||||
@@ -727,6 +740,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
@@ -727,6 +730,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
AXPropertyFilter::ALLOW_EMPTY);
|
||||
AddPropertyFilters(property_filters, deny, AXPropertyFilter::DENY);
|
||||
|
||||
|
@ -117,7 +90,7 @@ index 45b085ebb5096b2cdd083337371539a249c7a0a8..404a0a8d99eb68a35c0c06fe1b1dbfa3
|
|||
for (Browser* browser : *BrowserList::GetInstance()) {
|
||||
if (browser->session_id().id() == session_id) {
|
||||
base::Value::Dict result = BuildTargetDescriptor(browser);
|
||||
@@ -739,6 +753,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
@@ -739,6 +743,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -125,25 +98,24 @@ index 45b085ebb5096b2cdd083337371539a249c7a0a8..404a0a8d99eb68a35c0c06fe1b1dbfa3
|
|||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
// No browser with the specified |session_id| was found.
|
||||
base::Value::Dict result;
|
||||
@@ -807,11 +822,15 @@ void AccessibilityUIMessageHandler::StopRecording(
|
||||
@@ -807,11 +812,13 @@ void AccessibilityUIMessageHandler::StopRecording(
|
||||
}
|
||||
|
||||
ui::AXApiType::Type AccessibilityUIMessageHandler::GetRecordingApiType() {
|
||||
+#if 0
|
||||
PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
- PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
|
||||
- const std::vector<ui::AXApiType::Type> supported_types =
|
||||
- content::AXInspectFactory::SupportedApis();
|
||||
+ PrefService* pref = static_cast<electron::ElectronBrowserContext*>(
|
||||
+ web_ui()->GetWebContents()->GetBrowserContext())->prefs();
|
||||
ui::AXApiType::Type api_type =
|
||||
ui::AXApiType::From(pref->GetString(prefs::kShownAccessibilityApiType));
|
||||
+#else
|
||||
+ ui::AXApiType::Type api_type = ui::AXApiType::kBlink;
|
||||
+#endif
|
||||
+
|
||||
+ const std::vector<ui::AXApiType::Type> supported_types =
|
||||
+ content::AXInspectFactory::SupportedApis();
|
||||
// Check to see if it is in the supported types list.
|
||||
if (std::find(supported_types.begin(), supported_types.end(), api_type) ==
|
||||
supported_types.end()) {
|
||||
@@ -881,8 +900,11 @@ void AccessibilityUIMessageHandler::RequestAccessibilityEvents(
|
||||
@@ -881,8 +888,11 @@ void AccessibilityUIMessageHandler::RequestAccessibilityEvents(
|
||||
// static
|
||||
void AccessibilityUIMessageHandler::RegisterProfilePrefs(
|
||||
user_prefs::PrefRegistrySyncable* registry) {
|
|
@ -50,6 +50,7 @@
|
|||
#include "shell/browser/protocol_registry.h"
|
||||
#include "shell/browser/special_storage_policy.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/webui/accessibility_ui.h"
|
||||
#include "shell/browser/web_contents_permission_helper.h"
|
||||
#include "shell/browser/web_view_manager.h"
|
||||
#include "shell/browser/zoom_level_delegate.h"
|
||||
|
@ -352,6 +353,7 @@ void ElectronBrowserContext::InitPrefs() {
|
|||
MediaDeviceIDSalt::RegisterPrefs(registry.get());
|
||||
ZoomLevelDelegate::RegisterPrefs(registry.get());
|
||||
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
|
||||
ElectronAccessibilityUIMessageHandler::RegisterPrefs(registry.get());
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
if (!in_memory_)
|
||||
extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "electron/shell/browser/media/media_device_id_salt.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "shell/browser/media/media_device_id_salt.h"
|
||||
#include "third_party/blink/public/common/permissions/permission_utils.h"
|
||||
|
||||
class PrefService;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
#include "chrome/grit/accessibility_resources.h" // nogncheck
|
||||
|
@ -40,11 +39,17 @@
|
|||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "ui/accessibility/accessibility_features.h"
|
||||
#include "ui/accessibility/platform/ax_platform_node.h"
|
||||
#include "ui/accessibility/platform/ax_platform_node_delegate.h"
|
||||
#include "ui/base/webui/web_ui_util.h"
|
||||
#include "ui/views/accessibility/view_accessibility.h"
|
||||
#include "ui/views/accessibility/widget_ax_tree_id_map.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -57,26 +62,34 @@ static const char kFaviconUrlField[] = "faviconUrl";
|
|||
static const char kNameField[] = "name";
|
||||
static const char kPagesField[] = "pages";
|
||||
static const char kPidField[] = "pid";
|
||||
static const char kSessionIdField[] = "sessionId";
|
||||
static const char kProcessIdField[] = "processId";
|
||||
static const char kRequestTypeField[] = "requestType";
|
||||
static const char kRoutingIdField[] = "routingId";
|
||||
static const char kSessionIdField[] = "sessionId";
|
||||
static const char kSupportedApiTypesField[] = "supportedApiTypes";
|
||||
static const char kTreeField[] = "tree";
|
||||
static const char kTypeField[] = "type";
|
||||
static const char kUrlField[] = "url";
|
||||
static const char kTreeField[] = "tree";
|
||||
static const char kWidgetsField[] = "widgets";
|
||||
static const char kApiTypeField[] = "apiType";
|
||||
|
||||
#if defined(USE_AURA)
|
||||
static const char kWidgetIdField[] = "widgetId";
|
||||
static const char kWidget[] = "widget";
|
||||
#endif
|
||||
|
||||
// Global flags
|
||||
static const char kBrowser[] = "browser";
|
||||
static const char kCopyTree[] = "copyTree";
|
||||
static const char kHTML[] = "html";
|
||||
static const char kInternal[] = "internal";
|
||||
static const char kLabelImages[] = "labelImages";
|
||||
static const char kLocked[] = "locked";
|
||||
static const char kNative[] = "native";
|
||||
static const char kPage[] = "page";
|
||||
static const char kPDF[] = "pdf";
|
||||
static const char kPDFPrinting[] = "pdfPrinting";
|
||||
static const char kScreenReader[] = "screenreader";
|
||||
static const char kShowOrRefreshTree[] = "showOrRefreshTree";
|
||||
static const char kText[] = "text";
|
||||
static const char kViewsAccessibility[] = "viewsAccessibility";
|
||||
static const char kWeb[] = "web";
|
||||
|
||||
// Possible global flag values
|
||||
|
@ -141,75 +154,23 @@ base::Value::Dict BuildTargetDescriptor(electron::NativeWindow* window) {
|
|||
return target_data;
|
||||
}
|
||||
|
||||
#if defined(USE_AURA)
|
||||
base::Value::Dict BuildTargetDescriptor(views::Widget* widget) {
|
||||
base::Value::Dict widget_data;
|
||||
widget_data.Set(kNameField, widget->widget_delegate()->GetWindowTitle());
|
||||
widget_data.Set(kTypeField, kWidget);
|
||||
|
||||
// Use the Widget's root view ViewAccessibility's unique ID for lookup.
|
||||
int id = widget->GetRootView()->GetViewAccessibility().GetUniqueId().Get();
|
||||
widget_data.Set(kWidgetIdField, id);
|
||||
return widget_data;
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
bool ShouldHandleAccessibilityRequestCallback(const std::string& path) {
|
||||
return path == kTargetsDataFile;
|
||||
}
|
||||
|
||||
// Add property filters to the property_filters vector for the given property
|
||||
// filter type. The attributes are passed in as a string with each attribute
|
||||
// separated by a space.
|
||||
void AddPropertyFilters(std::vector<ui::AXPropertyFilter>* property_filters,
|
||||
const std::string& attributes,
|
||||
ui::AXPropertyFilter::Type type) {
|
||||
for (const std::string& attribute : base::SplitString(
|
||||
attributes, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
|
||||
property_filters->emplace_back(attribute, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool MatchesPropertyFilters(
|
||||
const std::vector<ui::AXPropertyFilter>& property_filters,
|
||||
const std::string& text) {
|
||||
bool allow = false;
|
||||
for (const auto& filter : property_filters) {
|
||||
if (base::MatchPattern(text, filter.match_str)) {
|
||||
switch (filter.type) {
|
||||
case ui::AXPropertyFilter::ALLOW_EMPTY:
|
||||
case ui::AXPropertyFilter::SCRIPT:
|
||||
allow = true;
|
||||
break;
|
||||
case ui::AXPropertyFilter::ALLOW:
|
||||
allow = (!base::MatchPattern(text, "*=''"));
|
||||
break;
|
||||
case ui::AXPropertyFilter::DENY:
|
||||
allow = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
|
||||
std::string RecursiveDumpAXPlatformNodeAsString(
|
||||
const ui::AXPlatformNode* node,
|
||||
int indent,
|
||||
const std::vector<ui::AXPropertyFilter>& property_filters) {
|
||||
if (!node)
|
||||
return "";
|
||||
std::string str(2 * indent, '+');
|
||||
const std::string line = node->GetDelegate()->GetData().ToString();
|
||||
const std::vector<std::string> attributes = base::SplitString(
|
||||
line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
for (const std::string& attribute : attributes) {
|
||||
if (MatchesPropertyFilters(property_filters, attribute)) {
|
||||
str += attribute + " ";
|
||||
}
|
||||
}
|
||||
str += "\n";
|
||||
for (size_t i = 0; i < node->GetDelegate()->GetChildCount(); i++) {
|
||||
gfx::NativeViewAccessible child = node->GetDelegate()->ChildAtIndex(i);
|
||||
const ui::AXPlatformNode* child_node =
|
||||
ui::AXPlatformNode::FromNativeViewAccessible(child);
|
||||
str += RecursiveDumpAXPlatformNodeAsString(child_node, indent + 1,
|
||||
property_filters);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
bool IsValidJSValue(const std::string* str) {
|
||||
return str && str->length() < 5000U;
|
||||
}
|
||||
|
||||
void HandleAccessibilityRequestCallback(
|
||||
content::BrowserContext* current_context,
|
||||
const std::string& path,
|
||||
|
@ -217,6 +178,8 @@ void HandleAccessibilityRequestCallback(
|
|||
DCHECK(ShouldHandleAccessibilityRequestCallback(path));
|
||||
|
||||
base::Value::Dict data;
|
||||
PrefService* pref =
|
||||
static_cast<electron::ElectronBrowserContext*>(current_context)->prefs();
|
||||
ui::AXMode mode =
|
||||
content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
|
||||
bool is_native_enabled = content::BrowserAccessibilityState::GetInstance()
|
||||
|
@ -226,7 +189,7 @@ void HandleAccessibilityRequestCallback(
|
|||
bool text = mode.has_mode(ui::AXMode::kInlineTextBoxes);
|
||||
bool screenreader = mode.has_mode(ui::AXMode::kScreenReader);
|
||||
bool html = mode.has_mode(ui::AXMode::kHTML);
|
||||
bool pdf = mode.has_mode(ui::AXMode::kPDFPrinting);
|
||||
bool pdf_printing = mode.has_mode(ui::AXMode::kPDFPrinting);
|
||||
|
||||
// The "native" and "web" flags are disabled if
|
||||
// --disable-renderer-accessibility is set.
|
||||
|
@ -241,73 +204,161 @@ void HandleAccessibilityRequestCallback(
|
|||
is_web_enabled ? (screenreader ? kOn : kOff) : kDisabled);
|
||||
data.Set(kHTML, is_web_enabled ? (html ? kOn : kOff) : kDisabled);
|
||||
|
||||
// TODO(codebytere): enable use of this flag.
|
||||
//
|
||||
// The "labelImages" flag works only if "web" is enabled, the current profile
|
||||
// has the kAccessibilityImageLabelsEnabled preference set and the appropriate
|
||||
// command line switch has been used. Since this is so closely tied into user
|
||||
// prefs and causes bugs, we're disabling it for now.
|
||||
bool are_accessibility_image_labels_enabled = is_web_enabled;
|
||||
data.Set(kLabelImages, kDisabled);
|
||||
// The "pdfPrinting" flag is independent of the others.
|
||||
data.Set(kPDFPrinting, pdf_printing ? kOn : kOff);
|
||||
|
||||
// The "pdf" flag is independent of the others.
|
||||
data.Set(kPDF, pdf ? kOn : kOff);
|
||||
// The "Top Level Widgets" section is only relevant if views accessibility is
|
||||
// enabled.
|
||||
data.Set(kViewsAccessibility, features::IsAccessibilityTreeForViewsEnabled());
|
||||
|
||||
// Always dump the Accessibility tree.
|
||||
data.Set(kInternal, kOn);
|
||||
std::string pref_api_type =
|
||||
std::string(pref->GetString(prefs::kShownAccessibilityApiType));
|
||||
bool pref_api_type_supported = false;
|
||||
|
||||
base::Value::List rvh_list;
|
||||
std::unique_ptr<content::RenderWidgetHostIterator> widgets(
|
||||
std::vector<ui::AXApiType::Type> supported_api_types =
|
||||
content::AXInspectFactory::SupportedApis();
|
||||
base::Value::List supported_api_list;
|
||||
supported_api_list.reserve(supported_api_types.size());
|
||||
for (ui::AXApiType::Type type : supported_api_types) {
|
||||
supported_api_list.Append(std::string_view(type));
|
||||
if (type == ui::AXApiType::From(pref_api_type)) {
|
||||
pref_api_type_supported = true;
|
||||
}
|
||||
}
|
||||
data.Set(kSupportedApiTypesField, std::move(supported_api_list));
|
||||
|
||||
// If the saved API type is not supported, use the default platform formatter
|
||||
// API type.
|
||||
if (!pref_api_type_supported) {
|
||||
pref_api_type = std::string_view(
|
||||
content::AXInspectFactory::DefaultPlatformFormatterType());
|
||||
}
|
||||
data.Set(kApiTypeField, pref_api_type);
|
||||
|
||||
bool is_mode_locked = !content::BrowserAccessibilityState::GetInstance()
|
||||
->IsAXModeChangeAllowed();
|
||||
data.Set(kLocked, is_mode_locked ? kOn : kOff);
|
||||
|
||||
base::Value::List page_list;
|
||||
std::unique_ptr<content::RenderWidgetHostIterator> widget_iter(
|
||||
content::RenderWidgetHost::GetRenderWidgetHosts());
|
||||
|
||||
while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
|
||||
while (content::RenderWidgetHost* widget = widget_iter->GetNextHost()) {
|
||||
// Ignore processes that don't have a connection, such as crashed tabs.
|
||||
if (!widget->GetProcess()->IsInitializedAndNotDead())
|
||||
if (!widget->GetProcess()->IsInitializedAndNotDead()) {
|
||||
continue;
|
||||
}
|
||||
content::RenderViewHost* rvh = content::RenderViewHost::From(widget);
|
||||
if (!rvh)
|
||||
if (!rvh) {
|
||||
continue;
|
||||
}
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderViewHost(rvh);
|
||||
content::WebContentsDelegate* delegate = web_contents->GetDelegate();
|
||||
if (!delegate)
|
||||
if (!delegate) {
|
||||
continue;
|
||||
}
|
||||
if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost() != rvh) {
|
||||
continue;
|
||||
}
|
||||
// Ignore views that are never user-visible, like background pages.
|
||||
if (delegate->IsNeverComposited(web_contents))
|
||||
if (delegate->IsNeverComposited(web_contents)) {
|
||||
continue;
|
||||
}
|
||||
content::BrowserContext* context = rvh->GetProcess()->GetBrowserContext();
|
||||
if (context != current_context)
|
||||
if (context != current_context) {
|
||||
continue;
|
||||
}
|
||||
|
||||
base::Value::Dict descriptor = BuildTargetDescriptor(rvh);
|
||||
descriptor.Set(kNative, is_native_enabled);
|
||||
descriptor.Set(kScreenReader, is_web_enabled && screenreader);
|
||||
descriptor.Set(kWeb, is_web_enabled);
|
||||
descriptor.Set(kLabelImages, are_accessibility_image_labels_enabled);
|
||||
rvh_list.Append(std::move(descriptor));
|
||||
page_list.Append(std::move(descriptor));
|
||||
}
|
||||
|
||||
data.Set(kPagesField, std::move(rvh_list));
|
||||
data.Set(kPagesField, std::move(page_list));
|
||||
|
||||
base::Value::List window_list;
|
||||
for (auto* window : electron::WindowList::GetWindows()) {
|
||||
window_list.Append(BuildTargetDescriptor(window));
|
||||
}
|
||||
|
||||
data.Set(kBrowsersField, std::move(window_list));
|
||||
|
||||
base::Value::List widgets_list;
|
||||
#if defined(USE_AURA)
|
||||
if (features::IsAccessibilityTreeForViewsEnabled()) {
|
||||
views::WidgetAXTreeIDMap& manager_map =
|
||||
views::WidgetAXTreeIDMap::GetInstance();
|
||||
const std::vector<views::Widget*> widgets = manager_map.GetWidgets();
|
||||
for (views::Widget* widget : widgets) {
|
||||
widgets_list.Append(BuildTargetDescriptor(widget));
|
||||
}
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
data.Set(kWidgetsField, std::move(widgets_list));
|
||||
|
||||
std::move(callback).Run(base::MakeRefCounted<base::RefCountedString>(
|
||||
base::WriteJson(data).value_or("")));
|
||||
}
|
||||
|
||||
std::string RecursiveDumpAXPlatformNodeAsString(
|
||||
ui::AXPlatformNode* node,
|
||||
int indent,
|
||||
const std::vector<ui::AXPropertyFilter>& property_filters) {
|
||||
if (!node) {
|
||||
return "";
|
||||
}
|
||||
std::string str(2 * indent, '+');
|
||||
std::string line = node->GetDelegate()->GetData().ToString();
|
||||
std::vector<std::string> attributes = base::SplitString(
|
||||
line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
for (std::string attribute : attributes) {
|
||||
if (ui::AXTreeFormatter::MatchesPropertyFilters(property_filters, attribute,
|
||||
false)) {
|
||||
str += attribute + " ";
|
||||
}
|
||||
}
|
||||
str += "\n";
|
||||
for (size_t i = 0; i < node->GetDelegate()->GetChildCount(); i++) {
|
||||
gfx::NativeViewAccessible child = node->GetDelegate()->ChildAtIndex(i);
|
||||
ui::AXPlatformNode* child_node =
|
||||
ui::AXPlatformNode::FromNativeViewAccessible(child);
|
||||
str += RecursiveDumpAXPlatformNodeAsString(child_node, indent + 1,
|
||||
property_filters);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// Add property filters to the property_filters vector for the given property
|
||||
// filter type. The attributes are passed in as a string with each attribute
|
||||
// separated by a space.
|
||||
void AddPropertyFilters(std::vector<ui::AXPropertyFilter>& property_filters,
|
||||
const std::string& attributes,
|
||||
ui::AXPropertyFilter::Type type) {
|
||||
for (const std::string& attribute : base::SplitString(
|
||||
attributes, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
|
||||
property_filters.emplace_back(attribute, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidJSValue(const std::string* str) {
|
||||
return str && str->length() < 5000U;
|
||||
}
|
||||
|
||||
const std::string& CheckJSValue(const std::string* str) {
|
||||
CHECK(IsValidJSValue(str));
|
||||
return *str;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ElectronAccessibilityUI::ElectronAccessibilityUI(content::WebUI* web_ui)
|
||||
: content::WebUIController(web_ui) {
|
||||
auto* const browser_context = web_ui->GetWebContents()->GetBrowserContext();
|
||||
// Set up the chrome://accessibility source.
|
||||
content::WebUIDataSource* html_source =
|
||||
content::WebUIDataSource::CreateAndAdd(
|
||||
web_ui->GetWebContents()->GetBrowserContext(),
|
||||
chrome::kChromeUIAccessibilityHost);
|
||||
browser_context, chrome::kChromeUIAccessibilityHost);
|
||||
|
||||
// Add required resources.
|
||||
html_source->UseStringsJs();
|
||||
|
@ -317,8 +368,7 @@ ElectronAccessibilityUI::ElectronAccessibilityUI(content::WebUI* web_ui)
|
|||
html_source->SetRequestFilter(
|
||||
base::BindRepeating(&ShouldHandleAccessibilityRequestCallback),
|
||||
base::BindRepeating(&HandleAccessibilityRequestCallback,
|
||||
web_ui->GetWebContents()->GetBrowserContext()));
|
||||
|
||||
browser_context));
|
||||
html_source->OverrideContentSecurityPolicy(
|
||||
network::mojom::CSPDirectiveName::TrustedTypes,
|
||||
"trusted-types parse-html-subset sanitize-inner-html;");
|
||||
|
@ -332,33 +382,35 @@ ElectronAccessibilityUI::~ElectronAccessibilityUI() = default;
|
|||
ElectronAccessibilityUIMessageHandler::ElectronAccessibilityUIMessageHandler() =
|
||||
default;
|
||||
|
||||
void ElectronAccessibilityUIMessageHandler::GetRequestTypeAndFilters(
|
||||
const base::Value::Dict& data,
|
||||
std::string& request_type,
|
||||
std::string& allow,
|
||||
std::string& allow_empty,
|
||||
std::string& deny) {
|
||||
request_type = CheckJSValue(data.FindString(kRequestTypeField));
|
||||
CHECK(request_type == kShowOrRefreshTree || request_type == kCopyTree);
|
||||
allow = CheckJSValue(data.FindStringByDottedPath("filters.allow"));
|
||||
allow_empty = CheckJSValue(data.FindStringByDottedPath("filters.allowEmpty"));
|
||||
deny = CheckJSValue(data.FindStringByDottedPath("filters.deny"));
|
||||
}
|
||||
|
||||
void ElectronAccessibilityUIMessageHandler::RequestNativeUITree(
|
||||
const base::Value::List& args) {
|
||||
const base::Value::Dict& data = args.front().GetDict();
|
||||
|
||||
const int window_id = *data.FindInt(kSessionIdField);
|
||||
const std::string* const request_type_p = data.FindString(kRequestTypeField);
|
||||
CHECK(IsValidJSValue(request_type_p));
|
||||
std::string request_type = *request_type_p;
|
||||
CHECK(request_type == kShowOrRefreshTree || request_type == kCopyTree);
|
||||
request_type = "accessibility." + request_type;
|
||||
std::string request_type, allow, allow_empty, deny;
|
||||
GetRequestTypeAndFilters(data, request_type, allow, allow_empty, deny);
|
||||
|
||||
const std::string* const allow_p =
|
||||
data.FindStringByDottedPath("filters.allow");
|
||||
CHECK(IsValidJSValue(allow_p));
|
||||
const std::string* const allow_empty_p =
|
||||
data.FindStringByDottedPath("filters.allowEmpty");
|
||||
CHECK(IsValidJSValue(allow_empty_p));
|
||||
const std::string* const deny_p = data.FindStringByDottedPath("filters.deny");
|
||||
CHECK(IsValidJSValue(deny_p));
|
||||
int window_id = *data.FindInt(kSessionIdField);
|
||||
|
||||
AllowJavascript();
|
||||
|
||||
std::vector<ui::AXPropertyFilter> property_filters;
|
||||
AddPropertyFilters(&property_filters, *allow_p, ui::AXPropertyFilter::ALLOW);
|
||||
AddPropertyFilters(&property_filters, *allow_empty_p,
|
||||
AddPropertyFilters(property_filters, allow, ui::AXPropertyFilter::ALLOW);
|
||||
AddPropertyFilters(property_filters, allow_empty,
|
||||
ui::AXPropertyFilter::ALLOW_EMPTY);
|
||||
AddPropertyFilters(&property_filters, *deny_p, ui::AXPropertyFilter::DENY);
|
||||
AddPropertyFilters(property_filters, deny, ui::AXPropertyFilter::DENY);
|
||||
|
||||
for (auto* window : electron::WindowList::GetWindows()) {
|
||||
if (window->window_id() == window_id) {
|
||||
|
@ -366,9 +418,9 @@ void ElectronAccessibilityUIMessageHandler::RequestNativeUITree(
|
|||
gfx::NativeWindow native_window = window->GetNativeWindow();
|
||||
ui::AXPlatformNode* node =
|
||||
ui::AXPlatformNode::FromNativeWindow(native_window);
|
||||
result.Set(kTreeField, base::Value(RecursiveDumpAXPlatformNodeAsString(
|
||||
node, 0, property_filters)));
|
||||
CallJavascriptFunction(request_type, base::Value(std::move(result)));
|
||||
result.Set(kTreeField, RecursiveDumpAXPlatformNodeAsString(
|
||||
node, 0, property_filters));
|
||||
FireWebUIListener(request_type, result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +430,7 @@ void ElectronAccessibilityUIMessageHandler::RequestNativeUITree(
|
|||
result.Set(kSessionIdField, window_id);
|
||||
result.Set(kTypeField, kBrowser);
|
||||
result.Set(kErrorField, "Window no longer exists.");
|
||||
CallJavascriptFunction(request_type, base::Value(std::move(result)));
|
||||
FireWebUIListener(request_type, result);
|
||||
}
|
||||
|
||||
void ElectronAccessibilityUIMessageHandler::RegisterMessages() {
|
||||
|
@ -393,6 +445,10 @@ void ElectronAccessibilityUIMessageHandler::RegisterMessages() {
|
|||
"setGlobalFlag",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::SetGlobalFlag,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"setGlobalString",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::SetGlobalString,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestWebContentsTree",
|
||||
base::BindRepeating(
|
||||
|
@ -403,9 +459,24 @@ void ElectronAccessibilityUIMessageHandler::RegisterMessages() {
|
|||
base::BindRepeating(
|
||||
&ElectronAccessibilityUIMessageHandler::RequestNativeUITree,
|
||||
base::Unretained(this)));
|
||||
#if defined(USE_AURA)
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestWidgetsTree",
|
||||
base::BindRepeating(&AccessibilityUIMessageHandler::RequestWidgetsTree,
|
||||
base::Unretained(this)));
|
||||
#endif
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"requestAccessibilityEvents",
|
||||
base::BindRepeating(
|
||||
&AccessibilityUIMessageHandler::RequestAccessibilityEvents,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
// static
|
||||
void ElectronAccessibilityUIMessageHandler::RegisterPrefs(
|
||||
user_prefs::PrefRegistrySyncable* registry) {
|
||||
const std::string_view default_api_type =
|
||||
std::string_view(ui::AXApiType::Type(ui::AXApiType::kBlink));
|
||||
registry->RegisterStringPref(prefs::kShownAccessibilityApiType,
|
||||
std::string(default_api_type));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,14 @@ class ElectronAccessibilityUIMessageHandler
|
|||
|
||||
void RegisterMessages() final;
|
||||
|
||||
static void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry);
|
||||
|
||||
private:
|
||||
void GetRequestTypeAndFilters(const base::Value::Dict& data,
|
||||
std::string& request_type,
|
||||
std::string& allow,
|
||||
std::string& allow_empty,
|
||||
std::string& deny);
|
||||
void RequestNativeUITree(const base::Value::List& args);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue