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"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file_path.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/location.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/task_runner_util.h"
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chromeos/dbus/pipe_reader.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EmptyStopSystemTracingCallbackBody(
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::RefCountedString>& unused_result) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DebugDaemonClient implementation used in production.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugDaemonClientImpl : public DebugDaemonClient {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DebugDaemonClientImpl() : debugdaemon_proxy_(NULL), weak_ptr_factory_(this) {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DebugDaemonClientImpl() {}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DebugDaemonClient override.
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void DumpDebugLogs(bool is_compressed,
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             base::File file,
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             scoped_refptr<base::TaskRunner> task_runner,
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             const GetDebugLogsCallback& callback) OVERRIDE {
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor;
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_descriptor->PutValue(file.TakePlatformFile());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Punt descriptor validity check to a worker thread; on return we'll
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    task_runner->PostTaskAndReply(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        base::Bind(&dbus::FileDescriptor::CheckValidity,
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                   base::Unretained(file_descriptor)),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   is_compressed,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Owned(file_descriptor),
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   callback));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetDebugMode(const std::string& subsystem,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const SetDebugModeCallback& callback) OVERRIDE {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kSetDebugMode);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(subsystem);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetRoutes(bool numeric, bool ipv6,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const GetRoutesCallback& callback) OVERRIDE {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetRoutes);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter sub_writer(NULL);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.OpenArray("{sv}", &sub_writer);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter elem_writer(NULL);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("numeric");
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(numeric);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.OpenDictEntry(&elem_writer);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendString("v6");
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elem_writer.AppendVariantOfBool(ipv6);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_writer.CloseContainer(&elem_writer);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.CloseContainer(&sub_writer);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetNetworkStatus);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetModemStatus(const GetModemStatusCallback& callback)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetModemStatus);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
13158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      OVERRIDE {
13258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
13358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                                 debugd::kGetWiMaxStatus);
13458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    debugdaemon_proxy_->CallMethod(
13558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        &method_call,
13658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
13758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        base::Bind(&DebugDaemonClientImpl::OnGetWiMaxStatus,
13858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                   weak_ptr_factory_.GetWeakPtr(),
13958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                   callback));
14058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
14158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetNetworkInterfaces(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetNetworkInterfacesCallback& callback) OVERRIDE {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetInterfaces);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetPerfData(uint32_t duration,
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GetPerfDataCallback& callback) OVERRIDE {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 debugd::kGetRichPerfData);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    writer.AppendUint32(duration);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &method_call,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   callback));
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                 debugd::kGetFeedbackLogs);
172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    debugdaemon_proxy_->CallMethod(
173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        &method_call,
174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_ptr_factory_.GetWeakPtr(),
177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   callback));
178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAllLogs(const GetLogsCallback& callback)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetAllLogs);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetUserLogFiles(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetLogsCallback& callback) OVERRIDE {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kGetUserLogFiles);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartSystemTracing() OVERRIDE {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStart);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString("all"); // TODO(sleffler) parameterize category list
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace start";
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
215e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        base::Bind(&DebugDaemonClientImpl::OnStartMethod,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual bool RequestStopSystemTracing(
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_refptr<base::TaskRunner> task_runner,
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const StopSystemTracingCallback& callback) OVERRIDE {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pipe_reader_ != NULL) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Busy doing StopSystemTracing";
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    pipe_reader_.reset(new PipeReaderForString(
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        task_runner,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnIOComplete,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr())));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::File pipe_write_end = pipe_reader_->StartIO();
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Create dbus::FileDescriptor on the worker thread; on return we'll
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // issue the D-Bus request to stop tracing and collect results.
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::PostTaskAndReplyWithResult(
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        task_runner.get(),
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        base::Bind(
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            &DebugDaemonClientImpl::CreateFileDescriptorToStopSystemTracing,
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            base::Passed(&pipe_write_end)),
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        base::Bind(
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            &DebugDaemonClientImpl::OnCreateFileDescriptorRequestStopSystem,
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            callback));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TestICMP(const std::string& ip_address,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const TestICMPCallback& callback) OVERRIDE {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 debugd::kTestICMP);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(ip_address);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void TestICMPWithOptions(
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const std::string& ip_address,
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const std::map<std::string, std::string>& options,
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const TestICMPCallback& callback) OVERRIDE {
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 debugd::kTestICMPWithOptions);
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter writer(&method_call);
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter sub_writer(NULL);
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    dbus::MessageWriter elem_writer(NULL);
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Write the host.
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.AppendString(ip_address);
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Write the options.
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.OpenArray("{ss}", &sub_writer);
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::map<std::string, std::string>::const_iterator it;
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    for (it = options.begin(); it != options.end(); ++it) {
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sub_writer.OpenDictEntry(&elem_writer);
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      elem_writer.AppendString(it->first);
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      elem_writer.AppendString(it->second);
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sub_writer.CloseContainer(&elem_writer);
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    writer.CloseContainer(&sub_writer);
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Call the function.
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    debugdaemon_proxy_->CallMethod(
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        &method_call,
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   weak_ptr_factory_.GetWeakPtr(),
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   callback));
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
295e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void UploadCrashes() OVERRIDE {
296e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    dbus::MethodCall method_call(debugd::kDebugdInterface,
297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                 debugd::kUploadCrashes);
298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    debugdaemon_proxy_->CallMethod(
299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        &method_call,
300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
301e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        base::Bind(&DebugDaemonClientImpl::OnStartMethod,
302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                   weak_ptr_factory_.GetWeakPtr()));
303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    debugdaemon_proxy_ =
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bus->GetObjectProxy(debugd::kDebugdServiceName,
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                            dbus::ObjectPath(debugd::kDebugdServicePath));
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnCheckValidityGetDebugLogs(bool is_compressed,
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   dbus::FileDescriptor* file_descriptor,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GetDebugLogsCallback& callback) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to get debug logs.
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dbus::MethodCall method_call(debugd::kDebugdInterface,
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 debugd::kDumpDebugLogs);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    writer.AppendBool(is_compressed);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for GetDebugLogs() is received.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetDebugLogs(const GetDebugLogsCallback& callback,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to get debug logs";
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(true);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for SetDebugMode() is received.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSetDebugMode(const SetDebugModeCallback& callback,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to change debug mode";
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetRoutes(const GetRoutesCallback& callback,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   dbus::Response* response) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> routes;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader reader(response);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (reader.PopArrayOfStrings(&routes)) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(true, routes);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Got non-array response from GetRoutes";
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.Run(false, routes);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, routes);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          dbus::Response* response) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetModemStatus(const GetModemStatusCallback& callback,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        dbus::Response* response) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  void OnGetWiMaxStatus(const GetWiMaxStatusCallback& callback,
38958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                        dbus::Response* response) {
39058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    std::string status;
39158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    if (response && dbus::MessageReader(response).PopString(&status))
39258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      callback.Run(true, status);
39358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    else
39458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      callback.Run(false, "");
39558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
39658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              dbus::Response* response) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnGetPerfData(const GetPerfDataCallback& callback,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     dbus::Response* response) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint8> data;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!response) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MessageReader reader(response);
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const uint8* buffer = NULL;
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t buf_size = 0;
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!reader.PopArrayOfBytes(&buffer, &buf_size))
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(asharif): Figure out a way to avoid this copy.
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data.insert(data.end(), buffer, buffer + buf_size);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(data);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetAllLogs(const GetLogsCallback& callback,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dbus::Response* response) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, std::string> logs;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool broken = false; // did we see a broken (k,v) pair?
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader sub_reader(NULL);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, logs);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (sub_reader.HasMoreData()) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageReader sub_sub_reader(NULL);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string key, value;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!sub_reader.PopDictEntry(&sub_sub_reader)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&key)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          || !sub_sub_reader.PopString(&value)) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        broken = true;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logs[key] = value;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(!sub_reader.HasMoreData() && !broken, logs);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetUserLogFiles(const GetLogsCallback& callback,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         dbus::Response* response) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OnGetAllLogs(callback, response);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
454e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Called when a response for a simple start is received.
455e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void OnStartMethod(dbus::Response* response) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
457e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      LOG(ERROR) << "Failed to request start";
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Creates dbus::FileDescriptor from base::File.
463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  static scoped_ptr<dbus::FileDescriptor>
464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  CreateFileDescriptorToStopSystemTracing(base::File pipe_write_end) {
465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!pipe_write_end.IsValid()) {
466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      LOG(ERROR) << "Cannot create pipe reader";
467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // NB: continue anyway to shutdown tracing; toss trace data
468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      pipe_write_end.Initialize(base::FilePath(FILE_PATH_LITERAL("/dev/null")),
469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                base::File::FLAG_OPEN | base::File::FLAG_WRITE);
470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // TODO(sleffler) if this fails AppendFileDescriptor will abort
471010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
472010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<dbus::FileDescriptor> file_descriptor(new dbus::FileDescriptor);
473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    file_descriptor->PutValue(pipe_write_end.TakePlatformFile());
474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    file_descriptor->CheckValidity();
475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return file_descriptor.Pass();
476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a CheckValidity response is received.
479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void OnCreateFileDescriptorRequestStopSystem(
480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const StopSystemTracingCallback& callback,
481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      scoped_ptr<dbus::FileDescriptor> file_descriptor) {
482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DCHECK(file_descriptor);
483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Issue the dbus request to stop system tracing
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kDebugdInterface,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        debugd::kSystraceStop);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendFileDescriptor(*file_descriptor);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Requesting a systrace stop";
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    debugdaemon_proxy_->CallMethod(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a response for RequestStopSystemTracing() is received.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRequestStopSystemTracing(dbus::Response* response) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to request systrace stop";
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If debugd crashes or completes I/O before this message is processed
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // then pipe_reader_ can be NULL, see OnIOComplete().
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pipe_reader_.get())
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pipe_reader_->OnDataReady(-1); // terminate data stream
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NB: requester is signaled when i/o completes
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response && dbus::MessageReader(response).PopString(&status))
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(true, status);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(false, "");
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when pipe i/o completes; pass data on and delete the instance.
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIOComplete() {
523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    std::string pipe_data;
524c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    pipe_reader_->GetData(&pipe_data);
525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    callback_.Run(base::RefCountedString::TakeString(&pipe_data));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pipe_reader_.reset();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::ObjectProxy* debugdaemon_proxy_;
530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<PipeReaderForString> pipe_reader_;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSystemTracingCallback callback_;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::DebugDaemonClient() {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::~DebugDaemonClient() {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::StopSystemTracingCallback
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DebugDaemonClient::EmptyStopSystemTracingCallback() {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::Bind(&EmptyStopSystemTracingCallbackBody);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DebugDaemonClient* DebugDaemonClient::Create() {
551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new DebugDaemonClientImpl();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
555