Coverage Report

Created: 2023-09-21 18:56

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