1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <iostream>
6 #include <string>
7
8 #include "base/at_exit.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "build/build_config.h"
13 #include "tools/accessibility/inspect/ax_tree_server.h"
14 #include "tools/accessibility/inspect/ax_utils.h"
15
16 using ui::AXTreeSelector;
17
18 char kIdSwitch[] =
19 #if defined(WINDOWS)
20 "window";
21 #else
22 "pid";
23 #endif
24 char kFiltersSwitch[] = "filters";
25 char kJsonSwitch[] = "json";
26 char kHelpSwitch[] = "help";
27
28 // Convert from string to int, whether in 0x hex format or decimal format.
StringToInt(std::string str,unsigned * result)29 bool StringToInt(std::string str, unsigned* result) {
30 if (str.empty())
31 return false;
32 bool is_hex =
33 str.size() > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X');
34 return is_hex ? base::HexStringToUInt(str, result)
35 : base::StringToUint(str, result);
36 }
37
AXDumpTreeLogMessageHandler(int severity,const char * file,int line,size_t message_start,const std::string & str)38 bool AXDumpTreeLogMessageHandler(int severity,
39 const char* file,
40 int line,
41 size_t message_start,
42 const std::string& str) {
43 printf("%s", str.substr(message_start).c_str());
44 return true;
45 }
46
CastToAcceleratedWidget(unsigned window_id)47 gfx::AcceleratedWidget CastToAcceleratedWidget(unsigned window_id) {
48 #if defined(USE_OZONE) || defined(USE_X11) || defined(OS_MAC)
49 return static_cast<gfx::AcceleratedWidget>(window_id);
50 #else
51 return reinterpret_cast<gfx::AcceleratedWidget>(window_id);
52 #endif
53 }
54
PrintHelp()55 void PrintHelp() {
56 printf(
57 "ax_dump_tree is a tool designed to dump platform accessible trees "
58 "of running applications.\n");
59 printf("\nusage: ax_dump_tree <options>\n");
60 printf("options:\n");
61 #if defined(WINDOWS)
62 printf(" --window\tHWND of a window to dump accessible tree for\n");
63 #else
64 printf(
65 " --pid\t\tprocess id of an application to dump accessible tree for\n");
66 #endif
67 tools::PrintHelpForTreeSelectors();
68 printf(
69 " --filters\tfile containing property filters used to filter out\n"
70 " \t\taccessible tree, see example-tree-filters.txt as an example\n");
71 printf(" --json\toutputs tree in JSON format\n");
72 }
73
main(int argc,char ** argv)74 int main(int argc, char** argv) {
75 logging::SetLogMessageHandler(AXDumpTreeLogMessageHandler);
76
77 base::AtExitManager at_exit_manager;
78
79 base::CommandLine::Init(argc, argv);
80 const base::CommandLine* command_line =
81 base::CommandLine::ForCurrentProcess();
82
83 if (command_line->HasSwitch(kHelpSwitch)) {
84 PrintHelp();
85 return 0;
86 }
87
88 base::FilePath filters_path =
89 command_line->GetSwitchValuePath(kFiltersSwitch);
90
91 bool use_json = command_line->HasSwitch(kJsonSwitch);
92
93 std::string id_str = command_line->GetSwitchValueASCII(kIdSwitch);
94 if (!id_str.empty()) {
95 unsigned hwnd_or_pid;
96 if (!StringToInt(id_str, &hwnd_or_pid)) {
97 LOG(ERROR) << "* Error: Could not convert window id string to integer.";
98 return 1;
99 }
100 gfx::AcceleratedWidget widget(CastToAcceleratedWidget(hwnd_or_pid));
101
102 std::unique_ptr<content::AXTreeServer> server(
103 new content::AXTreeServer(widget, filters_path, use_json));
104 return 0;
105 }
106
107 AXTreeSelector selector = tools::TreeSelectorFromCommandLine(command_line);
108 if (!selector.empty()) {
109 std::unique_ptr<content::AXTreeServer> server(
110 new content::AXTreeServer(selector, filters_path, use_json));
111 return 0;
112 }
113
114 LOG(ERROR)
115 << "* Error: no accessible tree was identified to dump. Run with --help "
116 "for help.";
117 return 1;
118 }
119