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