debug_daemon_client.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EmptyStopSystemTracingCallbackBody(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::RefCountedString>& unused_result) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple class to encapsulate collecting data from a pipe into a
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string.  To use, instantiate the class, start i/o, and then delete
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the instance on callback.  The data should be retrieved before
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// delete and extracted or copied.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(sleffler) move data collection to a sub-class so this
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can be reused to process data as it is received
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PipeReader {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(void)>IOCompleteCallback;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PipeReader(IOCompleteCallback callback)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : io_buffer_(new net::IOBufferWithSize(4096)),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        weak_ptr_factory_(this) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_fd_[0] = pipe_fd_[1] = -1;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PipeReader() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't close pipe_fd_[0] as it's closed by data_stream_.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_fd_[1] != -1)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (HANDLE_EINTR(close(pipe_fd_[1])) < 0)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PLOG(ERROR) << "close[1]";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns descriptor for the writeable side of the pipe.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetWriteFD() { return pipe_fd_[1]; }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes writeable descriptor; normally used in parent process after fork.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseWriteFD() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_fd_[1] != -1) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (HANDLE_EINTR(close(pipe_fd_[1])) < 0)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PLOG(ERROR) << "close";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pipe_fd_[1] = -1;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns collected data.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* data() { return &data_; }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts data collection.  Returns true if stream was setup correctly.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On success data will automatically be accumulated into a string that
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be retrieved with PipeReader::data().  To shutdown collection delete
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the instance and/or use PipeReader::OnDataReady(-1).
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool StartIO() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use a pipe to collect data
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int status = HANDLE_EINTR(pipe(pipe_fd_));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status < 0) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PLOG(ERROR) << "pipe";
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFile data_file_ = pipe_fd_[0];  // read side
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_stream_.reset(new net::FileStream(data_file_,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NULL));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Post an initial async read to setup data collection
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::ERR_IO_PENDING) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unable to post initial read";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when pipe data are available.  Can also be used to shutdown
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data collection by passing -1 for |byte_count|.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDataReady(int byte_count) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "OnDataReady byte_count " << byte_count;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (byte_count <= 0) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_.Run();  // signal creator to take data and delete us
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.append(io_buffer_->data(), byte_count);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Post another read
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::ERR_IO_PENDING) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unable to post another read";
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(sleffler) do something more intelligent?
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<PipeReader>;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pipe_fd_[2];
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::FileStream> data_stream_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> io_buffer_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IOCompleteCallback callback_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<PipeReader> weak_ptr_factory_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PipeReader);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DebugDaemonClient implementation used in production.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugDaemonClientImpl : public DebugDaemonClient {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit DebugDaemonClientImpl(dbus::Bus* bus)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : debugdaemon_proxy_(NULL),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        weak_ptr_factory_(this) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_ = bus->GetObjectProxy(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdServiceName,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectPath(debugd::kDebugdServicePath));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DebugDaemonClientImpl() {}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DebugDaemonClient override.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetDebugLogs(base::PlatformFile file,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GetDebugLogsCallback& callback) OVERRIDE {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Punt descriptor validity check to a worker thread; on return we'll
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::CheckValidity,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   file_descriptor),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Owned(file_descriptor),
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback),
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        false);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetDebugMode(const std::string& subsystem,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const SetDebugModeCallback& callback) OVERRIDE {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kSetDebugMode);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(subsystem);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetRoutes(bool numeric, bool ipv6,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GetRoutesCallback& callback) OVERRIDE {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetRoutes);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter sub_writer(NULL);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenArray("{sv}", &sub_writer);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter elem_writer(NULL);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("numeric");
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(numeric);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("v6");
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(ipv6);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&sub_writer);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetNetworkStatus);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetModemStatus(const GetModemStatusCallback& callback)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetModemStatus);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkInterfaces(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetNetworkInterfacesCallback& callback) OVERRIDE {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetInterfaces);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetPerfData(uint32_t duration,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GetPerfDataCallback& callback) OVERRIDE {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 debugd::kGetPerfData);
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    writer.AppendUint32(duration);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &method_call,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   callback));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAllLogs(const GetLogsCallback& callback)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetAllLogs);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetUserLogFiles(
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetLogsCallback& callback) OVERRIDE {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetUserLogFiles);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSystemTracing() OVERRIDE {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStart);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString("all"); // TODO(sleffler) parameterize category list
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace start";
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback) OVERRIDE {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_reader_ != NULL) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Busy doing StopSystemTracing";
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_.reset(new PipeReader(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnIOComplete,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr())));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int write_fd = -1;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pipe_reader_->StartIO()) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Cannot create pipe reader";
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // NB: continue anyway to shutdown tracing; toss trace data
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(sleffler) if this fails AppendFileDescriptor will abort
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_fd = pipe_reader_->GetWriteFD();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Punt descriptor validity check to a worker thread; on return we'll
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::CheckValidity,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   file_descriptor),
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Owned(file_descriptor),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback),
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        false);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TestICMP(const std::string& ip_address,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const TestICMPCallback& callback) OVERRIDE {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kTestICMP);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(ip_address);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to check descriptor validity on a thread where i/o is permitted.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_descriptor->CheckValidity();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GetDebugLogsCallback& callback) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to get debug logs.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kGetDebugLogs);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for GetDebugLogs() is received.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetDebugLogs(const GetDebugLogsCallback& callback,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to get debug logs";
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(true);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for SetDebugMode() is received.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSetDebugMode(const SetDebugModeCallback& callback,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to change debug mode";
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetRoutes(const GetRoutesCallback& callback,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dbus::Response* response) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> routes;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader reader(response);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (reader.PopArrayOfStrings(&routes)) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(true, routes);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Got non-array response from GetRoutes";
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(false, routes);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, routes);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          dbus::Response* response) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetModemStatus(const GetModemStatusCallback& callback,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        dbus::Response* response) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              dbus::Response* response) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnGetPerfData(const GetPerfDataCallback& callback,
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     dbus::Response* response) {
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint8> data;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!response) {
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageReader reader(response);
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8* buffer = NULL;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t buf_size = 0;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!reader.PopArrayOfBytes(reinterpret_cast<uint8**>(
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &buffer), &buf_size)) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(asharif): Figure out a way to avoid this copy.
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data.insert(data.end(), buffer, buffer + buf_size);
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(data);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetAllLogs(const GetLogsCallback& callback,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dbus::Response* response) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, std::string> logs;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool broken = false; // did we see a broken (k,v) pair?
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader sub_reader(NULL);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, logs);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (sub_reader.HasMoreData()) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader sub_sub_reader(NULL);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string key, value;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!sub_reader.PopDictEntry(&sub_sub_reader)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&key)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&value)) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        broken = true;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logs[key] = value;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(!sub_reader.HasMoreData() && !broken, logs);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetUserLogFiles(const GetLogsCallback& callback,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         dbus::Response* response) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OnGetAllLogs(callback, response);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for StartSystemTracing() is received.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStartSystemTracing(dbus::Response* response) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to request systrace start";
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckValidityRequestStopSystem(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::FileDescriptor* file_descriptor,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const StopSystemTracingCallback& callback) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to stop system tracing
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStop);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace stop";
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_->CloseWriteFD();  // close our copy of fd after send
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for RequestStopSystemTracing() is received.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRequestStopSystemTracing(dbus::Response* response) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to request systrace stop";
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If debugd crashes or completes I/O before this message is processed
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // then pipe_reader_ can be NULL, see OnIOComplete().
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pipe_reader_.get())
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pipe_reader_->OnDataReady(-1); // terminate data stream
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NB: requester is signaled when i/o completes
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when pipe i/o completes; pass data on and delete the instance.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIOComplete() {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_.reset();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::ObjectProxy* debugdaemon_proxy_;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<PipeReader> pipe_reader_;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSystemTracingCallback callback_;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DebugDaemonClient implementation used on Linux desktop,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which does nothing.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugDaemonClientStubImpl : public DebugDaemonClient {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DebugDaemonClient overrides.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetDebugLogs(base::PlatformFile file,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GetDebugLogsCallback& callback) OVERRIDE {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(false);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetDebugMode(const std::string& subsystem,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const SetDebugModeCallback& callback) OVERRIDE {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(false);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSystemTracing() OVERRIDE {}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback) OVERRIDE {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string no_data;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(base::RefCountedString::TakeString(&no_data));
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetRoutes(bool numeric, bool ipv6,
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GetRoutesCallback& callback) OVERRIDE {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> empty;
575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, empty));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, ""));
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetModemStatus(const GetModemStatusCallback& callback)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, ""));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkInterfaces(
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetNetworkInterfacesCallback& callback) OVERRIDE {
590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, ""));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetPerfData(uint32_t duration,
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GetPerfDataCallback& callback) OVERRIDE {
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint8> data;
596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           base::Bind(callback, data));
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAllLogs(const GetLogsCallback& callback) OVERRIDE {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, std::string> empty;
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, empty));
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetUserLogFiles(const GetLogsCallback& callback) OVERRIDE {
605b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    std::map<std::string, std::string> user_logs;
606b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    user_logs["preferences"] = "Preferences";
607b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    user_logs["invalid_file"] = "Invalid File";
608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
609b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     base::Bind(callback, true, user_logs));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TestICMP(const std::string& ip_address,
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const TestICMPCallback& callback) OVERRIDE {
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::Bind(callback, false, ""));
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::DebugDaemonClient() {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::~DebugDaemonClient() {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::StopSystemTracingCallback
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::EmptyStopSystemTracingCallback() {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::Bind(&EmptyStopSystemTracingCallbackBody);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient* DebugDaemonClient::Create(DBusClientImplementationType type,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   dbus::Bus* bus) {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new DebugDaemonClientImpl(bus);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new DebugDaemonClientStubImpl();
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
641