1 //===-- AdbClient.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "AdbClient.h" 10 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/Support/FileUtilities.h" 15 16 #include "lldb/Host/ConnectionFileDescriptor.h" 17 #include "lldb/Host/FileSystem.h" 18 #include "lldb/Host/PosixApi.h" 19 #include "lldb/Utility/DataBuffer.h" 20 #include "lldb/Utility/DataBufferHeap.h" 21 #include "lldb/Utility/DataEncoder.h" 22 #include "lldb/Utility/DataExtractor.h" 23 #include "lldb/Utility/FileSpec.h" 24 #include "lldb/Utility/StreamString.h" 25 #include "lldb/Utility/Timeout.h" 26 27 #include <limits.h> 28 29 #include <algorithm> 30 #include <cstdlib> 31 #include <fstream> 32 #include <sstream> 33 34 // On Windows, transitive dependencies pull in <Windows.h>, which defines a 35 // macro that clashes with a method name. 36 #ifdef SendMessage 37 #undef SendMessage 38 #endif 39 40 using namespace lldb; 41 using namespace lldb_private; 42 using namespace lldb_private::platform_android; 43 using namespace std::chrono; 44 45 namespace { 46 47 const seconds kReadTimeout(20); 48 const char *kOKAY = "OKAY"; 49 const char *kFAIL = "FAIL"; 50 const char *kDATA = "DATA"; 51 const char *kDONE = "DONE"; 52 53 const char *kSEND = "SEND"; 54 const char *kRECV = "RECV"; 55 const char *kSTAT = "STAT"; 56 57 const size_t kSyncPacketLen = 8; 58 // Maximum size of a filesync DATA packet. 59 const size_t kMaxPushData = 2 * 1024; 60 // Default mode for pushed files. 61 const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG 62 63 const char *kSocketNamespaceAbstract = "localabstract"; 64 const char *kSocketNamespaceFileSystem = "localfilesystem"; 65 66 Status ReadAllBytes(Connection &conn, void *buffer, size_t size) { 67 68 Status error; 69 ConnectionStatus status; 70 char *read_buffer = static_cast<char *>(buffer); 71 72 auto now = steady_clock::now(); 73 const auto deadline = now + kReadTimeout; 74 size_t total_read_bytes = 0; 75 while (total_read_bytes < size && now < deadline) { 76 auto read_bytes = 77 conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, 78 duration_cast<microseconds>(deadline - now), status, &error); 79 if (error.Fail()) 80 return error; 81 total_read_bytes += read_bytes; 82 if (status != eConnectionStatusSuccess) 83 break; 84 now = steady_clock::now(); 85 } 86 if (total_read_bytes < size) 87 error = Status( 88 "Unable to read requested number of bytes. Connection status: %d.", 89 status); 90 return error; 91 } 92 93 } // namespace 94 95 Status AdbClient::CreateByDeviceID(const std::string &device_id, 96 AdbClient &adb) { 97 DeviceIDList connect_devices; 98 auto error = adb.GetDevices(connect_devices); 99 if (error.Fail()) 100 return error; 101 102 std::string android_serial; 103 if (!device_id.empty()) 104 android_serial = device_id; 105 else if (const char *env_serial = std::getenv("ANDROID_SERIAL")) 106 android_serial = env_serial; 107 108 if (android_serial.empty()) { 109 if (connect_devices.size() != 1) 110 return Status("Expected a single connected device, got instead %zu - try " 111 "setting 'ANDROID_SERIAL'", 112 connect_devices.size()); 113 adb.SetDeviceID(connect_devices.front()); 114 } else { 115 auto find_it = std::find(connect_devices.begin(), connect_devices.end(), 116 android_serial); 117 if (find_it == connect_devices.end()) 118 return Status("Device \"%s\" not found", android_serial.c_str()); 119 120 adb.SetDeviceID(*find_it); 121 } 122 return error; 123 } 124 125 AdbClient::AdbClient() {} 126 127 AdbClient::AdbClient(const std::string &device_id) : m_device_id(device_id) {} 128 129 AdbClient::~AdbClient() {} 130 131 void AdbClient::SetDeviceID(const std::string &device_id) { 132 m_device_id = device_id; 133 } 134 135 const std::string &AdbClient::GetDeviceID() const { return m_device_id; } 136 137 Status AdbClient::Connect() { 138 Status error; 139 m_conn.reset(new ConnectionFileDescriptor); 140 std::string port = "5037"; 141 if (const char *env_port = std::getenv("ANDROID_ADB_SERVER_PORT")) { 142 port = env_port; 143 } 144 std::string uri = "connect://localhost:" + port; 145 m_conn->Connect(uri.c_str(), &error); 146 147 return error; 148 } 149 150 Status AdbClient::GetDevices(DeviceIDList &device_list) { 151 device_list.clear(); 152 153 auto error = SendMessage("host:devices"); 154 if (error.Fail()) 155 return error; 156 157 error = ReadResponseStatus(); 158 if (error.Fail()) 159 return error; 160 161 std::vector<char> in_buffer; 162 error = ReadMessage(in_buffer); 163 164 llvm::StringRef response(&in_buffer[0], in_buffer.size()); 165 llvm::SmallVector<llvm::StringRef, 4> devices; 166 response.split(devices, "\n", -1, false); 167 168 for (const auto &device : devices) 169 device_list.push_back(device.split('\t').first); 170 171 // Force disconnect since ADB closes connection after host:devices response 172 // is sent. 173 m_conn.reset(); 174 return error; 175 } 176 177 Status AdbClient::SetPortForwarding(const uint16_t local_port, 178 const uint16_t remote_port) { 179 char message[48]; 180 snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port, 181 remote_port); 182 183 const auto error = SendDeviceMessage(message); 184 if (error.Fail()) 185 return error; 186 187 return ReadResponseStatus(); 188 } 189 190 Status 191 AdbClient::SetPortForwarding(const uint16_t local_port, 192 llvm::StringRef remote_socket_name, 193 const UnixSocketNamespace socket_namespace) { 194 char message[PATH_MAX]; 195 const char *sock_namespace_str = 196 (socket_namespace == UnixSocketNamespaceAbstract) 197 ? kSocketNamespaceAbstract 198 : kSocketNamespaceFileSystem; 199 snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port, 200 sock_namespace_str, remote_socket_name.str().c_str()); 201 202 const auto error = SendDeviceMessage(message); 203 if (error.Fail()) 204 return error; 205 206 return ReadResponseStatus(); 207 } 208 209 Status AdbClient::DeletePortForwarding(const uint16_t local_port) { 210 char message[32]; 211 snprintf(message, sizeof(message), "killforward:tcp:%d", local_port); 212 213 const auto error = SendDeviceMessage(message); 214 if (error.Fail()) 215 return error; 216 217 return ReadResponseStatus(); 218 } 219 220 Status AdbClient::SendMessage(const std::string &packet, const bool reconnect) { 221 Status error; 222 if (!m_conn || reconnect) { 223 error = Connect(); 224 if (error.Fail()) 225 return error; 226 } 227 228 char length_buffer[5]; 229 snprintf(length_buffer, sizeof(length_buffer), "%04x", 230 static_cast<int>(packet.size())); 231 232 ConnectionStatus status; 233 234 m_conn->Write(length_buffer, 4, status, &error); 235 if (error.Fail()) 236 return error; 237 238 m_conn->Write(packet.c_str(), packet.size(), status, &error); 239 return error; 240 } 241 242 Status AdbClient::SendDeviceMessage(const std::string &packet) { 243 std::ostringstream msg; 244 msg << "host-serial:" << m_device_id << ":" << packet; 245 return SendMessage(msg.str()); 246 } 247 248 Status AdbClient::ReadMessage(std::vector<char> &message) { 249 message.clear(); 250 251 char buffer[5]; 252 buffer[4] = 0; 253 254 auto error = ReadAllBytes(buffer, 4); 255 if (error.Fail()) 256 return error; 257 258 unsigned int packet_len = 0; 259 sscanf(buffer, "%x", &packet_len); 260 261 message.resize(packet_len, 0); 262 error = ReadAllBytes(&message[0], packet_len); 263 if (error.Fail()) 264 message.clear(); 265 266 return error; 267 } 268 269 Status AdbClient::ReadMessageStream(std::vector<char> &message, 270 milliseconds timeout) { 271 auto start = steady_clock::now(); 272 message.clear(); 273 274 Status error; 275 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; 276 char buffer[1024]; 277 while (error.Success() && status == lldb::eConnectionStatusSuccess) { 278 auto end = steady_clock::now(); 279 auto elapsed = end - start; 280 if (elapsed >= timeout) 281 return Status("Timed out"); 282 283 size_t n = m_conn->Read(buffer, sizeof(buffer), 284 duration_cast<microseconds>(timeout - elapsed), 285 status, &error); 286 if (n > 0) 287 message.insert(message.end(), &buffer[0], &buffer[n]); 288 } 289 return error; 290 } 291 292 Status AdbClient::ReadResponseStatus() { 293 char response_id[5]; 294 295 static const size_t packet_len = 4; 296 response_id[packet_len] = 0; 297 298 auto error = ReadAllBytes(response_id, packet_len); 299 if (error.Fail()) 300 return error; 301 302 if (strncmp(response_id, kOKAY, packet_len) != 0) 303 return GetResponseError(response_id); 304 305 return error; 306 } 307 308 Status AdbClient::GetResponseError(const char *response_id) { 309 if (strcmp(response_id, kFAIL) != 0) 310 return Status("Got unexpected response id from adb: \"%s\"", response_id); 311 312 std::vector<char> error_message; 313 auto error = ReadMessage(error_message); 314 if (error.Success()) 315 error.SetErrorString( 316 std::string(&error_message[0], error_message.size()).c_str()); 317 318 return error; 319 } 320 321 Status AdbClient::SwitchDeviceTransport() { 322 std::ostringstream msg; 323 msg << "host:transport:" << m_device_id; 324 325 auto error = SendMessage(msg.str()); 326 if (error.Fail()) 327 return error; 328 329 return ReadResponseStatus(); 330 } 331 332 Status AdbClient::StartSync() { 333 auto error = SwitchDeviceTransport(); 334 if (error.Fail()) 335 return Status("Failed to switch to device transport: %s", 336 error.AsCString()); 337 338 error = Sync(); 339 if (error.Fail()) 340 return Status("Sync failed: %s", error.AsCString()); 341 342 return error; 343 } 344 345 Status AdbClient::Sync() { 346 auto error = SendMessage("sync:", false); 347 if (error.Fail()) 348 return error; 349 350 return ReadResponseStatus(); 351 } 352 353 Status AdbClient::ReadAllBytes(void *buffer, size_t size) { 354 return ::ReadAllBytes(*m_conn, buffer, size); 355 } 356 357 Status AdbClient::internalShell(const char *command, milliseconds timeout, 358 std::vector<char> &output_buf) { 359 output_buf.clear(); 360 361 auto error = SwitchDeviceTransport(); 362 if (error.Fail()) 363 return Status("Failed to switch to device transport: %s", 364 error.AsCString()); 365 366 StreamString adb_command; 367 adb_command.Printf("shell:%s", command); 368 error = SendMessage(adb_command.GetString(), false); 369 if (error.Fail()) 370 return error; 371 372 error = ReadResponseStatus(); 373 if (error.Fail()) 374 return error; 375 376 error = ReadMessageStream(output_buf, timeout); 377 if (error.Fail()) 378 return error; 379 380 // ADB doesn't propagate return code of shell execution - if 381 // output starts with /system/bin/sh: most likely command failed. 382 static const char *kShellPrefix = "/system/bin/sh:"; 383 if (output_buf.size() > strlen(kShellPrefix)) { 384 if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix))) 385 return Status("Shell command %s failed: %s", command, 386 std::string(output_buf.begin(), output_buf.end()).c_str()); 387 } 388 389 return Status(); 390 } 391 392 Status AdbClient::Shell(const char *command, milliseconds timeout, 393 std::string *output) { 394 std::vector<char> output_buffer; 395 auto error = internalShell(command, timeout, output_buffer); 396 if (error.Fail()) 397 return error; 398 399 if (output) 400 output->assign(output_buffer.begin(), output_buffer.end()); 401 return error; 402 } 403 404 Status AdbClient::ShellToFile(const char *command, milliseconds timeout, 405 const FileSpec &output_file_spec) { 406 std::vector<char> output_buffer; 407 auto error = internalShell(command, timeout, output_buffer); 408 if (error.Fail()) 409 return error; 410 411 const auto output_filename = output_file_spec.GetPath(); 412 std::error_code EC; 413 llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::OF_None); 414 if (EC) 415 return Status("Unable to open local file %s", output_filename.c_str()); 416 417 dst.write(&output_buffer[0], output_buffer.size()); 418 dst.close(); 419 if (dst.has_error()) 420 return Status("Failed to write file %s", output_filename.c_str()); 421 return Status(); 422 } 423 424 std::unique_ptr<AdbClient::SyncService> 425 AdbClient::GetSyncService(Status &error) { 426 std::unique_ptr<SyncService> sync_service; 427 error = StartSync(); 428 if (error.Success()) 429 sync_service.reset(new SyncService(std::move(m_conn))); 430 431 return sync_service; 432 } 433 434 Status AdbClient::SyncService::internalPullFile(const FileSpec &remote_file, 435 const FileSpec &local_file) { 436 const auto local_file_path = local_file.GetPath(); 437 llvm::FileRemover local_file_remover(local_file_path); 438 439 std::error_code EC; 440 llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::OF_None); 441 if (EC) 442 return Status("Unable to open local file %s", local_file_path.c_str()); 443 444 const auto remote_file_path = remote_file.GetPath(false); 445 auto error = SendSyncRequest(kRECV, remote_file_path.length(), 446 remote_file_path.c_str()); 447 if (error.Fail()) 448 return error; 449 450 std::vector<char> chunk; 451 bool eof = false; 452 while (!eof) { 453 error = PullFileChunk(chunk, eof); 454 if (error.Fail()) 455 return error; 456 if (!eof) 457 dst.write(&chunk[0], chunk.size()); 458 } 459 dst.close(); 460 if (dst.has_error()) 461 return Status("Failed to write file %s", local_file_path.c_str()); 462 463 local_file_remover.releaseFile(); 464 return error; 465 } 466 467 Status AdbClient::SyncService::internalPushFile(const FileSpec &local_file, 468 const FileSpec &remote_file) { 469 const auto local_file_path(local_file.GetPath()); 470 std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary); 471 if (!src.is_open()) 472 return Status("Unable to open local file %s", local_file_path.c_str()); 473 474 std::stringstream file_description; 475 file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode; 476 std::string file_description_str = file_description.str(); 477 auto error = SendSyncRequest(kSEND, file_description_str.length(), 478 file_description_str.c_str()); 479 if (error.Fail()) 480 return error; 481 482 char chunk[kMaxPushData]; 483 while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) { 484 size_t chunk_size = src.gcount(); 485 error = SendSyncRequest(kDATA, chunk_size, chunk); 486 if (error.Fail()) 487 return Status("Failed to send file chunk: %s", error.AsCString()); 488 } 489 error = SendSyncRequest( 490 kDONE, llvm::sys::toTimeT(FileSystem::Instance().GetModificationTime(local_file)), 491 nullptr); 492 if (error.Fail()) 493 return error; 494 495 std::string response_id; 496 uint32_t data_len; 497 error = ReadSyncHeader(response_id, data_len); 498 if (error.Fail()) 499 return Status("Failed to read DONE response: %s", error.AsCString()); 500 if (response_id == kFAIL) { 501 std::string error_message(data_len, 0); 502 error = ReadAllBytes(&error_message[0], data_len); 503 if (error.Fail()) 504 return Status("Failed to read DONE error message: %s", error.AsCString()); 505 return Status("Failed to push file: %s", error_message.c_str()); 506 } else if (response_id != kOKAY) 507 return Status("Got unexpected DONE response: %s", response_id.c_str()); 508 509 // If there was an error reading the source file, finish the adb file 510 // transfer first so that adb isn't expecting any more data. 511 if (src.bad()) 512 return Status("Failed read on %s", local_file_path.c_str()); 513 return error; 514 } 515 516 Status AdbClient::SyncService::internalStat(const FileSpec &remote_file, 517 uint32_t &mode, uint32_t &size, 518 uint32_t &mtime) { 519 const std::string remote_file_path(remote_file.GetPath(false)); 520 auto error = SendSyncRequest(kSTAT, remote_file_path.length(), 521 remote_file_path.c_str()); 522 if (error.Fail()) 523 return Status("Failed to send request: %s", error.AsCString()); 524 525 static const size_t stat_len = strlen(kSTAT); 526 static const size_t response_len = stat_len + (sizeof(uint32_t) * 3); 527 528 std::vector<char> buffer(response_len); 529 error = ReadAllBytes(&buffer[0], buffer.size()); 530 if (error.Fail()) 531 return Status("Failed to read response: %s", error.AsCString()); 532 533 DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle, 534 sizeof(void *)); 535 offset_t offset = 0; 536 537 const void *command = extractor.GetData(&offset, stat_len); 538 if (!command) 539 return Status("Failed to get response command"); 540 const char *command_str = static_cast<const char *>(command); 541 if (strncmp(command_str, kSTAT, stat_len)) 542 return Status("Got invalid stat command: %s", command_str); 543 544 mode = extractor.GetU32(&offset); 545 size = extractor.GetU32(&offset); 546 mtime = extractor.GetU32(&offset); 547 return Status(); 548 } 549 550 Status AdbClient::SyncService::PullFile(const FileSpec &remote_file, 551 const FileSpec &local_file) { 552 return executeCommand([this, &remote_file, &local_file]() { 553 return internalPullFile(remote_file, local_file); 554 }); 555 } 556 557 Status AdbClient::SyncService::PushFile(const FileSpec &local_file, 558 const FileSpec &remote_file) { 559 return executeCommand([this, &local_file, &remote_file]() { 560 return internalPushFile(local_file, remote_file); 561 }); 562 } 563 564 Status AdbClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode, 565 uint32_t &size, uint32_t &mtime) { 566 return executeCommand([this, &remote_file, &mode, &size, &mtime]() { 567 return internalStat(remote_file, mode, size, mtime); 568 }); 569 } 570 571 bool AdbClient::SyncService::IsConnected() const { 572 return m_conn && m_conn->IsConnected(); 573 } 574 575 AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn) 576 : m_conn(std::move(conn)) {} 577 578 Status 579 AdbClient::SyncService::executeCommand(const std::function<Status()> &cmd) { 580 if (!m_conn) 581 return Status("SyncService is disconnected"); 582 583 const auto error = cmd(); 584 if (error.Fail()) 585 m_conn.reset(); 586 587 return error; 588 } 589 590 AdbClient::SyncService::~SyncService() {} 591 592 Status AdbClient::SyncService::SendSyncRequest(const char *request_id, 593 const uint32_t data_len, 594 const void *data) { 595 const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0)); 596 DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *)); 597 auto offset = encoder.PutData(0, request_id, strlen(request_id)); 598 encoder.PutUnsigned(offset, 4, data_len); 599 600 Status error; 601 ConnectionStatus status; 602 m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error); 603 if (error.Fail()) 604 return error; 605 606 if (data) 607 m_conn->Write(data, data_len, status, &error); 608 return error; 609 } 610 611 Status AdbClient::SyncService::ReadSyncHeader(std::string &response_id, 612 uint32_t &data_len) { 613 char buffer[kSyncPacketLen]; 614 615 auto error = ReadAllBytes(buffer, kSyncPacketLen); 616 if (error.Success()) { 617 response_id.assign(&buffer[0], 4); 618 DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *)); 619 offset_t offset = 0; 620 data_len = extractor.GetU32(&offset); 621 } 622 623 return error; 624 } 625 626 Status AdbClient::SyncService::PullFileChunk(std::vector<char> &buffer, 627 bool &eof) { 628 buffer.clear(); 629 630 std::string response_id; 631 uint32_t data_len; 632 auto error = ReadSyncHeader(response_id, data_len); 633 if (error.Fail()) 634 return error; 635 636 if (response_id == kDATA) { 637 buffer.resize(data_len, 0); 638 error = ReadAllBytes(&buffer[0], data_len); 639 if (error.Fail()) 640 buffer.clear(); 641 } else if (response_id == kDONE) { 642 eof = true; 643 } else if (response_id == kFAIL) { 644 std::string error_message(data_len, 0); 645 error = ReadAllBytes(&error_message[0], data_len); 646 if (error.Fail()) 647 return Status("Failed to read pull error message: %s", error.AsCString()); 648 return Status("Failed to pull file: %s", error_message.c_str()); 649 } else 650 return Status("Pull failed with unknown response: %s", response_id.c_str()); 651 652 return Status(); 653 } 654 655 Status AdbClient::SyncService::ReadAllBytes(void *buffer, size_t size) { 656 return ::ReadAllBytes(*m_conn, buffer, size); 657 } 658