- add sources.
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / debug_daemon_client.cc
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
27 namespace {
28
29 // Used in DebugDaemonClient::EmptySystemStopTracingCallback().
30 void 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
41 class 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
137 namespace chromeos {
138
139 // The DebugDaemonClient implementation used in production.
140 class DebugDaemonClientImpl : public DebugDaemonClient {
141  public:
142   DebugDaemonClientImpl() : debugdaemon_proxy_(NULL), weak_ptr_factory_(this) {}
143
144   virtual ~DebugDaemonClientImpl() {}
145
146   // DebugDaemonClient override.
147   virtual void GetDebugLogs(base::PlatformFile file,
148                             const GetDebugLogsCallback& callback) OVERRIDE {
149
150     dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file);
151     // Punt descriptor validity check to a worker thread; on return we'll
152     // issue the D-Bus request to stop tracing and collect results.
153     base::WorkerPool::PostTaskAndReply(
154         FROM_HERE,
155         base::Bind(&DebugDaemonClientImpl::CheckValidity,
156                    file_descriptor),
157         base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
158                    weak_ptr_factory_.GetWeakPtr(),
159                    base::Owned(file_descriptor),
160                    callback),
161         false);
162   }
163
164   virtual void SetDebugMode(const std::string& subsystem,
165                             const SetDebugModeCallback& callback) OVERRIDE {
166     dbus::MethodCall method_call(debugd::kDebugdInterface,
167                                  debugd::kSetDebugMode);
168     dbus::MessageWriter writer(&method_call);
169     writer.AppendString(subsystem);
170     debugdaemon_proxy_->CallMethod(
171         &method_call,
172         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
173         base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
174                    weak_ptr_factory_.GetWeakPtr(),
175                    callback));
176   }
177
178   virtual void GetRoutes(bool numeric, bool ipv6,
179                          const GetRoutesCallback& callback) OVERRIDE {
180     dbus::MethodCall method_call(debugd::kDebugdInterface,
181                                  debugd::kGetRoutes);
182     dbus::MessageWriter writer(&method_call);
183     dbus::MessageWriter sub_writer(NULL);
184     writer.OpenArray("{sv}", &sub_writer);
185     dbus::MessageWriter elem_writer(NULL);
186     sub_writer.OpenDictEntry(&elem_writer);
187     elem_writer.AppendString("numeric");
188     elem_writer.AppendVariantOfBool(numeric);
189     sub_writer.CloseContainer(&elem_writer);
190     sub_writer.OpenDictEntry(&elem_writer);
191     elem_writer.AppendString("v6");
192     elem_writer.AppendVariantOfBool(ipv6);
193     sub_writer.CloseContainer(&elem_writer);
194     writer.CloseContainer(&sub_writer);
195     debugdaemon_proxy_->CallMethod(
196         &method_call,
197         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
198         base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
199                    weak_ptr_factory_.GetWeakPtr(),
200                    callback));
201   }
202
203   virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
204       OVERRIDE {
205     dbus::MethodCall method_call(debugd::kDebugdInterface,
206                                  debugd::kGetNetworkStatus);
207     debugdaemon_proxy_->CallMethod(
208         &method_call,
209         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
210         base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
211                    weak_ptr_factory_.GetWeakPtr(),
212                    callback));
213   }
214
215   virtual void GetModemStatus(const GetModemStatusCallback& callback)
216       OVERRIDE {
217     dbus::MethodCall method_call(debugd::kDebugdInterface,
218                                  debugd::kGetModemStatus);
219     debugdaemon_proxy_->CallMethod(
220         &method_call,
221         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
222         base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
223                    weak_ptr_factory_.GetWeakPtr(),
224                    callback));
225   }
226
227   virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
228       OVERRIDE {
229     dbus::MethodCall method_call(debugd::kDebugdInterface,
230                                  debugd::kGetWiMaxStatus);
231     debugdaemon_proxy_->CallMethod(
232         &method_call,
233         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
234         base::Bind(&DebugDaemonClientImpl::OnGetWiMaxStatus,
235                    weak_ptr_factory_.GetWeakPtr(),
236                    callback));
237   }
238
239   virtual void GetNetworkInterfaces(
240       const GetNetworkInterfacesCallback& callback) OVERRIDE {
241     dbus::MethodCall method_call(debugd::kDebugdInterface,
242                                  debugd::kGetInterfaces);
243     debugdaemon_proxy_->CallMethod(
244         &method_call,
245         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
246         base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
247                    weak_ptr_factory_.GetWeakPtr(),
248                    callback));
249   }
250
251   virtual void GetPerfData(uint32_t duration,
252                            const GetPerfDataCallback& callback) OVERRIDE {
253     dbus::MethodCall method_call(debugd::kDebugdInterface,
254                                  debugd::kGetRichPerfData);
255     dbus::MessageWriter writer(&method_call);
256     writer.AppendUint32(duration);
257
258     debugdaemon_proxy_->CallMethod(
259         &method_call,
260         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
261         base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
262                    weak_ptr_factory_.GetWeakPtr(),
263                    callback));
264   }
265
266   virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
267     dbus::MethodCall method_call(debugd::kDebugdInterface,
268                                  debugd::kGetFeedbackLogs);
269     debugdaemon_proxy_->CallMethod(
270         &method_call,
271         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
272         base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
273                    weak_ptr_factory_.GetWeakPtr(),
274                    callback));
275   }
276
277   virtual void GetAllLogs(const GetLogsCallback& callback)
278       OVERRIDE {
279     dbus::MethodCall method_call(debugd::kDebugdInterface,
280                                  debugd::kGetAllLogs);
281     debugdaemon_proxy_->CallMethod(
282         &method_call,
283         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
284         base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
285                    weak_ptr_factory_.GetWeakPtr(),
286                    callback));
287   }
288
289   virtual void GetUserLogFiles(
290       const GetLogsCallback& callback) OVERRIDE {
291     dbus::MethodCall method_call(debugd::kDebugdInterface,
292                                  debugd::kGetUserLogFiles);
293     debugdaemon_proxy_->CallMethod(
294         &method_call,
295         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
296         base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
297                    weak_ptr_factory_.GetWeakPtr(),
298                    callback));
299   }
300
301   virtual void StartSystemTracing() OVERRIDE {
302     dbus::MethodCall method_call(
303         debugd::kDebugdInterface,
304         debugd::kSystraceStart);
305     dbus::MessageWriter writer(&method_call);
306     writer.AppendString("all"); // TODO(sleffler) parameterize category list
307
308     DVLOG(1) << "Requesting a systrace start";
309     debugdaemon_proxy_->CallMethod(
310         &method_call,
311         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
312         base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
313                    weak_ptr_factory_.GetWeakPtr()));
314   }
315
316   virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
317       callback) OVERRIDE {
318     if (pipe_reader_ != NULL) {
319       LOG(ERROR) << "Busy doing StopSystemTracing";
320       return false;
321     }
322
323     pipe_reader_.reset(new PipeReader(
324         base::Bind(&DebugDaemonClientImpl::OnIOComplete,
325                    weak_ptr_factory_.GetWeakPtr())));
326     int write_fd = -1;
327     if (!pipe_reader_->StartIO()) {
328       LOG(ERROR) << "Cannot create pipe reader";
329       // NB: continue anyway to shutdown tracing; toss trace data
330       write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
331       // TODO(sleffler) if this fails AppendFileDescriptor will abort
332     } else {
333       write_fd = pipe_reader_->GetWriteFD();
334     }
335
336     dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
337     // Punt descriptor validity check to a worker thread; on return we'll
338     // issue the D-Bus request to stop tracing and collect results.
339     base::WorkerPool::PostTaskAndReply(
340         FROM_HERE,
341         base::Bind(&DebugDaemonClientImpl::CheckValidity,
342                    file_descriptor),
343         base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
344                    weak_ptr_factory_.GetWeakPtr(),
345                    base::Owned(file_descriptor),
346                    callback),
347         false);
348
349     return true;
350   }
351
352   virtual void TestICMP(const std::string& ip_address,
353                         const TestICMPCallback& callback) OVERRIDE {
354     dbus::MethodCall method_call(debugd::kDebugdInterface,
355                                  debugd::kTestICMP);
356     dbus::MessageWriter writer(&method_call);
357     writer.AppendString(ip_address);
358     debugdaemon_proxy_->CallMethod(
359         &method_call,
360         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
361         base::Bind(&DebugDaemonClientImpl::OnTestICMP,
362                    weak_ptr_factory_.GetWeakPtr(),
363                    callback));
364   }
365
366   virtual void TestICMPWithOptions(
367       const std::string& ip_address,
368       const std::map<std::string, std::string>& options,
369       const TestICMPCallback& callback) OVERRIDE {
370     dbus::MethodCall method_call(debugd::kDebugdInterface,
371                                  debugd::kTestICMPWithOptions);
372     dbus::MessageWriter writer(&method_call);
373     dbus::MessageWriter sub_writer(NULL);
374     dbus::MessageWriter elem_writer(NULL);
375
376     // Write the host.
377     writer.AppendString(ip_address);
378
379     // Write the options.
380     writer.OpenArray("{ss}", &sub_writer);
381     std::map<std::string, std::string>::const_iterator it;
382     for (it = options.begin(); it != options.end(); ++it) {
383       sub_writer.OpenDictEntry(&elem_writer);
384       elem_writer.AppendString(it->first);
385       elem_writer.AppendString(it->second);
386       sub_writer.CloseContainer(&elem_writer);
387     }
388     writer.CloseContainer(&sub_writer);
389
390     // Call the function.
391     debugdaemon_proxy_->CallMethod(
392         &method_call,
393         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
394         base::Bind(&DebugDaemonClientImpl::OnTestICMP,
395                    weak_ptr_factory_.GetWeakPtr(),
396                    callback));
397   }
398
399  protected:
400   virtual void Init(dbus::Bus* bus) OVERRIDE {
401     debugdaemon_proxy_ =
402         bus->GetObjectProxy(debugd::kDebugdServiceName,
403                             dbus::ObjectPath(debugd::kDebugdServicePath));
404   }
405
406  private:
407   // Called to check descriptor validity on a thread where i/o is permitted.
408   static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
409     file_descriptor->CheckValidity();
410   }
411
412   // Called when a CheckValidity response is received.
413   void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
414                                    const GetDebugLogsCallback& callback) {
415     // Issue the dbus request to get debug logs.
416     dbus::MethodCall method_call(
417         debugd::kDebugdInterface,
418         debugd::kGetDebugLogs);
419     dbus::MessageWriter writer(&method_call);
420     writer.AppendFileDescriptor(*file_descriptor);
421
422     debugdaemon_proxy_->CallMethod(
423         &method_call,
424         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
425         base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
426                    weak_ptr_factory_.GetWeakPtr(),
427                    callback));
428   }
429
430   // Called when a response for GetDebugLogs() is received.
431   void OnGetDebugLogs(const GetDebugLogsCallback& callback,
432                       dbus::Response* response) {
433     if (!response) {
434       LOG(ERROR) << "Failed to get debug logs";
435       callback.Run(false);
436       return;
437     }
438     callback.Run(true);
439   }
440
441   // Called when a response for SetDebugMode() is received.
442   void OnSetDebugMode(const SetDebugModeCallback& callback,
443                       dbus::Response* response) {
444     if (!response) {
445       LOG(ERROR) << "Failed to change debug mode";
446       callback.Run(false);
447     } else {
448       callback.Run(true);
449     }
450   }
451
452   void OnGetRoutes(const GetRoutesCallback& callback,
453                    dbus::Response* response) {
454     std::vector<std::string> routes;
455     if (response) {
456       dbus::MessageReader reader(response);
457       if (reader.PopArrayOfStrings(&routes)) {
458         callback.Run(true, routes);
459       } else {
460         LOG(ERROR) << "Got non-array response from GetRoutes";
461         callback.Run(false, routes);
462       }
463     } else {
464       callback.Run(false, routes);
465     }
466   }
467
468   void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
469                           dbus::Response* response) {
470     std::string status;
471     if (response && dbus::MessageReader(response).PopString(&status))
472       callback.Run(true, status);
473     else
474       callback.Run(false, "");
475   }
476
477   void OnGetModemStatus(const GetModemStatusCallback& callback,
478                         dbus::Response* response) {
479     std::string status;
480     if (response && dbus::MessageReader(response).PopString(&status))
481       callback.Run(true, status);
482     else
483       callback.Run(false, "");
484   }
485
486   void OnGetWiMaxStatus(const GetWiMaxStatusCallback& callback,
487                         dbus::Response* response) {
488     std::string status;
489     if (response && dbus::MessageReader(response).PopString(&status))
490       callback.Run(true, status);
491     else
492       callback.Run(false, "");
493   }
494
495   void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
496                               dbus::Response* response) {
497     std::string status;
498     if (response && dbus::MessageReader(response).PopString(&status))
499       callback.Run(true, status);
500     else
501       callback.Run(false, "");
502   }
503
504   void OnGetPerfData(const GetPerfDataCallback& callback,
505                      dbus::Response* response) {
506     std::vector<uint8> data;
507
508     if (!response) {
509       return;
510     }
511
512     dbus::MessageReader reader(response);
513     uint8* buffer = NULL;
514     size_t buf_size = 0;
515     if (!reader.PopArrayOfBytes(reinterpret_cast<uint8**>(
516         &buffer), &buf_size)) {
517       return;
518     }
519
520     // TODO(asharif): Figure out a way to avoid this copy.
521     data.insert(data.end(), buffer, buffer + buf_size);
522
523     callback.Run(data);
524   }
525
526   void OnGetAllLogs(const GetLogsCallback& callback,
527                     dbus::Response* response) {
528     std::map<std::string, std::string> logs;
529     bool broken = false; // did we see a broken (k,v) pair?
530     dbus::MessageReader sub_reader(NULL);
531     if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
532       callback.Run(false, logs);
533       return;
534     }
535     while (sub_reader.HasMoreData()) {
536       dbus::MessageReader sub_sub_reader(NULL);
537       std::string key, value;
538       if (!sub_reader.PopDictEntry(&sub_sub_reader)
539           || !sub_sub_reader.PopString(&key)
540           || !sub_sub_reader.PopString(&value)) {
541         broken = true;
542         break;
543       }
544       logs[key] = value;
545     }
546     callback.Run(!sub_reader.HasMoreData() && !broken, logs);
547   }
548
549   void OnGetUserLogFiles(const GetLogsCallback& callback,
550                          dbus::Response* response) {
551     return OnGetAllLogs(callback, response);
552   }
553
554   // Called when a response for StartSystemTracing() is received.
555   void OnStartSystemTracing(dbus::Response* response) {
556     if (!response) {
557       LOG(ERROR) << "Failed to request systrace start";
558       return;
559     }
560   }
561
562   // Called when a CheckValidity response is received.
563   void OnCheckValidityRequestStopSystem(
564       dbus::FileDescriptor* file_descriptor,
565       const StopSystemTracingCallback& callback) {
566     // Issue the dbus request to stop system tracing
567     dbus::MethodCall method_call(
568         debugd::kDebugdInterface,
569         debugd::kSystraceStop);
570     dbus::MessageWriter writer(&method_call);
571     writer.AppendFileDescriptor(*file_descriptor);
572
573     callback_ = callback;
574
575     DVLOG(1) << "Requesting a systrace stop";
576     debugdaemon_proxy_->CallMethod(
577         &method_call,
578         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
579         base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
580                    weak_ptr_factory_.GetWeakPtr()));
581
582     pipe_reader_->CloseWriteFD();  // close our copy of fd after send
583   }
584
585   // Called when a response for RequestStopSystemTracing() is received.
586   void OnRequestStopSystemTracing(dbus::Response* response) {
587     if (!response) {
588       LOG(ERROR) << "Failed to request systrace stop";
589       // If debugd crashes or completes I/O before this message is processed
590       // then pipe_reader_ can be NULL, see OnIOComplete().
591       if (pipe_reader_.get())
592         pipe_reader_->OnDataReady(-1); // terminate data stream
593     }
594     // NB: requester is signaled when i/o completes
595   }
596
597   void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
598     std::string status;
599     if (response && dbus::MessageReader(response).PopString(&status))
600       callback.Run(true, status);
601     else
602       callback.Run(false, "");
603   }
604
605   // Called when pipe i/o completes; pass data on and delete the instance.
606   void OnIOComplete() {
607     callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
608     pipe_reader_.reset();
609   }
610
611   dbus::ObjectProxy* debugdaemon_proxy_;
612   scoped_ptr<PipeReader> pipe_reader_;
613   StopSystemTracingCallback callback_;
614   base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
615
616   DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
617 };
618
619 // The DebugDaemonClient implementation used on Linux desktop,
620 // which does nothing.
621 class DebugDaemonClientStubImpl : public DebugDaemonClient {
622   // DebugDaemonClient overrides.
623   virtual void Init(dbus::Bus* bus) OVERRIDE {}
624   virtual void GetDebugLogs(base::PlatformFile file,
625                             const GetDebugLogsCallback& callback) OVERRIDE {
626     callback.Run(false);
627   }
628   virtual void SetDebugMode(const std::string& subsystem,
629                             const SetDebugModeCallback& callback) OVERRIDE {
630     callback.Run(false);
631   }
632   virtual void StartSystemTracing() OVERRIDE {}
633   virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
634       callback) OVERRIDE {
635     std::string no_data;
636     callback.Run(base::RefCountedString::TakeString(&no_data));
637     return true;
638   }
639   virtual void GetRoutes(bool numeric, bool ipv6,
640                          const GetRoutesCallback& callback) OVERRIDE {
641     std::vector<std::string> empty;
642     base::MessageLoop::current()->PostTask(FROM_HERE,
643                                            base::Bind(callback, false, empty));
644   }
645   virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
646       OVERRIDE {
647     base::MessageLoop::current()->PostTask(FROM_HERE,
648                                            base::Bind(callback, false, ""));
649   }
650   virtual void GetModemStatus(const GetModemStatusCallback& callback)
651       OVERRIDE {
652     base::MessageLoop::current()->PostTask(FROM_HERE,
653                                            base::Bind(callback, false, ""));
654   }
655   virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
656       OVERRIDE {
657     base::MessageLoop::current()->PostTask(FROM_HERE,
658                                            base::Bind(callback, false, ""));
659   }
660   virtual void GetNetworkInterfaces(
661       const GetNetworkInterfacesCallback& callback) OVERRIDE {
662     base::MessageLoop::current()->PostTask(FROM_HERE,
663                                            base::Bind(callback, false, ""));
664   }
665   virtual void GetPerfData(uint32_t duration,
666                            const GetPerfDataCallback& callback) OVERRIDE {
667     std::vector<uint8> data;
668     base::MessageLoop::current()->PostTask(FROM_HERE,
669     base::Bind(callback, data));
670   }
671   virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
672     std::map<std::string, std::string> sample;
673     sample["Sample Scrubbed Log"] = "Your email address is xxxxxxxx";
674     base::MessageLoop::current()->PostTask(
675         FROM_HERE, base::Bind(callback, false, sample));
676   }
677   virtual void GetAllLogs(const GetLogsCallback& callback) OVERRIDE {
678     std::map<std::string, std::string> sample;
679     sample["Sample Log"] = "Your email address is abc@abc.com";
680     base::MessageLoop::current()->PostTask(
681         FROM_HERE, base::Bind(callback, false, sample));
682   }
683   virtual void GetUserLogFiles(const GetLogsCallback& callback) OVERRIDE {
684     std::map<std::string, std::string> user_logs;
685     user_logs["preferences"] = "Preferences";
686     user_logs["invalid_file"] = "Invalid File";
687     base::MessageLoop::current()->PostTask(
688         FROM_HERE,
689         base::Bind(callback, true, user_logs));
690   }
691
692   virtual void TestICMP(const std::string& ip_address,
693                         const TestICMPCallback& callback) OVERRIDE {
694     base::MessageLoop::current()->PostTask(FROM_HERE,
695                                            base::Bind(callback, false, ""));
696   }
697
698   virtual void TestICMPWithOptions(
699       const std::string& ip_address,
700       const std::map<std::string, std::string>& options,
701       const TestICMPCallback& callback) OVERRIDE {
702     base::MessageLoop::current()->PostTask(FROM_HERE,
703                                            base::Bind(callback, false, ""));
704   }
705 };
706
707 DebugDaemonClient::DebugDaemonClient() {
708 }
709
710 DebugDaemonClient::~DebugDaemonClient() {
711 }
712
713 // static
714 DebugDaemonClient::StopSystemTracingCallback
715 DebugDaemonClient::EmptyStopSystemTracingCallback() {
716   return base::Bind(&EmptyStopSystemTracingCallbackBody);
717 }
718
719 // static
720 DebugDaemonClient* DebugDaemonClient::Create(
721     DBusClientImplementationType type) {
722   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
723     return new DebugDaemonClientImpl();
724   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
725   return new DebugDaemonClientStubImpl();
726 }
727
728 }  // namespace chromeos