summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/dbus
diff options
context:
space:
mode:
authorsleffler@chromium.org <sleffler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-05 07:27:34 +0000
committersleffler@chromium.org <sleffler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-05 07:27:34 +0000
commit3629fd7b8bbec105c5819aba93f7931e62443461 (patch)
treee1127a18a0cd5cc736eefe0147f1b6ec200783ee /chrome/browser/chromeos/dbus
parent32dfbe4c74fb99ccef54c9006c143ea9e538c656 (diff)
downloadchromium_src-3629fd7b8bbec105c5819aba93f7931e62443461.zip
chromium_src-3629fd7b8bbec105c5819aba93f7931e62443461.tar.gz
chromium_src-3629fd7b8bbec105c5819aba93f7931e62443461.tar.bz2
chromeos: add client support for debugd systrace support
Add support for communicating with the debugd service and enable access to use systrace methods. BUG=chromium-os:27809 TEST=use new about:tracing support to collect system event data Change-Id: I1b6ed75f3ece960c77527e7b9d3a34e5cb76401e Review URL: http://codereview.chromium.org/9700073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130860 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/dbus')
-rw-r--r--chrome/browser/chromeos/dbus/dbus_thread_manager.cc10
-rw-r--r--chrome/browser/chromeos/dbus/dbus_thread_manager.h6
-rw-r--r--chrome/browser/chromeos/dbus/debug_daemon_client.cc277
-rw-r--r--chrome/browser/chromeos/dbus/debug_daemon_client.h52
-rw-r--r--chrome/browser/chromeos/dbus/mock_dbus_thread_manager.cc4
-rw-r--r--chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h6
-rw-r--r--chrome/browser/chromeos/dbus/mock_debug_daemon_client.cc13
-rw-r--r--chrome/browser/chromeos/dbus/mock_debug_daemon_client.h25
8 files changed, 393 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/dbus/dbus_thread_manager.cc b/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
index fc169cc..9cbd6ab 100644
--- a/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
+++ b/chrome/browser/chromeos/dbus/dbus_thread_manager.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/chromeos/dbus/dbus_client_implementation_type.h"
#include "chrome/browser/chromeos/dbus/cros_disks_client.h"
#include "chrome/browser/chromeos/dbus/cryptohome_client.h"
+#include "chrome/browser/chromeos/dbus/debug_daemon_client.h"
#include "chrome/browser/chromeos/dbus/flimflam_ipconfig_client.h"
#include "chrome/browser/chromeos/dbus/flimflam_network_client.h"
#include "chrome/browser/chromeos/dbus/flimflam_profile_client.h"
@@ -72,6 +73,9 @@ class DBusThreadManagerImpl : public DBusThreadManager {
// Create the Cryptohome client.
cryptohome_client_.reset(
CryptohomeClient::Create(client_type, system_bus_.get()));
+ // Create the debugdaemon client.
+ debugdaemon_client_.reset(
+ DebugDaemonClient::Create(client_type, system_bus_.get()));
// Create the Flimflam IPConfig client.
flimflam_ipconfig_client_.reset(
FlimflamIPConfigClient::Create(client_type, system_bus_.get()));
@@ -156,6 +160,11 @@ class DBusThreadManagerImpl : public DBusThreadManager {
}
// DBusThreadManager override.
+ virtual DebugDaemonClient* GetDebugDaemonClient() OVERRIDE {
+ return debugdaemon_client_.get();
+ }
+
+ // DBusThreadManager override.
virtual FlimflamIPConfigClient* GetFlimflamIPConfigClient() OVERRIDE {
return flimflam_ipconfig_client_.get();
}
@@ -209,6 +218,7 @@ class DBusThreadManagerImpl : public DBusThreadManager {
scoped_ptr<CashewClient> cashew_client_;
scoped_ptr<CrosDisksClient> cros_disks_client_;
scoped_ptr<CryptohomeClient> cryptohome_client_;
+ scoped_ptr<DebugDaemonClient> debugdaemon_client_;
scoped_ptr<FlimflamIPConfigClient> flimflam_ipconfig_client_;
scoped_ptr<FlimflamNetworkClient> flimflam_network_client_;
scoped_ptr<FlimflamProfileClient> flimflam_profile_client_;
diff --git a/chrome/browser/chromeos/dbus/dbus_thread_manager.h b/chrome/browser/chromeos/dbus/dbus_thread_manager.h
index cbcf371..f2caffa 100644
--- a/chrome/browser/chromeos/dbus/dbus_thread_manager.h
+++ b/chrome/browser/chromeos/dbus/dbus_thread_manager.h
@@ -28,6 +28,7 @@ class BluetoothNodeClient;
class CashewClient;
class CrosDisksClient;
class CryptohomeClient;
+class DebugDaemonClient;
class FlimflamIPConfigClient;
class FlimflamNetworkClient;
class FlimflamProfileClient;
@@ -118,6 +119,11 @@ class DBusThreadManager {
// down.
virtual CryptohomeClient* GetCryptohomeClient() = 0;
+ // Returns the DebugDaemon client, owned by DBusThreadManager.
+ // Do not cache this pointer and use it after DBusThreadManager is shut
+ // down.
+ virtual DebugDaemonClient* GetDebugDaemonClient() = 0;
+
// Returns the Flimflam IPConfig client, owned by DBusThreadManager.
// Do not cache this pointer and use it after DBusThreadManager is shut
// down.
diff --git a/chrome/browser/chromeos/dbus/debug_daemon_client.cc b/chrome/browser/chromeos/dbus/debug_daemon_client.cc
new file mode 100644
index 0000000..1fec37d
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/debug_daemon_client.cc
@@ -0,0 +1,277 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "chrome/browser/chromeos/dbus/debug_daemon_client.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/chromeos/chromeos_version.h"
+#include "base/eintr_wrapper.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/platform_file.h"
+#include "base/string_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "net/base/file_stream.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+using content::BrowserThread;
+
+namespace {
+
+// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
+void EmptyStopSystemTracingCallbackBody(
+ const scoped_refptr<base::RefCountedString>& unused_result) {
+}
+
+// Simple class to encapsulate collecting data from a pipe into a
+// string. To use, instantiate the class, start i/o, and then delete
+// the instance on callback. The data should be retrieved before
+// delete and extracted or copied.
+//
+// TODO(sleffler) move data collection to a sub-class so this
+// can be reused to process data as it is received
+class PipeReader {
+ public:
+ typedef base::Callback<void(void)>IOCompleteCallback;
+
+ explicit PipeReader(IOCompleteCallback callback)
+ : data_stream_(NULL),
+ io_buffer_(new net::IOBufferWithSize(4096)),
+ weak_ptr_factory_(this),
+ callback_(callback) {
+ pipe_fd_[0] = pipe_fd_[1] = -1;
+ }
+
+ virtual ~PipeReader() {
+ if (pipe_fd_[0] != -1)
+ HANDLE_EINTR(close(pipe_fd_[0]));
+ if (pipe_fd_[1] != -1)
+ HANDLE_EINTR(close(pipe_fd_[1]));
+ }
+
+ // Returns descriptor for the writeable side of the pipe.
+ int GetWriteFD() { return pipe_fd_[1]; }
+
+ // Closes writeable descriptor; normally used in parent process after fork.
+ void CloseWriteFD() {
+ if (pipe_fd_[1] != -1) {
+ HANDLE_EINTR(close(pipe_fd_[1]));
+ pipe_fd_[1] = -1;
+ }
+ }
+
+ // Returns collected data.
+ std::string* data() { return &data_; }
+
+ // Starts data collection. Returns true if stream was setup correctly.
+ // On success data will automatically be accumulated into a string that
+ // can be retrieved with PipeReader::data(). To shutdown collection delete
+ // the instance and/or use PipeReader::OnDataReady(-1).
+ bool StartIO() {
+ // Use a pipe to collect data
+ const int status = HANDLE_EINTR(pipe(pipe_fd_));
+ if (status < 0) {
+ PLOG(ERROR) << "pipe";
+ return false;
+ }
+ base::PlatformFile data_file_ = pipe_fd_[0]; // read side
+ data_stream_.reset(new net::FileStream(data_file_,
+ base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
+ NULL));
+
+ // Post an initial async read to setup data collection
+ int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
+ base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
+ if (rv != net::ERR_IO_PENDING) {
+ LOG(ERROR) << "Unable to post initial read";
+ return false;
+ }
+ return true;
+ }
+
+ // Called when pipe data are available. Can also be used to shutdown
+ // data collection by passing -1 for |byte_count|.
+ void OnDataReady(int byte_count) {
+ DVLOG(1) << "OnDataReady byte_count " << byte_count;
+ if (byte_count <= 0) {
+ callback_.Run(); // signal creator to take data and delete us
+ return;
+ }
+ data_.append(io_buffer_->data(), byte_count);
+
+ // Post another read
+ int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
+ base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
+ if (rv != net::ERR_IO_PENDING) {
+ LOG(ERROR) << "Unable to post another read";
+ // TODO(sleffler) do something more intelligent?
+ }
+ }
+
+ private:
+ friend class base::RefCounted<PipeReader>;
+
+ int pipe_fd_[2];
+ scoped_ptr<net::FileStream> data_stream_;
+ scoped_refptr<net::IOBufferWithSize> io_buffer_;
+ base::WeakPtrFactory<PipeReader> weak_ptr_factory_;
+ std::string data_;
+ IOCompleteCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(PipeReader);
+};
+
+} // namespace
+
+namespace chromeos {
+
+// The DebugDaemonClient implementation used in production.
+class DebugDaemonClientImpl : public DebugDaemonClient {
+ public:
+ explicit DebugDaemonClientImpl(dbus::Bus* bus)
+ : debugdaemon_proxy_(NULL),
+ weak_ptr_factory_(this),
+ pipe_reader_(NULL) {
+ debugdaemon_proxy_ = bus->GetObjectProxy(
+ debugd::kDebugdServiceName,
+ dbus::ObjectPath(debugd::kDebugdServicePath));
+ }
+
+ virtual ~DebugDaemonClientImpl() {}
+
+ // DebugDaemonClient override.
+ virtual void StartSystemTracing() OVERRIDE {
+ dbus::MethodCall method_call(
+ debugd::kDebugdInterface,
+ debugd::kSystraceStart);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString("all"); // TODO(sleffler) parameterize category list
+
+ DVLOG(1) << "Requesting a systrace start";
+ debugdaemon_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
+ callback) OVERRIDE {
+ if (pipe_reader_ != NULL) {
+ LOG(ERROR) << "Busy doing StopSystemTracing";
+ return false;
+ }
+
+ pipe_reader_.reset(new PipeReader(
+ base::Bind(&DebugDaemonClientImpl::OnIOComplete,
+ weak_ptr_factory_.GetWeakPtr())));
+ int write_fd = -1;
+ if (!pipe_reader_->StartIO()) {
+ LOG(ERROR) << "Cannot create pipe reader";
+ // NB: continue anyway to shutdown tracing; toss trace data
+ write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
+ // TODO(sleffler) if this fails AppendFileDescriptor will abort
+ } else {
+ write_fd = pipe_reader_->GetWriteFD();
+ }
+
+ DCHECK(callback.is_null());
+ callback_ = callback;
+
+ // Issue the dbus request to stop system tracing
+ dbus::MethodCall method_call(
+ debugd::kDebugdInterface,
+ debugd::kSystraceStop);
+ dbus::MessageWriter writer(&method_call);
+ dbus::FileDescriptor temp(write_fd); // NB: explicit temp for C++98
+ writer.AppendFileDescriptor(temp);
+
+ DVLOG(1) << "Requesting a systrace stop";
+ debugdaemon_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ pipe_reader_->CloseWriteFD(); // close our copy of fd after send
+
+ return true;
+ }
+
+ private:
+ // Called when a response for StartSystemTracing() is received.
+ void OnStartSystemTracing(dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request systrace start";
+ return;
+ }
+ }
+
+ // Called when a response for RequestStopSystemTracing() is received.
+ void OnRequestStopSystemTracing(dbus::Response* response) {
+ if (!response) {
+ LOG(ERROR) << "Failed to request systrace stop";
+ pipe_reader_->OnDataReady(-1); // terminate data stream
+ }
+ // NB: requester is signaled when i/o completes
+ }
+
+ // Called when pipe i/o completes; pass data on and delete the instance.
+ void OnIOComplete() {
+ callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
+ pipe_reader_.reset();
+ }
+
+ dbus::ObjectProxy* debugdaemon_proxy_;
+ base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
+ scoped_ptr<PipeReader> pipe_reader_;
+ StopSystemTracingCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
+};
+
+// The DebugDaemonClient implementation used on Linux desktop,
+// which does nothing.
+class DebugDaemonClientStubImpl : public DebugDaemonClient {
+ // DebugDaemonClient overrides.
+ virtual void StartSystemTracing() OVERRIDE {}
+ virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
+ callback) OVERRIDE {
+ std::string no_data;
+ callback.Run(base::RefCountedString::TakeString(&no_data));
+ return true;
+ }
+};
+
+DebugDaemonClient::DebugDaemonClient() {
+}
+
+DebugDaemonClient::~DebugDaemonClient() {
+}
+
+// static
+DebugDaemonClient::StopSystemTracingCallback
+DebugDaemonClient::EmptyStopSystemTracingCallback() {
+ return base::Bind(&EmptyStopSystemTracingCallbackBody);
+}
+
+// static
+DebugDaemonClient* DebugDaemonClient::Create(DBusClientImplementationType type,
+ dbus::Bus* bus) {
+ if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
+ return new DebugDaemonClientImpl(bus);
+ DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
+ return new DebugDaemonClientStubImpl();
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/debug_daemon_client.h b/chrome/browser/chromeos/dbus/debug_daemon_client.h
new file mode 100644
index 0000000..843a059
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/debug_daemon_client.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_DEBUG_DAEMON_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_DEBUG_DAEMON_CLIENT_H_
+
+#include "base/callback.h"
+#include "base/memory/ref_counted_memory.h"
+#include "chrome/browser/chromeos/dbus/dbus_client_implementation_type.h"
+
+namespace dbus {
+class Bus;
+} // namespace dbus
+
+namespace chromeos {
+
+// DebugDaemonClient is used to communicate with the debug daemon.
+class DebugDaemonClient {
+ public:
+ virtual ~DebugDaemonClient();
+
+ // Requests to start system/kernel tracing.
+ virtual void StartSystemTracing() = 0;
+
+ // Called once RequestStopSystemTracing() is complete. Takes one parameter:
+ // - result: the data collected while tracing was active
+ typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&
+ result)> StopSystemTracingCallback;
+
+ // Requests to stop system tracing and calls |callback| when completed.
+ virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
+ callback) = 0;
+
+ // Returns an empty SystemTracingCallback that does nothing.
+ static StopSystemTracingCallback EmptyStopSystemTracingCallback();
+
+ // Factory function, creates a new instance and returns ownership.
+ // For normal usage, access the singleton via DBusThreadManager::Get().
+ static DebugDaemonClient* Create(DBusClientImplementationType type,
+ dbus::Bus* bus);
+ protected:
+ // Create() should be used instead.
+ DebugDaemonClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DebugDaemonClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_DEBUG_DAEMON_CLIENT_H_
diff --git a/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.cc b/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.cc
index 1e1a4c0..843bb4f 100644
--- a/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.cc
+++ b/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/chromeos/dbus/mock_cashew_client.h"
#include "chrome/browser/chromeos/dbus/mock_cros_disks_client.h"
#include "chrome/browser/chromeos/dbus/mock_cryptohome_client.h"
+#include "chrome/browser/chromeos/dbus/mock_debug_daemon_client.h"
#include "chrome/browser/chromeos/dbus/mock_flimflam_ipconfig_client.h"
#include "chrome/browser/chromeos/dbus/mock_flimflam_network_client.h"
#include "chrome/browser/chromeos/dbus/mock_flimflam_profile_client.h"
@@ -37,6 +38,7 @@ MockDBusThreadManager::MockDBusThreadManager()
mock_cashew_client_(new MockCashewClient),
mock_cros_disks_client_(new MockCrosDisksClient),
mock_cryptohome_client_(new MockCryptohomeClient),
+ mock_debugdaemon_client_(new MockDebugDaemonClient),
mock_flimflam_ipconfig_client_(new MockFlimflamIPConfigClient),
mock_flimflam_network_client_(new MockFlimflamNetworkClient),
mock_flimflam_profile_client_(new MockFlimflamProfileClient),
@@ -62,6 +64,8 @@ MockDBusThreadManager::MockDBusThreadManager()
.WillRepeatedly(Return(mock_cros_disks_client()));
EXPECT_CALL(*this, GetCryptohomeClient())
.WillRepeatedly(Return(mock_cryptohome_client()));
+ EXPECT_CALL(*this, GetDebugDaemonClient())
+ .WillRepeatedly(Return(mock_debugdaemon_client()));
EXPECT_CALL(*this, GetFlimflamIPConfigClient())
.WillRepeatedly(Return(mock_flimflam_ipconfig_client()));
EXPECT_CALL(*this, GetFlimflamNetworkClient())
diff --git a/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h b/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h
index 05ea0da..3402fcb 100644
--- a/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h
+++ b/chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h
@@ -26,6 +26,7 @@ class MockBluetoothNodeClient;
class MockCashewClient;
class MockCrosDisksClient;
class MockCryptohomeClient;
+class MockDebugDaemonClient;
class MockFlimflamIPConfigClient;
class MockFlimflamNetworkClient;
class MockFlimflamProfileClient;
@@ -53,6 +54,7 @@ class MockDBusThreadManager : public DBusThreadManager {
MOCK_METHOD0(GetCashewClient, CashewClient*(void));
MOCK_METHOD0(GetCrosDisksClient, CrosDisksClient*(void));
MOCK_METHOD0(GetCryptohomeClient, CryptohomeClient*(void));
+ MOCK_METHOD0(GetDebugDaemonClient, DebugDaemonClient*(void));
MOCK_METHOD0(GetFlimflamIPConfigClient, FlimflamIPConfigClient*(void));
MOCK_METHOD0(GetFlimflamNetworkClient, FlimflamNetworkClient*(void));
MOCK_METHOD0(GetFlimflamProfileClient, FlimflamProfileClient*(void));
@@ -87,6 +89,9 @@ class MockDBusThreadManager : public DBusThreadManager {
MockCryptohomeClient* mock_cryptohome_client() {
return mock_cryptohome_client_.get();
}
+ MockDebugDaemonClient* mock_debugdaemon_client() {
+ return mock_debugdaemon_client_.get();
+ }
MockFlimflamIPConfigClient* mock_flimflam_ipconfig_client() {
return mock_flimflam_ipconfig_client_.get();
}
@@ -124,6 +129,7 @@ class MockDBusThreadManager : public DBusThreadManager {
scoped_ptr<MockCashewClient> mock_cashew_client_;
scoped_ptr<MockCrosDisksClient> mock_cros_disks_client_;
scoped_ptr<MockCryptohomeClient> mock_cryptohome_client_;
+ scoped_ptr<MockDebugDaemonClient> mock_debugdaemon_client_;
scoped_ptr<MockFlimflamIPConfigClient> mock_flimflam_ipconfig_client_;
scoped_ptr<MockFlimflamNetworkClient> mock_flimflam_network_client_;
scoped_ptr<MockFlimflamProfileClient> mock_flimflam_profile_client_;
diff --git a/chrome/browser/chromeos/dbus/mock_debug_daemon_client.cc b/chrome/browser/chromeos/dbus/mock_debug_daemon_client.cc
new file mode 100644
index 0000000..4d1e5b6
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/mock_debug_daemon_client.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/mock_debug_daemon_client.h"
+
+namespace chromeos {
+
+MockDebugDaemonClient::MockDebugDaemonClient() {}
+
+MockDebugDaemonClient::~MockDebugDaemonClient() {}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/mock_debug_daemon_client.h b/chrome/browser/chromeos/dbus/mock_debug_daemon_client.h
new file mode 100644
index 0000000..9d825c3
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/mock_debug_daemon_client.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_MOCK_DEBUG_DAEMON_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_MOCK_DEBUG_DAEMON_CLIENT_H_
+
+#include "chrome/browser/chromeos/dbus/debug_daemon_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromeos {
+
+class MockDebugDaemonClient : public DebugDaemonClient {
+ public:
+ MockDebugDaemonClient();
+ virtual ~MockDebugDaemonClient();
+
+ MOCK_METHOD1(RequestStopSystemTracing,
+ bool(const StopSystemTracingCallback&));
+ MOCK_METHOD0(StartSystemTracing, void());
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DBUS_MOCK_DEBUG_DAEMON_CLIENT_H_