Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/test/chromedriver/chrome/adb_impl.h" | 5 #include "chrome/test/chromedriver/chrome/adb_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 } else { | 219 } else { |
| 220 break; | 220 break; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 return Status(kUnknownError, | 225 return Status(kUnknownError, |
| 226 "Failed to get PID for the following process: " + process_name); | 226 "Failed to get PID for the following process: " + process_name); |
| 227 } | 227 } |
| 228 | 228 |
| 229 Status AdbImpl::GetDevtoolsRemoteSocket(const std::string& device_serial, | |
| 230 const std::string& process_name, | |
| 231 std::string* device_socket) { | |
| 232 // Parse 'cat /proc/net/unix' output which on Android looks like this: | |
| 233 // | |
| 234 // Num RefCount Protocol Flags Type St Inode Path | |
| 235 // 00000000: 00000002 00000000 00010000 0001 01 331813 /dev/socket/zygote | |
| 236 // 00000000: 00000002 00000000 00010000 0001 01 358606 @xxx_devtools_remote | |
| 237 // 00000000: 00000002 00000000 00010000 0001 01 347300 @yyy_devtools_remote | |
| 238 // | |
| 239 // We need to find records with paths starting from '@' (abstract socket) | |
| 240 // and containing the channel pattern ("_devtools_remote"). | |
| 241 // | |
| 242 // The code that generates this file is in the unix_seq_show() function in | |
| 243 // net/unix/af_unix.c in the kernel source. Looking at include/net/af_unix.h | |
| 244 // is also helpful, to see the data structures in use. | |
| 245 // | |
| 246 // The socket path is always the last column in the output, and | |
| 247 // the Android Kernel source matches the stock kernel in this respect. | |
| 248 | |
|
samuong
2016/10/20 04:40:40
nit: no need for a blank line here
| |
| 249 std::string response; | |
| 250 Status status = ExecuteHostShellCommand(device_serial, | |
| 251 "cat /proc/net/unix", &response); | |
| 252 std::string kDevToolsSocketSuffix = "_devtools_remote"; | |
| 253 if (!status.IsOk()) | |
| 254 return status; | |
| 255 for (const base::StringPiece& line : | |
| 256 base::SplitStringPiece(response, "\n", base::KEEP_WHITESPACE, | |
| 257 base::SPLIT_WANT_NONEMPTY)) { | |
| 258 std::vector<std::string> fields = | |
| 259 base::SplitString(line, " \r", base::KEEP_WHITESPACE, | |
| 260 base::SPLIT_WANT_NONEMPTY); | |
| 261 if (fields.size() < 8) | |
| 262 continue; | |
| 263 | |
|
samuong
2016/10/20 04:40:40
nit: no need for a blank line here
| |
| 264 // fields[3] (Flags) != __SO_ACCEPTCON (include/uapi/net.h) | |
| 265 // fields[5] (State) != TCP_ESTABLISHED (inlclude/net/tcp_states.h) | |
|
samuong
2016/10/20 04:40:40
Sorry, I still feel this is too cryptic to develop
| |
| 266 if (fields[3] != "00010000" || fields[5] != "01") | |
| 267 continue; | |
| 268 std::string path_field = fields[7]; | |
| 269 if (path_field.size() < 1 || path_field[0] != '@') | |
| 270 continue; | |
| 271 size_t socket_name_pos = path_field.find(kDevToolsSocketSuffix); | |
| 272 if (socket_name_pos == std::string::npos) | |
| 273 continue; | |
| 274 | |
| 275 std::string socket_name = path_field.substr(1, socket_name_pos - 1); | |
| 276 if (socket_name.compare(process_name) == 0) { | |
| 277 *device_socket = path_field.substr(1); | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 // We could not find a device socket for the expected process name | |
| 282 if (device_socket->empty()) { | |
| 283 return Status(kUnknownError, | |
| 284 "Failed to find remote devtools socket for: " + process_name); | |
| 285 } | |
| 286 return Status(kOk); | |
| 287 } | |
| 288 | |
| 229 Status AdbImpl::ExecuteCommand( | 289 Status AdbImpl::ExecuteCommand( |
| 230 const std::string& command, std::string* response) { | 290 const std::string& command, std::string* response) { |
| 231 scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer; | 291 scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer; |
| 232 VLOG(1) << "Sending adb command: " << command; | 292 VLOG(1) << "Sending adb command: " << command; |
| 233 io_task_runner_->PostTask( | 293 io_task_runner_->PostTask( |
| 234 FROM_HERE, | 294 FROM_HERE, |
| 235 base::Bind(&ExecuteCommandOnIOThread, command, response_buffer, port_)); | 295 base::Bind(&ExecuteCommandOnIOThread, command, response_buffer, port_)); |
| 236 Status status = response_buffer->GetResponse( | 296 Status status = response_buffer->GetResponse( |
| 237 response, base::TimeDelta::FromSeconds(30)); | 297 response, base::TimeDelta::FromSeconds(30)); |
| 238 if (status.IsOk()) { | 298 if (status.IsOk()) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 250 | 310 |
| 251 Status AdbImpl::ExecuteHostShellCommand( | 311 Status AdbImpl::ExecuteHostShellCommand( |
| 252 const std::string& device_serial, | 312 const std::string& device_serial, |
| 253 const std::string& shell_command, | 313 const std::string& shell_command, |
| 254 std::string* response) { | 314 std::string* response) { |
| 255 return ExecuteCommand( | 315 return ExecuteCommand( |
| 256 "host:transport:" + device_serial + "|shell:" + shell_command, | 316 "host:transport:" + device_serial + "|shell:" + shell_command, |
| 257 response); | 317 response); |
| 258 } | 318 } |
| 259 | 319 |
| OLD | NEW |