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