Chromium Code Reviews| Index: chrome/test/chromedriver/chrome/adb_impl.cc |
| diff --git a/chrome/test/chromedriver/chrome/adb_impl.cc b/chrome/test/chromedriver/chrome/adb_impl.cc |
| index a60d8bce5dfaf31e0242ac49126df9da868effa1..2c7a2504ed200645674b4a58b23cd134b7aa5bfd 100644 |
| --- a/chrome/test/chromedriver/chrome/adb_impl.cc |
| +++ b/chrome/test/chromedriver/chrome/adb_impl.cc |
| @@ -226,6 +226,67 @@ Status AdbImpl::GetPidByName(const std::string& device_serial, |
| "Failed to get PID for the following process: " + process_name); |
| } |
| +Status AdbImpl::GetDevtoolsRemoteSocket(const std::string& device_serial, |
|
johnchen
2017/07/12 21:54:43
This doesn't work correctly for WebView apps. The
|
| + const std::string& process_name, |
| + std::string* device_socket) { |
| + // Parse 'cat /proc/net/unix' output which on Android looks like this: |
| + // |
| + // Num RefCount Protocol Flags Type St Inode Path |
| + // 00000000: 00000002 00000000 00010000 0001 01 331813 /dev/socket/zygote |
| + // 00000000: 00000002 00000000 00010000 0001 01 358606 @xxx_devtools_remote |
| + // 00000000: 00000002 00000000 00010000 0001 01 347300 @yyy_devtools_remote |
| + // |
| + // We need to find records with paths starting from '@' (abstract socket) |
| + // and containing the channel pattern ("_devtools_remote"). |
| + // |
| + // The code that generates this file is in the unix_seq_show() function in |
| + // net/unix/af_unix.c in the kernel source. Looking at include/net/af_unix.h |
| + // is also helpful, to see the data structures in use. |
| + // |
| + // The socket path is always the last column in the output, and |
| + // the Android Kernel source matches the stock kernel in this respect. |
| + std::string response; |
| + Status status = ExecuteHostShellCommand(device_serial, |
| + "cat /proc/net/unix", &response); |
| + std::string kDevToolsSocketSuffix = "_devtools_remote"; |
| + if (!status.IsOk()) |
| + return status; |
| + for (const base::StringPiece& line : |
| + base::SplitStringPiece(response, "\n", base::KEEP_WHITESPACE, |
| + base::SPLIT_WANT_NONEMPTY)) { |
| + std::vector<std::string> fields = |
| + base::SplitString(line, " \r", base::KEEP_WHITESPACE, |
| + base::SPLIT_WANT_NONEMPTY); |
| + if (fields.size() < 8) |
| + continue; |
| + // We are looking for sockets accepting connections and there is no TCP |
| + // connection established. Below values are defined in |
| + // the kernel for reference |
| + // fields[3] (Flags) != __SO_ACCEPTCON (include/uapi/net.h) |
| + // fields[5] (State) != TCP_ESTABLISHED (include/net/tcp_states.h) |
| + if (fields[3] != "00010000" || fields[5] != "01") |
| + continue; |
| + std::string path_field = fields[7]; |
| + if (path_field.size() < 1 || path_field[0] != '@') |
| + continue; |
| + size_t socket_name_pos = path_field.find(kDevToolsSocketSuffix); |
| + if (socket_name_pos == std::string::npos) |
| + continue; |
| + |
| + std::string socket_name = path_field.substr(1, socket_name_pos - 1); |
| + if (socket_name.compare(process_name) == 0) { |
| + *device_socket = path_field.substr(1); |
| + } |
| + } |
| + |
| + // We could not find a device socket for the expected process name |
| + if (device_socket->empty()) { |
| + return Status(kUnknownError, |
| + "Failed to find remote devtools socket for: " + process_name); |
| + } |
| + return Status(kOk); |
| +} |
| + |
| Status AdbImpl::ExecuteCommand( |
| const std::string& command, std::string* response) { |
| scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer; |