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