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 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. 620 class 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 (at) 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 705 DebugDaemonClient::DebugDaemonClient() { 706 } 707 708 DebugDaemonClient::~DebugDaemonClient() { 709 } 710 711 // static 712 DebugDaemonClient::StopSystemTracingCallback 713 DebugDaemonClient::EmptyStopSystemTracingCallback() { 714 return base::Bind(&EmptyStopSystemTracingCallbackBody); 715 } 716 717 // static 718 DebugDaemonClient* 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