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; |