Commit 3486ac47 authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Support filters for ax_dump_tree_output

The ax_dump_tree output puts out a lot of information, which can be too
noisy to efficiently read. This supports property filtering as follows:

ax_dump_tree --filters=[FILTERS_TEXT_FILE]

The filters file can have @ALLOW, @ALLOW-EMPTY and @DENY rules, similar
to the dump accessibility tree browsertests. It is not necessary to have
a platform prefix (e.g. @WIN- or @MAC-). The role of the object cannot
be filtered, but any other properties can. If no filters are provided
then all properties are shown.

Example, to filter out everything except role, name and value, use:
@ALLOW:name=*
@ALLOW:value=*

Put each filter on a separate line. For more info on writing rules, see
https://cs.chromium.org/chromium/src/content/test/data/accessibility/readme.md

Bug: 771747
Change-Id: If15a5c6f6baf6a1827749dae16825242a0913913
Reviewed-on: https://chromium-review.googlesource.com/725879
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#510171}
parent 0491d459
...@@ -43,7 +43,6 @@ BOOL CALLBACK EnumWindowsProcPid(HWND hwnd, LPARAM lParam) { ...@@ -43,7 +43,6 @@ BOOL CALLBACK EnumWindowsProcPid(HWND hwnd, LPARAM lParam) {
HwndWithProcId* hwnd_with_proc_id = (HwndWithProcId*)lParam; HwndWithProcId* hwnd_with_proc_id = (HwndWithProcId*)lParam;
if (process_id == static_cast<DWORD>(hwnd_with_proc_id->pid)) { if (process_id == static_cast<DWORD>(hwnd_with_proc_id->pid)) {
hwnd_with_proc_id->hwnd = hwnd; hwnd_with_proc_id->hwnd = hwnd;
;
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
...@@ -54,6 +53,7 @@ HWND GetHwndForProcess(base::ProcessId pid) { ...@@ -54,6 +53,7 @@ HWND GetHwndForProcess(base::ProcessId pid) {
EnumWindows(&EnumWindowsProcPid, (LPARAM)&hwnd_with_proc_id); EnumWindows(&EnumWindowsProcPid, (LPARAM)&hwnd_with_proc_id);
return hwnd_with_proc_id.hwnd; return hwnd_with_proc_id.hwnd;
} }
} // namespace } // namespace
namespace content { namespace content {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
char kPidSwitch[] = "pid"; char kPidSwitch[] = "pid";
char kWindowSwitch[] = "window"; char kWindowSwitch[] = "window";
char kFiltersSwitch[] = "filters";
// Convert from string to int, whether in 0x hex format or decimal format. // Convert from string to int, whether in 0x hex format or decimal format.
bool StringToInt(std::string str, int* result) { bool StringToInt(std::string str, int* result) {
...@@ -26,6 +27,11 @@ int main(int argc, char** argv) { ...@@ -26,6 +27,11 @@ int main(int argc, char** argv) {
base::AtExitManager at_exit_manager; base::AtExitManager at_exit_manager;
base::CommandLine::Init(argc, argv); base::CommandLine::Init(argc, argv);
base::string16 filters_path = base::ASCIIToUTF16(
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
kFiltersSwitch));
std::string window_str = std::string window_str =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
kWindowSwitch); kWindowSwitch);
...@@ -35,7 +41,7 @@ int main(int argc, char** argv) { ...@@ -35,7 +41,7 @@ int main(int argc, char** argv) {
gfx::AcceleratedWidget widget( gfx::AcceleratedWidget widget(
reinterpret_cast<gfx::AcceleratedWidget>(window)); reinterpret_cast<gfx::AcceleratedWidget>(window));
std::unique_ptr<content::AXTreeServer> server( std::unique_ptr<content::AXTreeServer> server(
new content::AXTreeServer(widget)); new content::AXTreeServer(widget, filters_path));
return 0; return 0;
} }
} }
...@@ -46,7 +52,7 @@ int main(int argc, char** argv) { ...@@ -46,7 +52,7 @@ int main(int argc, char** argv) {
if (StringToInt(pid_str, &pid)) { if (StringToInt(pid_str, &pid)) {
base::ProcessId process_id = static_cast<base::ProcessId>(pid); base::ProcessId process_id = static_cast<base::ProcessId>(pid);
std::unique_ptr<content::AXTreeServer> server( std::unique_ptr<content::AXTreeServer> server(
new content::AXTreeServer(process_id)); new content::AXTreeServer(process_id, filters_path));
} }
} }
return 0; return 0;
......
...@@ -9,14 +9,20 @@ ...@@ -9,14 +9,20 @@
#include "base/at_exit.h" #include "base/at_exit.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
namespace content { namespace content {
AXTreeServer::AXTreeServer(base::ProcessId pid) { constexpr char kAllowOptEmptyStr[] = "@ALLOW-EMPTY:";
constexpr char kAllowOptStr[] = "@ALLOW:";
constexpr char kDenyOptStr[] = "@DENY:";
AXTreeServer::AXTreeServer(base::ProcessId pid, base::string16& filters_path) {
std::unique_ptr<AccessibilityTreeFormatter> formatter( std::unique_ptr<AccessibilityTreeFormatter> formatter(
AccessibilityTreeFormatter::Create()); AccessibilityTreeFormatter::Create());
...@@ -30,10 +36,11 @@ AXTreeServer::AXTreeServer(base::ProcessId pid) { ...@@ -30,10 +36,11 @@ AXTreeServer::AXTreeServer(base::ProcessId pid) {
return; return;
} }
Format(*formatter, *dict); Format(*formatter, *dict, filters_path);
} }
AXTreeServer::AXTreeServer(gfx::AcceleratedWidget widget) { AXTreeServer::AXTreeServer(gfx::AcceleratedWidget widget,
base::string16& filters_path) {
std::unique_ptr<AccessibilityTreeFormatter> formatter( std::unique_ptr<AccessibilityTreeFormatter> formatter(
AccessibilityTreeFormatter::Create()); AccessibilityTreeFormatter::Create());
...@@ -46,15 +53,54 @@ AXTreeServer::AXTreeServer(gfx::AcceleratedWidget widget) { ...@@ -46,15 +53,54 @@ AXTreeServer::AXTreeServer(gfx::AcceleratedWidget widget) {
return; return;
} }
Format(*formatter, *dict); Format(*formatter, *dict, filters_path);
}
std::vector<AccessibilityTreeFormatter::Filter> GetFilters(
const base::string16& filters_path) {
std::vector<AccessibilityTreeFormatter::Filter> filters;
if (!filters_path.empty()) {
std::string raw_filters_text;
base::ScopedAllowBlockingForTesting allow_io_for_test_setup;
if (base::ReadFileToString(base::FilePath(filters_path),
&raw_filters_text)) {
for (const std::string& line :
base::SplitString(raw_filters_text, "\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
if (base::StartsWith(line, kAllowOptEmptyStr,
base::CompareCase::SENSITIVE)) {
filters.push_back(AccessibilityTreeFormatter::Filter(
base::UTF8ToUTF16(line.substr(strlen(kAllowOptEmptyStr))),
AccessibilityTreeFormatter::Filter::ALLOW_EMPTY));
} else if (base::StartsWith(line, kAllowOptStr,
base::CompareCase::SENSITIVE)) {
filters.push_back(AccessibilityTreeFormatter::Filter(
base::UTF8ToUTF16(line.substr(strlen(kAllowOptStr))),
AccessibilityTreeFormatter::Filter::ALLOW));
} else if (base::StartsWith(line, kDenyOptStr,
base::CompareCase::SENSITIVE)) {
filters.push_back(AccessibilityTreeFormatter::Filter(
base::UTF8ToUTF16(line.substr(strlen(kDenyOptStr))),
AccessibilityTreeFormatter::Filter::DENY));
}
}
}
}
if (filters.empty()) {
filters = {AccessibilityTreeFormatter::Filter(
base::ASCIIToUTF16("*"), AccessibilityTreeFormatter::Filter::ALLOW)};
}
return filters;
} }
void AXTreeServer::Format(AccessibilityTreeFormatter& formatter, void AXTreeServer::Format(AccessibilityTreeFormatter& formatter,
base::DictionaryValue& dict) { base::DictionaryValue& dict,
base::string16& filters_path) {
std::vector<AccessibilityTreeFormatter::Filter> filters =
GetFilters(filters_path);
// Set filters. // Set filters.
std::vector<AccessibilityTreeFormatter::Filter> filters;
filters.push_back(AccessibilityTreeFormatter::Filter(
base::ASCIIToUTF16("*"), AccessibilityTreeFormatter::Filter::ALLOW));
formatter.SetFilters(filters); formatter.SetFilters(filters);
// Format accessibility tree as text. // Format accessibility tree as text.
......
...@@ -13,14 +13,15 @@ namespace content { ...@@ -13,14 +13,15 @@ namespace content {
class AXTreeServer { class AXTreeServer {
public: public:
explicit AXTreeServer(base::ProcessId pid); AXTreeServer(base::ProcessId pid, base::string16& filters_path);
explicit AXTreeServer(gfx::AcceleratedWidget widget); AXTreeServer(gfx::AcceleratedWidget widget, base::string16& filters_path);
private: private:
DISALLOW_COPY_AND_ASSIGN(AXTreeServer); DISALLOW_COPY_AND_ASSIGN(AXTreeServer);
void Format(AccessibilityTreeFormatter& formatter, void Format(AccessibilityTreeFormatter& formatter,
base::DictionaryValue& dict); base::DictionaryValue& dict,
base::string16& filters_path);
}; };
} // namespace content } // namespace content
......
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