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