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