debug_daemon_client.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string>
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind_helpers.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/location.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EmptyStopSystemTracingCallbackBody(
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::RefCountedString>& unused_result) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple class to encapsulate collecting data from a pipe into a
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string.  To use, instantiate the class, start i/o, and then delete
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the instance on callback.  The data should be retrieved before
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// delete and extracted or copied.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(sleffler) move data collection to a sub-class so this
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can be reused to process data as it is received
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PipeReader {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(void)>IOCompleteCallback;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PipeReader(IOCompleteCallback callback)
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : io_buffer_(new net::IOBufferWithSize(4096)),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback_(callback),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        weak_ptr_factory_(this) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_fd_[0] = pipe_fd_[1] = -1;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PipeReader() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't close pipe_fd_[0] as it's closed by data_stream_.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_fd_[1] != -1)
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (IGNORE_EINTR(close(pipe_fd_[1])) < 0)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PLOG(ERROR) << "close[1]";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns descriptor for the writeable side of the pipe.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetWriteFD() { return pipe_fd_[1]; }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes writeable descriptor; normally used in parent process after fork.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseWriteFD() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_fd_[1] != -1) {
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (IGNORE_EINTR(close(pipe_fd_[1])) < 0)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PLOG(ERROR) << "close";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pipe_fd_[1] = -1;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns collected data.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* data() { return &data_; }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts data collection.  Returns true if stream was setup correctly.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On success data will automatically be accumulated into a string that
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be retrieved with PipeReader::data().  To shutdown collection delete
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the instance and/or use PipeReader::OnDataReady(-1).
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool StartIO() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use a pipe to collect data
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int status = HANDLE_EINTR(pipe(pipe_fd_));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status < 0) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PLOG(ERROR) << "pipe";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFile data_file_ = pipe_fd_[0];  // read side
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_stream_.reset(new net::FileStream(data_file_,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NULL));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Post an initial async read to setup data collection
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::ERR_IO_PENDING) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unable to post initial read";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when pipe data are available.  Can also be used to shutdown
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data collection by passing -1 for |byte_count|.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDataReady(int byte_count) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "OnDataReady byte_count " << byte_count;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (byte_count <= 0) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_.Run();  // signal creator to take data and delete us
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.append(io_buffer_->data(), byte_count);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Post another read
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != net::ERR_IO_PENDING) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unable to post another read";
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(sleffler) do something more intelligent?
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<PipeReader>;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pipe_fd_[2];
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::FileStream> data_stream_;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> io_buffer_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IOCompleteCallback callback_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<PipeReader> weak_ptr_factory_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PipeReader);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DebugDaemonClient implementation used in production.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugDaemonClientImpl : public DebugDaemonClient {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DebugDaemonClientImpl() : debugdaemon_proxy_(NULL), weak_ptr_factory_(this) {}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DebugDaemonClientImpl() {}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DebugDaemonClient override.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetDebugLogs(base::PlatformFile file,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GetDebugLogsCallback& callback) OVERRIDE {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Punt descriptor validity check to a worker thread; on return we'll
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::CheckValidity,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   file_descriptor),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Owned(file_descriptor),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        false);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetDebugMode(const std::string& subsystem,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const SetDebugModeCallback& callback) OVERRIDE {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kSetDebugMode);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(subsystem);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetRoutes(bool numeric, bool ipv6,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GetRoutesCallback& callback) OVERRIDE {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetRoutes);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter sub_writer(NULL);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenArray("{sv}", &sub_writer);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter elem_writer(NULL);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("numeric");
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(numeric);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("v6");
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(ipv6);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&sub_writer);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetNetworkStatus);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetModemStatus(const GetModemStatusCallback& callback)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetModemStatus);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
23258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      OVERRIDE {
23358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
23458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                                 debugd::kGetWiMaxStatus);
23558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    debugdaemon_proxy_->CallMethod(
23658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        &method_call,
23758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
23858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        base::Bind(&DebugDaemonClientImpl::OnGetWiMaxStatus,
23958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                   weak_ptr_factory_.GetWeakPtr(),
24058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                   callback));
24158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
24258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkInterfaces(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetNetworkInterfacesCallback& callback) OVERRIDE {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetInterfaces);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetPerfData(uint32_t duration,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GetPerfDataCallback& callback) OVERRIDE {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 debugd::kGetRichPerfData);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    writer.AppendUint32(duration);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &method_call,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   callback));
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                 debugd::kGetFeedbackLogs);
273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    debugdaemon_proxy_->CallMethod(
274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        &method_call,
275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_ptr_factory_.GetWeakPtr(),
278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   callback));
279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAllLogs(const GetLogsCallback& callback)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetAllLogs);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetUserLogFiles(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetLogsCallback& callback) OVERRIDE {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetUserLogFiles);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSystemTracing() OVERRIDE {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStart);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString("all"); // TODO(sleffler) parameterize category list
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace start";
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback) OVERRIDE {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_reader_ != NULL) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Busy doing StopSystemTracing";
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_.reset(new PipeReader(
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnIOComplete,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr())));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int write_fd = -1;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pipe_reader_->StartIO()) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Cannot create pipe reader";
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // NB: continue anyway to shutdown tracing; toss trace data
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(sleffler) if this fails AppendFileDescriptor will abort
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_fd = pipe_reader_->GetWriteFD();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Punt descriptor validity check to a worker thread; on return we'll
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::CheckValidity,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   file_descriptor),
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Owned(file_descriptor),
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback),
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        false);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TestICMP(const std::string& ip_address,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const TestICMPCallback& callback) OVERRIDE {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kTestICMP);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(ip_address);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void TestICMPWithOptions(
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const std::string& ip_address,
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const std::map<std::string, std::string>& options,
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const TestICMPCallback& callback) OVERRIDE {
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 debugd::kTestICMPWithOptions);
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter writer(&method_call);
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter sub_writer(NULL);
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter elem_writer(NULL);
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Write the host.
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.AppendString(ip_address);
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Write the options.
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.OpenArray("{ss}", &sub_writer);
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::map<std::string, std::string>::const_iterator it;
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    for (it = options.begin(); it != options.end(); ++it) {
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sub_writer.OpenDictEntry(&elem_writer);
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      elem_writer.AppendString(it->first);
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      elem_writer.AppendString(it->second);
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sub_writer.CloseContainer(&elem_writer);
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.CloseContainer(&sub_writer);
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Call the function.
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    debugdaemon_proxy_->CallMethod(
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        &method_call,
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   weak_ptr_factory_.GetWeakPtr(),
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   callback));
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    debugdaemon_proxy_ =
406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bus->GetObjectProxy(debugd::kDebugdServiceName,
407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                            dbus::ObjectPath(debugd::kDebugdServicePath));
408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to check descriptor validity on a thread where i/o is permitted.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_descriptor->CheckValidity();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GetDebugLogsCallback& callback) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to get debug logs.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kGetDebugLogs);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for GetDebugLogs() is received.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetDebugLogs(const GetDebugLogsCallback& callback,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to get debug logs";
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(true);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for SetDebugMode() is received.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSetDebugMode(const SetDebugModeCallback& callback,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to change debug mode";
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetRoutes(const GetRoutesCallback& callback,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dbus::Response* response) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> routes;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader reader(response);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (reader.PopArrayOfStrings(&routes)) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(true, routes);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Got non-array response from GetRoutes";
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(false, routes);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, routes);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          dbus::Response* response) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetModemStatus(const GetModemStatusCallback& callback,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        dbus::Response* response) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  void OnGetWiMaxStatus(const GetWiMaxStatusCallback& callback,
49158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                        dbus::Response* response) {
49258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    std::string status;
49358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    if (response && dbus::MessageReader(response).PopString(&status))
49458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      callback.Run(true, status);
49558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    else
49658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      callback.Run(false, "");
49758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
49858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              dbus::Response* response) {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnGetPerfData(const GetPerfDataCallback& callback,
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     dbus::Response* response) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint8> data;
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!response) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageReader reader(response);
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const uint8* buffer = NULL;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t buf_size = 0;
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!reader.PopArrayOfBytes(&buffer, &buf_size))
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(asharif): Figure out a way to avoid this copy.
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data.insert(data.end(), buffer, buffer + buf_size);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(data);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetAllLogs(const GetLogsCallback& callback,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dbus::Response* response) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, std::string> logs;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool broken = false; // did we see a broken (k,v) pair?
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader sub_reader(NULL);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, logs);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (sub_reader.HasMoreData()) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader sub_sub_reader(NULL);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string key, value;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!sub_reader.PopDictEntry(&sub_sub_reader)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&key)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&value)) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        broken = true;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logs[key] = value;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(!sub_reader.HasMoreData() && !broken, logs);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetUserLogFiles(const GetLogsCallback& callback,
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         dbus::Response* response) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OnGetAllLogs(callback, response);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for StartSystemTracing() is received.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStartSystemTracing(dbus::Response* response) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to request systrace start";
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckValidityRequestStopSystem(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::FileDescriptor* file_descriptor,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const StopSystemTracingCallback& callback) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to stop system tracing
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStop);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace stop";
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_->CloseWriteFD();  // close our copy of fd after send
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for RequestStopSystemTracing() is received.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRequestStopSystemTracing(dbus::Response* response) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to request systrace stop";
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If debugd crashes or completes I/O before this message is processed
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // then pipe_reader_ can be NULL, see OnIOComplete().
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pipe_reader_.get())
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pipe_reader_->OnDataReady(-1); // terminate data stream
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NB: requester is signaled when i/o completes
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when pipe i/o completes; pass data on and delete the instance.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIOComplete() {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_.reset();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::ObjectProxy* debugdaemon_proxy_;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<PipeReader> pipe_reader_;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSystemTracingCallback callback_;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::DebugDaemonClient() {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::~DebugDaemonClient() {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::StopSystemTracingCallback
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::EmptyStopSystemTracingCallback() {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::Bind(&EmptyStopSystemTracingCallbackBody);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DebugDaemonClient* DebugDaemonClient::Create() {
635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new DebugDaemonClientImpl();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
639