22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/FileUtilities.h"
35using namespace std::chrono;
41static const char *
kOKAY =
"OKAY";
42static const char *
kFAIL =
"FAIL";
43static const char *
kDATA =
"DATA";
44static const char *
kDONE =
"DONE";
45static const char *
kSEND =
"SEND";
46static const char *
kRECV =
"RECV";
47static const char *
kSTAT =
"STAT";
55 char *read_buffer =
static_cast<char *
>(buffer);
57 auto now = steady_clock::now();
59 size_t total_read_bytes = 0;
60 while (total_read_bytes < size && now < deadline) {
62 conn.
Read(read_buffer + total_read_bytes, size - total_read_bytes,
63 duration_cast<microseconds>(deadline - now), status, &
error);
66 total_read_bytes += read_bytes;
69 now = steady_clock::now();
71 if (total_read_bytes < size)
73 "Unable to read requested number of bytes. Connection status: %d.",
89 unsigned int packet_len = 0;
90 sscanf(buffer,
"%x", &packet_len);
92 message.resize(packet_len, 0);
101 if (strcmp(response_id,
kFAIL) != 0)
103 "Got unexpected response id from adb: \"%s\"", response_id);
105 std::vector<char> error_message;
107 if (!
error.Success())
110 std::string error_str(&error_message[0], error_message.size());
112 LLDB_LOGF(log,
"ADB error: %s", error_str.c_str());
119 const size_t packet_len = 4;
120 response_id[packet_len] = 0;
126 if (strncmp(response_id,
kOKAY, packet_len) != 0)
135 char length_buffer[5];
136 snprintf(length_buffer,
sizeof(length_buffer),
"%04x",
137 static_cast<int>(packet.size()));
145 conn.
Write(packet.str().c_str(), packet.size(), status, &
error);
150 std::string port =
"5037";
151 if (
const char *env_port = std::getenv(
"ANDROID_ADB_SERVER_PORT"))
153 std::string uri =
"connect://127.0.0.1:" + port;
156 LLDB_LOGF(log,
"Connecting to ADB server at %s", uri.c_str());
173 LLDB_LOG(log,
"Selecting device: {0}", device_id);
175 std::ostringstream msg;
176 msg <<
"host:transport:" << device_id.str();
186 StringRef preferred_serial;
187 if (!device_id.empty())
188 preferred_serial = device_id;
189 else if (
const char *env_serial = std::getenv(
"ANDROID_SERIAL"))
190 preferred_serial = env_serial;
192 if (preferred_serial.empty()) {
199 auto temp_conn = std::make_unique<ConnectionFileDescriptor>();
214 std::vector<char> in_buffer;
217 StringRef response(&in_buffer[0], in_buffer.size());
218 SmallVector<StringRef, 4> devices;
219 response.split(devices,
"\n", -1,
false);
221 for (
const auto &device : devices)
222 device_list.push_back(std::string(device.split(
'\t').first));
228 return error.ToError();
230 if (connected_devices.size() != 1)
232 inconvertibleErrorCode(),
233 "Expected a single connected device, got instead %zu - try "
234 "setting 'ANDROID_SERIAL'",
235 connected_devices.size());
237 std::string resolved_device_id = std::move(connected_devices.front());
239 LLDB_LOGF(log,
"AdbClient::ResolveDeviceID Resolved device ID: %s",
240 resolved_device_id.c_str());
241 return resolved_device_id;
244 std::string resolved_device_id = preferred_serial.str();
246 LLDB_LOGF(log,
"AdbClient::ResolveDeviceID Resolved device ID: %s",
247 resolved_device_id.c_str());
248 return resolved_device_id;
254 "AdbClient::AdbClient(device_id='%s') - Creating AdbClient with "
256 device_id.str().c_str());
257 m_conn = std::make_unique<ConnectionFileDescriptor>();
265 "AdbClient::AdbClient() - Creating AdbClient with default constructor");
266 m_conn = std::make_unique<ConnectionFileDescriptor>();
273 "AdbClient::~AdbClient() - Destroying AdbClient for device: %s",
280 if (
m_conn->IsConnected())
287 const uint16_t remote_port) {
289 snprintf(message,
sizeof(message),
"forward:tcp:%d;tcp:%d", local_port,
301 llvm::StringRef remote_socket_name,
304 const char *sock_namespace_str =
308 snprintf(message,
sizeof(message),
"forward:tcp:%d;%s:%s", local_port,
309 sock_namespace_str, remote_socket_name.str().c_str());
320 snprintf(message,
sizeof(message),
"killforward:tcp:%d", local_port);
330 std::ostringstream msg;
331 msg <<
"host-serial:" <<
m_device_id <<
":" << packet.str();
336 milliseconds timeout) {
337 auto start = steady_clock::now();
347 auto end = steady_clock::now();
352 size_t n =
m_conn->Read(buffer,
sizeof(buffer),
353 duration_cast<microseconds>(timeout -
elapsed),
356 message.insert(message.end(), &buffer[0], &buffer[n]);
362 std::vector<char> &output_buf) {
368 "Failed to select target device: %s",
error.AsCString());
371 adb_command.
Printf(
"shell:%s", command);
386 static const char *kShellPrefix =
"/system/bin/sh:";
387 if (output_buf.size() > strlen(kShellPrefix)) {
388 if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix)))
390 "Shell command %s failed: %s", command,
391 std::string(output_buf.begin(), output_buf.end()).c_str());
398 std::string *output) {
399 std::vector<char> output_buffer;
405 output->assign(output_buffer.begin(), output_buffer.end());
411 std::vector<char> output_buffer;
416 const auto output_filename = output_file_spec.
GetPath();
418 llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::OF_None);
421 output_filename.c_str());
423 dst.write(&output_buffer[0], output_buffer.size());
427 output_filename.c_str());
433 const auto local_file_path = local_file.
GetPath();
434 llvm::FileRemover local_file_remover(local_file_path);
437 llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::OF_None);
440 local_file_path.c_str());
442 const auto remote_file_path = remote_file.
GetPath(
false);
444 remote_file_path.c_str());
448 std::vector<char> chunk;
455 dst.write(&chunk[0], chunk.size());
460 local_file_path.c_str());
462 local_file_remover.releaseFile();
468 const auto local_file_path(local_file.
GetPath());
469 std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary);
472 local_file_path.c_str());
474 std::stringstream file_description;
476 std::string file_description_str = file_description.str();
478 file_description_str.c_str());
483 while (!src.eof() && !src.read(chunk,
kMaxPushData).bad()) {
484 size_t chunk_size = src.gcount();
498 std::string response_id;
504 if (response_id ==
kFAIL) {
505 std::string error_message(data_len, 0);
509 "Failed to read DONE error message: %s",
error.AsCString());
511 error_message.c_str());
512 }
else if (response_id !=
kOKAY)
514 response_id.c_str());
520 local_file_path.c_str());
525 uint32_t &size, uint32_t &mtime) {
526 const std::string remote_file_path(remote_file.
GetPath(
false));
528 remote_file_path.c_str());
533 static const size_t stat_len = strlen(
kSTAT);
534 static const size_t response_len = stat_len + (
sizeof(uint32_t) * 3);
536 std::vector<char> buffer(response_len);
546 const void *command = extractor.
GetData(&offset, stat_len);
549 const char *command_str =
static_cast<const char *
>(command);
550 if (strncmp(command_str,
kSTAT, stat_len))
554 mode = extractor.
GetU32(&offset);
555 size = extractor.
GetU32(&offset);
556 mtime = extractor.
GetU32(&offset);
575 uint32_t &size, uint32_t &mtime) {
576 return ExecuteCommand([
this, &remote_file, &mode, &size, &mtime]() {
577 return StatImpl(remote_file, mode, size, mtime);
587 m_conn = std::make_unique<ConnectionFileDescriptor>();
590 "AdbSyncService::AdbSyncService() - Creating AdbSyncService for "
603 "AdbSyncService::~AdbSyncService() - Destroying AdbSyncService for "
609 const uint32_t data_len,
612 encoder.
AppendData(llvm::StringRef(request_id));
614 llvm::ArrayRef<uint8_t> bytes = encoder.
GetData();
627 uint32_t &data_len) {
631 if (
error.Success()) {
632 response_id.assign(&buffer[0], 4);
635 data_len = extractor.
GetU32(&offset);
644 std::string response_id;
650 if (response_id ==
kDATA) {
651 buffer.resize(data_len, 0);
655 }
else if (response_id ==
kDONE) {
657 }
else if (response_id ==
kFAIL) {
658 std::string error_message(data_len, 0);
662 "Failed to read pull error message: %s",
error.AsCString());
664 error_message.c_str());
667 "Pull failed with unknown response: %s", response_id.c_str());
static Status ReadAllBytes(Connection &conn, void *buffer, size_t size)
static const char * kSTAT
static const size_t kSyncPacketLen
static Status SendAdbMessage(Connection &conn, llvm::StringRef packet)
static const char * kSocketNamespaceAbstract
static Status SelectTargetDevice(Connection &conn, llvm::StringRef device_id)
static Status ReadAdbMessage(Connection &conn, std::vector< char > &message)
static const char * kSocketNamespaceFileSystem
static Status GetResponseError(Connection &conn, const char *response_id)
static const char * kDATA
const seconds kReadTimeout(20)
static Status EnterSyncMode(Connection &conn)
static const char * kRECV
static const char * kSEND
static const char * kOKAY
static const char * kFAIL
static Status ConnectToAdb(Connection &conn)
static const uint32_t kDefaultMode
static const size_t kMaxPushData
static Status ReadResponseStatus(Connection &conn)
static const char * kDONE
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
static llvm::Error createStringError(const char *format, Args &&...args)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
A communication connection class.
virtual size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)=0
The read function that attempts to read from the connection.
virtual size_t Write(const void *dst, size_t dst_len, lldb::ConnectionStatus &status, Status *error_ptr)=0
The actual write function that attempts to write to the communications protocol.
virtual lldb::ConnectionStatus Connect(llvm::StringRef url, Status *error_ptr)=0
Connect using the connect string url.
An binary data encoding class.
llvm::ArrayRef< uint8_t > GetData() const
Get a access to the bytes that this references.
void AppendU32(uint32_t value)
void AppendData(llvm::StringRef data)
Append a bytes to the end of the owned data.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
static FileSystem & Instance()
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ConnectionStatus
Connection Status Types.
@ eConnectionStatusSuccess
Success.