1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <fcntl.h>
6#include <unistd.h>
7
8#include "chromeos/dbus/debug_daemon_client.h"
9
10#include "base/bind.h"
11#include "base/callback.h"
12#include "base/memory/ref_counted_memory.h"
13#include "base/message_loop/message_loop.h"
14#include "base/platform_file.h"
15#include "base/posix/eintr_wrapper.h"
16#include "base/strings/string_util.h"
17#include "base/threading/worker_pool.h"
18#include "dbus/bus.h"
19#include "dbus/message.h"
20#include "dbus/object_path.h"
21#include "dbus/object_proxy.h"
22#include "net/base/file_stream.h"
23#include "net/base/io_buffer.h"
24#include "net/base/net_errors.h"
25#include "third_party/cros_system_api/dbus/service_constants.h"
26
27namespace {
28
29// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
30void EmptyStopSystemTracingCallbackBody(
31  const scoped_refptr<base::RefCountedString>& unused_result) {
32}
33
34// Simple class to encapsulate collecting data from a pipe into a
35// string.  To use, instantiate the class, start i/o, and then delete
36// the instance on callback.  The data should be retrieved before
37// delete and extracted or copied.
38//
39// TODO(sleffler) move data collection to a sub-class so this
40// can be reused to process data as it is received
41class PipeReader {
42 public:
43  typedef base::Callback<void(void)>IOCompleteCallback;
44
45  explicit PipeReader(IOCompleteCallback callback)
46      : io_buffer_(new net::IOBufferWithSize(4096)),
47        callback_(callback),
48        weak_ptr_factory_(this) {
49    pipe_fd_[0] = pipe_fd_[1] = -1;
50  }
51
52  virtual ~PipeReader() {
53    // Don't close pipe_fd_[0] as it's closed by data_stream_.
54    if (pipe_fd_[1] != -1)
55      if (HANDLE_EINTR(close(pipe_fd_[1])) < 0)
56        PLOG(ERROR) << "close[1]";
57  }
58
59  // Returns descriptor for the writeable side of the pipe.
60  int GetWriteFD() { return pipe_fd_[1]; }
61
62  // Closes writeable descriptor; normally used in parent process after fork.
63  void CloseWriteFD() {
64    if (pipe_fd_[1] != -1) {
65      if (HANDLE_EINTR(close(pipe_fd_[1])) < 0)
66        PLOG(ERROR) << "close";
67      pipe_fd_[1] = -1;
68    }
69  }
70
71  // Returns collected data.
72  std::string* data() { return &data_; }
73
74  // Starts data collection.  Returns true if stream was setup correctly.
75  // On success data will automatically be accumulated into a string that
76  // can be retrieved with PipeReader::data().  To shutdown collection delete
77  // the instance and/or use PipeReader::OnDataReady(-1).
78  bool StartIO() {
79    // Use a pipe to collect data
80    const int status = HANDLE_EINTR(pipe(pipe_fd_));
81    if (status < 0) {
82      PLOG(ERROR) << "pipe";
83      return false;
84    }
85    base::PlatformFile data_file_ = pipe_fd_[0];  // read side
86    data_stream_.reset(new net::FileStream(data_file_,
87        base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
88        NULL));
89
90    // Post an initial async read to setup data collection
91    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
92        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
93    if (rv != net::ERR_IO_PENDING) {
94      LOG(ERROR) << "Unable to post initial read";
95      return false;
96    }
97    return true;
98  }
99
100  // Called when pipe data are available.  Can also be used to shutdown
101  // data collection by passing -1 for |byte_count|.
102  void OnDataReady(int byte_count) {
103    DVLOG(1) << "OnDataReady byte_count " << byte_count;
104    if (byte_count <= 0) {
105      callback_.Run();  // signal creator to take data and delete us
106      return;
107    }
108    data_.append(io_buffer_->data(), byte_count);
109
110    // Post another read
111    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
112        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
113    if (rv != net::ERR_IO_PENDING) {
114      LOG(ERROR) << "Unable to post another read";
115      // TODO(sleffler) do something more intelligent?
116    }
117  }
118
119 private:
120  friend class base::RefCounted<PipeReader>;
121
122  int pipe_fd_[2];
123  scoped_ptr<net::FileStream> data_stream_;
124  scoped_refptr<net::IOBufferWithSize> io_buffer_;
125  std::string data_;
126  IOCompleteCallback callback_;
127
128  // Note: This should remain the last member so it'll be destroyed and
129  // invalidate its weak pointers before any other members are destroyed.
130  base::WeakPtrFactory<PipeReader> weak_ptr_factory_;
131
132  DISALLOW_COPY_AND_ASSIGN(PipeReader);
133};
134
135}  // namespace
136
137namespace chromeos {
138
139// The DebugDaemonClient implementation used in production.
140class DebugDaemonClientImpl : public DebugDaemonClient {
141 public:
142  explicit DebugDaemonClientImpl(dbus::Bus* bus)
143      : debugdaemon_proxy_(NULL),
144        weak_ptr_factory_(this) {
145    debugdaemon_proxy_ = bus->GetObjectProxy(
146        debugd::kDebugdServiceName,
147        dbus::ObjectPath(debugd::kDebugdServicePath));
148  }
149
150  virtual ~DebugDaemonClientImpl() {}
151
152  // DebugDaemonClient override.
153  virtual void GetDebugLogs(base::PlatformFile file,
154                            const GetDebugLogsCallback& callback) OVERRIDE {
155
156    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file);
157    // Punt descriptor validity check to a worker thread; on return we'll
158    // issue the D-Bus request to stop tracing and collect results.
159    base::WorkerPool::PostTaskAndReply(
160        FROM_HERE,
161        base::Bind(&DebugDaemonClientImpl::CheckValidity,
162                   file_descriptor),
163        base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
164                   weak_ptr_factory_.GetWeakPtr(),
165                   base::Owned(file_descriptor),
166                   callback),
167        false);
168  }
169
170  virtual void SetDebugMode(const std::string& subsystem,
171                            const SetDebugModeCallback& callback) OVERRIDE {
172    dbus::MethodCall method_call(debugd::kDebugdInterface,
173                                 debugd::kSetDebugMode);
174    dbus::MessageWriter writer(&method_call);
175    writer.AppendString(subsystem);
176    debugdaemon_proxy_->CallMethod(
177        &method_call,
178        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
179        base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
180                   weak_ptr_factory_.GetWeakPtr(),
181                   callback));
182  }
183
184  virtual void GetRoutes(bool numeric, bool ipv6,
185                         const GetRoutesCallback& callback) OVERRIDE {
186    dbus::MethodCall method_call(debugd::kDebugdInterface,
187                                 debugd::kGetRoutes);
188    dbus::MessageWriter writer(&method_call);
189    dbus::MessageWriter sub_writer(NULL);
190    writer.OpenArray("{sv}", &sub_writer);
191    dbus::MessageWriter elem_writer(NULL);
192    sub_writer.OpenDictEntry(&elem_writer);
193    elem_writer.AppendString("numeric");
194    elem_writer.AppendVariantOfBool(numeric);
195    sub_writer.CloseContainer(&elem_writer);
196    sub_writer.OpenDictEntry(&elem_writer);
197    elem_writer.AppendString("v6");
198    elem_writer.AppendVariantOfBool(ipv6);
199    sub_writer.CloseContainer(&elem_writer);
200    writer.CloseContainer(&sub_writer);
201    debugdaemon_proxy_->CallMethod(
202        &method_call,
203        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
204        base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
205                   weak_ptr_factory_.GetWeakPtr(),
206                   callback));
207  }
208
209  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
210      OVERRIDE {
211    dbus::MethodCall method_call(debugd::kDebugdInterface,
212                                 debugd::kGetNetworkStatus);
213    debugdaemon_proxy_->CallMethod(
214        &method_call,
215        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
216        base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
217                   weak_ptr_factory_.GetWeakPtr(),
218                   callback));
219  }
220
221  virtual void GetModemStatus(const GetModemStatusCallback& callback)
222      OVERRIDE {
223    dbus::MethodCall method_call(debugd::kDebugdInterface,
224                                 debugd::kGetModemStatus);
225    debugdaemon_proxy_->CallMethod(
226        &method_call,
227        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
228        base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
229                   weak_ptr_factory_.GetWeakPtr(),
230                   callback));
231  }
232
233  virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
234      OVERRIDE {
235    dbus::MethodCall method_call(debugd::kDebugdInterface,
236                                 debugd::kGetWiMaxStatus);
237    debugdaemon_proxy_->CallMethod(
238        &method_call,
239        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
240        base::Bind(&DebugDaemonClientImpl::OnGetWiMaxStatus,
241                   weak_ptr_factory_.GetWeakPtr(),
242                   callback));
243  }
244
245  virtual void GetNetworkInterfaces(
246      const GetNetworkInterfacesCallback& callback) OVERRIDE {
247    dbus::MethodCall method_call(debugd::kDebugdInterface,
248                                 debugd::kGetInterfaces);
249    debugdaemon_proxy_->CallMethod(
250        &method_call,
251        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
252        base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
253                   weak_ptr_factory_.GetWeakPtr(),
254                   callback));
255  }
256
257  virtual void GetPerfData(uint32_t duration,
258                           const GetPerfDataCallback& callback) OVERRIDE {
259    dbus::MethodCall method_call(debugd::kDebugdInterface,
260                                 debugd::kGetPerfData);
261    dbus::MessageWriter writer(&method_call);
262    writer.AppendUint32(duration);
263
264    debugdaemon_proxy_->CallMethod(
265        &method_call,
266        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
267        base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
268                   weak_ptr_factory_.GetWeakPtr(),
269                   callback));
270  }
271
272  virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
273    dbus::MethodCall method_call(debugd::kDebugdInterface,
274                                 debugd::kGetFeedbackLogs);
275    debugdaemon_proxy_->CallMethod(
276        &method_call,
277        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
278        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
279                   weak_ptr_factory_.GetWeakPtr(),
280                   callback));
281  }
282
283  virtual void GetAllLogs(const GetLogsCallback& callback)
284      OVERRIDE {
285    dbus::MethodCall method_call(debugd::kDebugdInterface,
286                                 debugd::kGetAllLogs);
287    debugdaemon_proxy_->CallMethod(
288        &method_call,
289        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
290        base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
291                   weak_ptr_factory_.GetWeakPtr(),
292                   callback));
293  }
294
295  virtual void GetUserLogFiles(
296      const GetLogsCallback& callback) OVERRIDE {
297    dbus::MethodCall method_call(debugd::kDebugdInterface,
298                                 debugd::kGetUserLogFiles);
299    debugdaemon_proxy_->CallMethod(
300        &method_call,
301        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
302        base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
303                   weak_ptr_factory_.GetWeakPtr(),
304                   callback));
305  }
306
307  virtual void StartSystemTracing() OVERRIDE {
308    dbus::MethodCall method_call(
309        debugd::kDebugdInterface,
310        debugd::kSystraceStart);
311    dbus::MessageWriter writer(&method_call);
312    writer.AppendString("all"); // TODO(sleffler) parameterize category list
313
314    DVLOG(1) << "Requesting a systrace start";
315    debugdaemon_proxy_->CallMethod(
316        &method_call,
317        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
318        base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
319                   weak_ptr_factory_.GetWeakPtr()));
320  }
321
322  virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
323      callback) OVERRIDE {
324    if (pipe_reader_ != NULL) {
325      LOG(ERROR) << "Busy doing StopSystemTracing";
326      return false;
327    }
328
329    pipe_reader_.reset(new PipeReader(
330        base::Bind(&DebugDaemonClientImpl::OnIOComplete,
331                   weak_ptr_factory_.GetWeakPtr())));
332    int write_fd = -1;
333    if (!pipe_reader_->StartIO()) {
334      LOG(ERROR) << "Cannot create pipe reader";
335      // NB: continue anyway to shutdown tracing; toss trace data
336      write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
337      // TODO(sleffler) if this fails AppendFileDescriptor will abort
338    } else {
339      write_fd = pipe_reader_->GetWriteFD();
340    }
341
342    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
343    // Punt descriptor validity check to a worker thread; on return we'll
344    // issue the D-Bus request to stop tracing and collect results.
345    base::WorkerPool::PostTaskAndReply(
346        FROM_HERE,
347        base::Bind(&DebugDaemonClientImpl::CheckValidity,
348                   file_descriptor),
349        base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
350                   weak_ptr_factory_.GetWeakPtr(),
351                   base::Owned(file_descriptor),
352                   callback),
353        false);
354
355    return true;
356  }
357
358  virtual void TestICMP(const std::string& ip_address,
359                        const TestICMPCallback& callback) OVERRIDE {
360    dbus::MethodCall method_call(debugd::kDebugdInterface,
361                                 debugd::kTestICMP);
362    dbus::MessageWriter writer(&method_call);
363    writer.AppendString(ip_address);
364    debugdaemon_proxy_->CallMethod(
365        &method_call,
366        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
367        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
368                   weak_ptr_factory_.GetWeakPtr(),
369                   callback));
370  }
371
372  virtual void TestICMPWithOptions(
373      const std::string& ip_address,
374      const std::map<std::string, std::string>& options,
375      const TestICMPCallback& callback) OVERRIDE {
376    dbus::MethodCall method_call(debugd::kDebugdInterface,
377                                 debugd::kTestICMPWithOptions);
378    dbus::MessageWriter writer(&method_call);
379    dbus::MessageWriter sub_writer(NULL);
380    dbus::MessageWriter elem_writer(NULL);
381
382    // Write the host.
383    writer.AppendString(ip_address);
384
385    // Write the options.
386    writer.OpenArray("{ss}", &sub_writer);
387    std::map<std::string, std::string>::const_iterator it;
388    for (it = options.begin(); it != options.end(); ++it) {
389      sub_writer.OpenDictEntry(&elem_writer);
390      elem_writer.AppendString(it->first);
391      elem_writer.AppendString(it->second);
392      sub_writer.CloseContainer(&elem_writer);
393    }
394    writer.CloseContainer(&sub_writer);
395
396    // Call the function.
397    debugdaemon_proxy_->CallMethod(
398        &method_call,
399        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
400        base::Bind(&DebugDaemonClientImpl::OnTestICMP,
401                   weak_ptr_factory_.GetWeakPtr(),
402                   callback));
403  }
404
405 private:
406  // Called to check descriptor validity on a thread where i/o is permitted.
407  static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
408    file_descriptor->CheckValidity();
409  }
410
411  // Called when a CheckValidity response is received.
412  void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
413                                   const GetDebugLogsCallback& callback) {
414    // Issue the dbus request to get debug logs.
415    dbus::MethodCall method_call(
416        debugd::kDebugdInterface,
417        debugd::kGetDebugLogs);
418    dbus::MessageWriter writer(&method_call);
419    writer.AppendFileDescriptor(*file_descriptor);
420
421    debugdaemon_proxy_->CallMethod(
422        &method_call,
423        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
424        base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
425                   weak_ptr_factory_.GetWeakPtr(),
426                   callback));
427  }
428
429  // Called when a response for GetDebugLogs() is received.
430  void OnGetDebugLogs(const GetDebugLogsCallback& callback,
431                      dbus::Response* response) {
432    if (!response) {
433      LOG(ERROR) << "Failed to get debug logs";
434      callback.Run(false);
435      return;
436    }
437    callback.Run(true);
438  }
439
440  // Called when a response for SetDebugMode() is received.
441  void OnSetDebugMode(const SetDebugModeCallback& callback,
442                      dbus::Response* response) {
443    if (!response) {
444      LOG(ERROR) << "Failed to change debug mode";
445      callback.Run(false);
446    } else {
447      callback.Run(true);
448    }
449  }
450
451  void OnGetRoutes(const GetRoutesCallback& callback,
452                   dbus::Response* response) {
453    std::vector<std::string> routes;
454    if (response) {
455      dbus::MessageReader reader(response);
456      if (reader.PopArrayOfStrings(&routes)) {
457        callback.Run(true, routes);
458      } else {
459        LOG(ERROR) << "Got non-array response from GetRoutes";
460        callback.Run(false, routes);
461      }
462    } else {
463      callback.Run(false, routes);
464    }
465  }
466
467  void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
468                          dbus::Response* response) {
469    std::string status;
470    if (response && dbus::MessageReader(response).PopString(&status))
471      callback.Run(true, status);
472    else
473      callback.Run(false, "");
474  }
475
476  void OnGetModemStatus(const GetModemStatusCallback& callback,
477                        dbus::Response* response) {
478    std::string status;
479    if (response && dbus::MessageReader(response).PopString(&status))
480      callback.Run(true, status);
481    else
482      callback.Run(false, "");
483  }
484
485  void OnGetWiMaxStatus(const GetWiMaxStatusCallback& callback,
486                        dbus::Response* response) {
487    std::string status;
488    if (response && dbus::MessageReader(response).PopString(&status))
489      callback.Run(true, status);
490    else
491      callback.Run(false, "");
492  }
493
494  void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
495                              dbus::Response* response) {
496    std::string status;
497    if (response && dbus::MessageReader(response).PopString(&status))
498      callback.Run(true, status);
499    else
500      callback.Run(false, "");
501  }
502
503  void OnGetPerfData(const GetPerfDataCallback& callback,
504                     dbus::Response* response) {
505    std::vector<uint8> data;
506
507    if (!response) {
508      return;
509    }
510
511    dbus::MessageReader reader(response);
512    uint8* buffer = NULL;
513    size_t buf_size = 0;
514    if (!reader.PopArrayOfBytes(reinterpret_cast<uint8**>(
515        &buffer), &buf_size)) {
516      return;
517    }
518
519    // TODO(asharif): Figure out a way to avoid this copy.
520    data.insert(data.end(), buffer, buffer + buf_size);
521
522    callback.Run(data);
523  }
524
525  void OnGetAllLogs(const GetLogsCallback& callback,
526                    dbus::Response* response) {
527    std::map<std::string, std::string> logs;
528    bool broken = false; // did we see a broken (k,v) pair?
529    dbus::MessageReader sub_reader(NULL);
530    if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
531      callback.Run(false, logs);
532      return;
533    }
534    while (sub_reader.HasMoreData()) {
535      dbus::MessageReader sub_sub_reader(NULL);
536      std::string key, value;
537      if (!sub_reader.PopDictEntry(&sub_sub_reader)
538          || !sub_sub_reader.PopString(&key)
539          || !sub_sub_reader.PopString(&value)) {
540        broken = true;
541        break;
542      }
543      logs[key] = value;
544    }
545    callback.Run(!sub_reader.HasMoreData() && !broken, logs);
546  }
547
548  void OnGetUserLogFiles(const GetLogsCallback& callback,
549                         dbus::Response* response) {
550    return OnGetAllLogs(callback, response);
551  }
552
553  // Called when a response for StartSystemTracing() is received.
554  void OnStartSystemTracing(dbus::Response* response) {
555    if (!response) {
556      LOG(ERROR) << "Failed to request systrace start";
557      return;
558    }
559  }
560
561  // Called when a CheckValidity response is received.
562  void OnCheckValidityRequestStopSystem(
563      dbus::FileDescriptor* file_descriptor,
564      const StopSystemTracingCallback& callback) {
565    // Issue the dbus request to stop system tracing
566    dbus::MethodCall method_call(
567        debugd::kDebugdInterface,
568        debugd::kSystraceStop);
569    dbus::MessageWriter writer(&method_call);
570    writer.AppendFileDescriptor(*file_descriptor);
571
572    callback_ = callback;
573
574    DVLOG(1) << "Requesting a systrace stop";
575    debugdaemon_proxy_->CallMethod(
576        &method_call,
577        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
578        base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
579                   weak_ptr_factory_.GetWeakPtr()));
580
581    pipe_reader_->CloseWriteFD();  // close our copy of fd after send
582  }
583
584  // Called when a response for RequestStopSystemTracing() is received.
585  void OnRequestStopSystemTracing(dbus::Response* response) {
586    if (!response) {
587      LOG(ERROR) << "Failed to request systrace stop";
588      // If debugd crashes or completes I/O before this message is processed
589      // then pipe_reader_ can be NULL, see OnIOComplete().
590      if (pipe_reader_.get())
591        pipe_reader_->OnDataReady(-1); // terminate data stream
592    }
593    // NB: requester is signaled when i/o completes
594  }
595
596  void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
597    std::string status;
598    if (response && dbus::MessageReader(response).PopString(&status))
599      callback.Run(true, status);
600    else
601      callback.Run(false, "");
602  }
603
604  // Called when pipe i/o completes; pass data on and delete the instance.
605  void OnIOComplete() {
606    callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
607    pipe_reader_.reset();
608  }
609
610  dbus::ObjectProxy* debugdaemon_proxy_;
611  scoped_ptr<PipeReader> pipe_reader_;
612  StopSystemTracingCallback callback_;
613  base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
614
615  DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
616};
617
618// The DebugDaemonClient implementation used on Linux desktop,
619// which does nothing.
620class DebugDaemonClientStubImpl : public DebugDaemonClient {
621  // DebugDaemonClient overrides.
622  virtual void GetDebugLogs(base::PlatformFile file,
623                            const GetDebugLogsCallback& callback) OVERRIDE {
624    callback.Run(false);
625  }
626  virtual void SetDebugMode(const std::string& subsystem,
627                            const SetDebugModeCallback& callback) OVERRIDE {
628    callback.Run(false);
629  }
630  virtual void StartSystemTracing() OVERRIDE {}
631  virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
632      callback) OVERRIDE {
633    std::string no_data;
634    callback.Run(base::RefCountedString::TakeString(&no_data));
635    return true;
636  }
637  virtual void GetRoutes(bool numeric, bool ipv6,
638                         const GetRoutesCallback& callback) OVERRIDE {
639    std::vector<std::string> empty;
640    base::MessageLoop::current()->PostTask(FROM_HERE,
641                                           base::Bind(callback, false, empty));
642  }
643  virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
644      OVERRIDE {
645    base::MessageLoop::current()->PostTask(FROM_HERE,
646                                           base::Bind(callback, false, ""));
647  }
648  virtual void GetModemStatus(const GetModemStatusCallback& callback)
649      OVERRIDE {
650    base::MessageLoop::current()->PostTask(FROM_HERE,
651                                           base::Bind(callback, false, ""));
652  }
653  virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
654      OVERRIDE {
655    base::MessageLoop::current()->PostTask(FROM_HERE,
656                                           base::Bind(callback, false, ""));
657  }
658  virtual void GetNetworkInterfaces(
659      const GetNetworkInterfacesCallback& callback) OVERRIDE {
660    base::MessageLoop::current()->PostTask(FROM_HERE,
661                                           base::Bind(callback, false, ""));
662  }
663  virtual void GetPerfData(uint32_t duration,
664                           const GetPerfDataCallback& callback) OVERRIDE {
665    std::vector<uint8> data;
666    base::MessageLoop::current()->PostTask(FROM_HERE,
667    base::Bind(callback, data));
668  }
669  virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
670    std::map<std::string, std::string> sample;
671    sample["Sample Scrubbed Log"] = "Your email address is xxxxxxxx";
672    base::MessageLoop::current()->PostTask(
673        FROM_HERE, base::Bind(callback, false, sample));
674  }
675  virtual void GetAllLogs(const GetLogsCallback& callback) OVERRIDE {
676    std::map<std::string, std::string> sample;
677    sample["Sample Log"] = "Your email address is abc@abc.com";
678    base::MessageLoop::current()->PostTask(
679        FROM_HERE, base::Bind(callback, false, sample));
680  }
681  virtual void GetUserLogFiles(const GetLogsCallback& callback) OVERRIDE {
682    std::map<std::string, std::string> user_logs;
683    user_logs["preferences"] = "Preferences";
684    user_logs["invalid_file"] = "Invalid File";
685    base::MessageLoop::current()->PostTask(
686        FROM_HERE,
687        base::Bind(callback, true, user_logs));
688  }
689
690  virtual void TestICMP(const std::string& ip_address,
691                        const TestICMPCallback& callback) OVERRIDE {
692    base::MessageLoop::current()->PostTask(FROM_HERE,
693                                           base::Bind(callback, false, ""));
694  }
695
696  virtual void TestICMPWithOptions(
697      const std::string& ip_address,
698      const std::map<std::string, std::string>& options,
699      const TestICMPCallback& callback) OVERRIDE {
700    base::MessageLoop::current()->PostTask(FROM_HERE,
701                                           base::Bind(callback, false, ""));
702  }
703};
704
705DebugDaemonClient::DebugDaemonClient() {
706}
707
708DebugDaemonClient::~DebugDaemonClient() {
709}
710
711// static
712DebugDaemonClient::StopSystemTracingCallback
713DebugDaemonClient::EmptyStopSystemTracingCallback() {
714  return base::Bind(&EmptyStopSystemTracingCallbackBody);
715}
716
717// static
718DebugDaemonClient* DebugDaemonClient::Create(DBusClientImplementationType type,
719                                   dbus::Bus* bus) {
720  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
721    return new DebugDaemonClientImpl(bus);
722  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
723  return new DebugDaemonClientStubImpl();
724}
725
726}  // namespace chromeos
727