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