diff options
-rw-r--r-- | DEPS | 3 | ||||
-rw-r--r-- | chrome/browser/metrics/system_metrics.proto | 14 | ||||
-rw-r--r-- | chrome/browser/metrics/system_metrics_logger.h | 28 | ||||
-rw-r--r-- | chrome/browser/metrics/system_metrics_logger_impl.cc | 44 | ||||
-rw-r--r-- | chrome/browser/metrics/system_metrics_logger_impl.h | 31 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_overview_message_listener.cc | 24 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_overview_types.cc | 55 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_overview_types.h | 5 | ||||
-rw-r--r-- | chrome/chrome.gyp | 33 |
9 files changed, 237 insertions, 0 deletions
@@ -27,6 +27,9 @@ deps = { "src/third_party/icu38": "/trunk/deps/third_party/icu38@20192", + "src/third_party/protobuf/src": + "http://protobuf.googlecode.com/svn/trunk@154", + # TODO(mark): Remove once this has moved into depot_tools. "src/tools/gyp": "http://gyp.googlecode.com/svn/trunk@546", diff --git a/chrome/browser/metrics/system_metrics.proto b/chrome/browser/metrics/system_metrics.proto new file mode 100644 index 0000000..5118646 --- /dev/null +++ b/chrome/browser/metrics/system_metrics.proto @@ -0,0 +1,14 @@ +// Copyright (c) 2009 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. + +package chrome_os_pb; + +message SystemMetrics { + optional int32 boot_time_ms = 1; + optional int32 up_time_s = 2; + optional int32 keystroke_window_cycling_count = 3; + optional int32 overview_keystroke_count = 4; + optional int32 overview_exit_mouse_count = 5; + optional int32 overview_exit_keystroke_count = 6; +} diff --git a/chrome/browser/metrics/system_metrics_logger.h b/chrome/browser/metrics/system_metrics_logger.h new file mode 100644 index 0000000..83f94f6 --- /dev/null +++ b/chrome/browser/metrics/system_metrics_logger.h @@ -0,0 +1,28 @@ +// Copyright (c) 2009 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_METRICS_SYSTEM_METRICS_LOGGER_H_ +#define CHROME_BROWSER_METRICS_SYSTEM_METRICS_LOGGER_H_ + +#include "base/basictypes.h" + +class Profile; + +// This is the abstract base class for a simple class that wraps up some +// calls to chromium metrics logging helper functions. This design will +// allow for easy mocking in unit tests. + +class SystemMetricsLogger { + public: + SystemMetricsLogger() {} + virtual ~SystemMetricsLogger() {} + virtual void RecordOverviewKeystroke(Profile *profile) = 0; + virtual void RecordOverviewExitMouse(Profile *profile) = 0; + virtual void RecordOverviewExitKeystroke(Profile *profile) = 0; + virtual void RecordWindowCycleKeystroke(Profile *profile) = 0; + virtual void RecordBootTime(int64 time) = 0; + virtual void RecordUpTime(int64 time) = 0; +}; + +#endif // CHROME_BROWSER_METRICS_SYSTEM_METRICS_LOGGER_H_ diff --git a/chrome/browser/metrics/system_metrics_logger_impl.cc b/chrome/browser/metrics/system_metrics_logger_impl.cc new file mode 100644 index 0000000..b16fe5d --- /dev/null +++ b/chrome/browser/metrics/system_metrics_logger_impl.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2009 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/metrics/system_metrics_logger_impl.h" + +#include "base/basictypes.h" +#include "base/histogram.h" +#include "base/time.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/metrics/user_metrics.h" + +SystemMetricsLoggerImpl::SystemMetricsLoggerImpl() {} + +SystemMetricsLoggerImpl::~SystemMetricsLoggerImpl() {} + +void SystemMetricsLoggerImpl::RecordOverviewKeystroke(Profile *profile) { + UserMetrics::RecordAction(L"TabOverview_Keystroke", profile); +} + +void SystemMetricsLoggerImpl::RecordOverviewExitMouse(Profile *profile) { + UserMetrics::RecordAction(L"TabOverview_ExitMouse", profile); +} + +void SystemMetricsLoggerImpl::RecordOverviewExitKeystroke(Profile *profile) { + UserMetrics::RecordAction(L"TabOverview_ExitKeystroke", profile); +} + +void SystemMetricsLoggerImpl::RecordWindowCycleKeystroke(Profile *profile) { + UserMetrics::RecordAction(L"TabOverview_WindowCycleKeystroke", profile); +} + +void SystemMetricsLoggerImpl::RecordBootTime(int64 time) { + UMA_HISTOGRAM_CUSTOM_TIMES("ChromeOS.Boot Time", + base::TimeDelta::FromMilliseconds(time), + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMinutes(1), + 50); +} + +void SystemMetricsLoggerImpl::RecordUpTime(int64 time) { + UMA_HISTOGRAM_LONG_TIMES("ChromeOS.Uptime", + base::TimeDelta::FromSeconds(time)); +} diff --git a/chrome/browser/metrics/system_metrics_logger_impl.h b/chrome/browser/metrics/system_metrics_logger_impl.h new file mode 100644 index 0000000..8bcfc5b --- /dev/null +++ b/chrome/browser/metrics/system_metrics_logger_impl.h @@ -0,0 +1,31 @@ +// Copyright (c) 2009 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_METRICS_SYSTEM_METRICS_LOGGER_IMPL_H_ +#define CHROME_BROWSER_METRICS_SYSTEM_METRICS_LOGGER_IMPL_H_ + +#include "base/basictypes.h" +#include "chrome/browser/metrics/system_metrics_logger.h" + +class Profile; + +// Wraps calls to UserMetrics::RecordAction() and the appropriate +// version of the UMA_HISTOGRAM_*_TIMES macros, based on the metric +// being logged + +class SystemMetricsLoggerImpl : public SystemMetricsLogger { + public: + SystemMetricsLoggerImpl(); + ~SystemMetricsLoggerImpl(); + void RecordOverviewKeystroke(Profile *profile); + void RecordOverviewExitMouse(Profile *profile); + void RecordOverviewExitKeystroke(Profile *profile); + void RecordWindowCycleKeystroke(Profile *profile); + void RecordBootTime(int64 time); + void RecordUpTime(int64 time); + private: + DISALLOW_COPY_AND_ASSIGN(SystemMetricsLoggerImpl); +}; + +#endif // CHROME_BROWSER_METRICS_SYSTEM_METRICS_LOGGER_IMPL_H_ diff --git a/chrome/browser/views/tabs/tab_overview_message_listener.cc b/chrome/browser/views/tabs/tab_overview_message_listener.cc index a4a77d6..d0b6665 100644 --- a/chrome/browser/views/tabs/tab_overview_message_listener.cc +++ b/chrome/browser/views/tabs/tab_overview_message_listener.cc @@ -7,6 +7,8 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/gtk/browser_window_gtk.h" +#include "chrome/browser/metrics/system_metrics_logger_impl.h" +#include "chrome/browser/metrics/system_metrics.pb.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/views/new_browser_window_widget.h" #include "chrome/browser/views/tabs/tab_overview_controller.h" @@ -25,12 +27,34 @@ TabOverviewMessageListener* TabOverviewMessageListener::instance() { void TabOverviewMessageListener::WillProcessEvent(GdkEvent* event) { } +namespace { +void ProcessSystemMetricsString(const std::string& message) { + SystemMetricsLoggerImpl logger; + chrome_os_pb::SystemMetrics system_metrics; + if (!system_metrics.ParseFromString(message)) { + DLOG(ERROR) << "Could not parse system metrics protobuffer!"; + return; + } + // For now, boot time is the only metric we'll worry about. + if (system_metrics.has_boot_time_ms()) { + logger.RecordBootTime(system_metrics.boot_time_ms()); + } +} +} // namespace + void TabOverviewMessageListener::DidProcessEvent(GdkEvent* event) { if (event->type == GDK_CLIENT_EVENT) { TabOverviewTypes::Message message; GdkEventClient* client_event = reinterpret_cast<GdkEventClient*>(event); if (TabOverviewTypes::instance()->DecodeMessage(*client_event, &message)) ProcessMessage(message, client_event->window); + } else if (event->type == GDK_PROPERTY_NOTIFY) { + std::string message; + GdkEventProperty* client_event = reinterpret_cast<GdkEventProperty*>(event); + if (TabOverviewTypes::instance()->DecodeStringMessage(*client_event, + &message)) { + ProcessSystemMetricsString(message); + } } } diff --git a/chrome/browser/views/tabs/tab_overview_types.cc b/chrome/browser/views/tabs/tab_overview_types.cc index 28ab42c8..fac9926 100644 --- a/chrome/browser/views/tabs/tab_overview_types.cc +++ b/chrome/browser/views/tabs/tab_overview_types.cc @@ -49,6 +49,8 @@ static const AtomInfo kAtomInfos[] = { "WM_STATE" }, { TabOverviewTypes::ATOM_WM_TRANSIENT_FOR, "WM_TRANSIENT_FOR" }, + { TabOverviewTypes::ATOM_WM_SYSTEM_METRICS, + "WM_SYSTEM_METRICS" }, }; bool SetIntProperty(XID xid, Atom xatom, const std::vector<int>& values) { @@ -138,6 +140,59 @@ bool TabOverviewTypes::DecodeMessage(const GdkEventClient& event, return true; } +bool TabOverviewTypes::DecodeStringMessage(const GdkEventProperty& event, + std::string* msg) { + DCHECK(NULL != msg); + if (type_to_atom_[ATOM_WM_SYSTEM_METRICS] != + gdk_x11_atom_to_xatom(event.atom)) + return false; + + DLOG(WARNING) << "Got property change notification for system metrics."; + if (GDK_PROPERTY_DELETE == event.state) { + DLOG(WARNING) << "Ignoring delete EventPropertyNotification"; + return false; + } + + // We will be using DBus for this communication in the future, so I don't + // really worry right now that we could generate more than 1KB here. + // Also, I use "long" rather than int64 because that is what X expects. + long acceptable_bytes = 1024; + Atom actual_type; + int actual_format; + unsigned long num_items, bytes_left; + unsigned char *output; + if (Success != XGetWindowProperty(x11_util::GetXDisplay(), + GDK_WINDOW_XID(event.window), + type_to_atom_[ATOM_WM_SYSTEM_METRICS], + 0, + acceptable_bytes, + false, + AnyPropertyType, + &actual_type, + &actual_format, + &num_items, + &bytes_left, + &output)) { + DLOG(WARNING) << "Could not read system metrics property from X."; + return false; + } + if (actual_format == 0) { + DLOG(WARNING) << "System Metrics property not set."; + return false; + } + if (actual_format != 8) { + DLOG(WARNING) << "Message was not encoded as a string of bytes..."; + return false; + } + if (bytes_left != 0) { + DLOG(ERROR) << "We wanted all the bytes at once..."; + return false; + } + msg->assign(reinterpret_cast<char*>(output), num_items); + XFree(output); + return true; +} + TabOverviewTypes::TabOverviewTypes() { scoped_array<char*> names(new char*[kNumAtoms]); scoped_array<Atom> atoms(new Atom[kNumAtoms]); diff --git a/chrome/browser/views/tabs/tab_overview_types.h b/chrome/browser/views/tabs/tab_overview_types.h index 939ec34..b70a89d 100644 --- a/chrome/browser/views/tabs/tab_overview_types.h +++ b/chrome/browser/views/tabs/tab_overview_types.h @@ -32,6 +32,7 @@ class TabOverviewTypes { ATOM_WM_S0, ATOM_WM_STATE, ATOM_WM_TRANSIENT_FOR, + ATOM_WM_SYSTEM_METRICS, kNumAtoms, }; @@ -204,6 +205,10 @@ class TabOverviewTypes { // returned. If false is returned, |event| is not a valid Message. bool DecodeMessage(const GdkEventClient& event, Message* msg); + // If |event| is a valid StringMessage it is decoded into |msg| and true is + // returned. If false is returned, |event| is not a valid StringMessage. + bool DecodeStringMessage(const GdkEventProperty& event, std::string* msg); + private: friend struct DefaultSingletonTraits<TabOverviewTypes>; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 36ec4b6..a3ef1d2 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -2101,6 +2101,39 @@ ], }], ['chromeos==1',{ + 'dependencies': [ + '../third_party/protobuf/protobuf.gyp:protobuf', + '../third_party/protobuf/protobuf.gyp:protoc', + ], + 'actions': [ + { 'action_name': 'my_proto', + 'inputs': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + 'browser/metrics/system_metrics.proto', + ], + 'outputs': [ + '<(INTERMEDIATE_DIR)/chrome/browser/metrics/system_metrics.pb.cc', + '<(INTERMEDIATE_DIR)/chrome/browser/metrics/system_metrics.pb.h', + ], + 'dependencies': [ + '../third_party/protobuf/protobuf.gyp:protoc', + ], + 'action': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + 'browser/metrics/system_metrics.proto', + '--cpp_out=<(INTERMEDIATE_DIR)/chrome', + ], + }, + ], + 'sources': [ + '<(INTERMEDIATE_DIR)/chrome/browser/metrics/system_metrics.pb.cc', + 'browser/metrics/system_metrics_logger.h', + 'browser/metrics/system_metrics_logger_impl.cc', + 'browser/metrics/system_metrics_logger_impl.h', + ], + 'include_dirs': [ + '<(INTERMEDIATE_DIR)', + ], 'sources/': [ ['include', 'browser/views/new_browser_window_widget.cc'], ['include', 'browser/views/new_browser_window_widget.h'], |