Add support for user actions to the metrics library and the metrics clients.
BUG=10696 TEST=unit tests, tested on the device through metrics_client and inspecting the uma-events file. Change-Id: Ie39dd8b5ab968c328993076369a4ba14cb7fcd81 Review URL: http://codereview.chromium.org/6094010
This commit is contained in:
parent
b9b05e6047
commit
ed82485c3b
|
@ -29,19 +29,9 @@ UMA. In order to use the library in a module, you need to do the following:
|
|||
<metrics/metrics_library.h> header file. The file is installed in
|
||||
$SYSROOT/usr/include/ when the metrics library is built and installed.
|
||||
|
||||
- The API includes two methods:
|
||||
|
||||
bool MetricsLibrary::SendToUMA(const std::string& name, int sample,
|
||||
int min, int max, int nbuckets)
|
||||
sends a sample for a regular (exponential) histogram.
|
||||
|
||||
bool MetricsLibrary::SendEnumToUMA(const std::string& name, int sample,
|
||||
int max)
|
||||
sends a sample for an enumeration (linear) histogram.
|
||||
|
||||
Before using these methods, a MetricsLibrary object needs to be constructed
|
||||
and initialized through its Init method. See the complete API documentation in
|
||||
metrics_library.h under src/platform/metrics/.
|
||||
- The API is documented in metrics_library.h under src/platform/metrics/. Before
|
||||
using the API methods, a MetricsLibrary object needs to be constructed and
|
||||
initialized through its Init method.
|
||||
|
||||
For more information on the C API see c_metrics_library.h.
|
||||
|
||||
|
@ -88,9 +78,9 @@ The Metrics Client: metrics_client
|
|||
================================================================================
|
||||
|
||||
metrics_client is a simple shell command-line utility for sending histogram
|
||||
samples. It's installed under /usr/bin on the target platform and uses
|
||||
libmetrics to send the data to Chrome. The utility is useful for generating
|
||||
metrics from shell scripts.
|
||||
samples and user actions. It's installed under /usr/bin on the target platform
|
||||
and uses libmetrics to send the data to Chrome. The utility is useful for
|
||||
generating metrics from shell scripts.
|
||||
|
||||
For usage information and command-line options, run "metrics_client" on the
|
||||
target platform or look for "Usage:" in metrics_client.cc.
|
||||
|
|
|
@ -43,6 +43,14 @@ extern "C" int CMetricsLibrarySendEnumToUMA(CMetricsLibrary handle,
|
|||
return lib->SendEnumToUMA(std::string(name), sample, max);
|
||||
}
|
||||
|
||||
extern "C" int CMetricsLibrarySendUserActionToUMA(CMetricsLibrary handle,
|
||||
const char* action) {
|
||||
MetricsLibrary* lib = reinterpret_cast<MetricsLibrary*>(handle);
|
||||
if (lib == NULL)
|
||||
return 0;
|
||||
return lib->SendUserActionToUMA(std::string(action));
|
||||
}
|
||||
|
||||
extern "C" int CMetricsLibraryAreMetricsEnabled(CMetricsLibrary handle) {
|
||||
MetricsLibrary* lib = reinterpret_cast<MetricsLibrary*>(handle);
|
||||
if (lib == NULL)
|
||||
|
|
|
@ -28,6 +28,10 @@ int CMetricsLibrarySendToUMA(CMetricsLibrary handle,
|
|||
int CMetricsLibrarySendEnumToUMA(CMetricsLibrary handle,
|
||||
const char* name, int sample, int max);
|
||||
|
||||
// C wrapper for MetricsLibrary::SendUserActionToUMA.
|
||||
int CMetricsLibrarySendUserActionToUMA(CMetricsLibrary handle,
|
||||
const char* action);
|
||||
|
||||
// C wrapper for MetricsLibrary::AreMetricsEnabled.
|
||||
int CMetricsLibraryAreMetricsEnabled(CMetricsLibrary handle);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ void ShowUsage() {
|
|||
fprintf(stderr,
|
||||
"Usage: metrics_client [-ab] [-t] name sample min max nbuckets\n"
|
||||
" metrics_client [-ab] -e name sample max\n"
|
||||
" metrics_client -u action\n"
|
||||
" metrics_client [-cg]\n"
|
||||
"\n"
|
||||
" default: send metric with integer values to Chrome only\n"
|
||||
|
@ -20,7 +21,8 @@ void ShowUsage() {
|
|||
" -c: return exit status 0 if user consents to stats, 1 otherwise\n"
|
||||
" -e: send linear/enumeration histogram data\n"
|
||||
" -g: return exit status 0 if machine in guest mode, 1 otherwise\n"
|
||||
" -t: convert sample from double seconds to int milliseconds\n");
|
||||
" -t: convert sample from double seconds to int milliseconds\n"
|
||||
" -u: send a user action to Chrome\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -59,6 +61,14 @@ static int SendStats(char* argv[],
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int SendUserAction(char* argv[], int action_index) {
|
||||
const char* action = argv[action_index];
|
||||
MetricsLibrary metrics_lib;
|
||||
metrics_lib.Init();
|
||||
metrics_lib.SendUserActionToUMA(action);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HasConsent() {
|
||||
MetricsLibrary metrics_lib;
|
||||
metrics_lib.Init();
|
||||
|
@ -74,6 +84,7 @@ static int IsGuestMode() {
|
|||
int main(int argc, char** argv) {
|
||||
enum Mode {
|
||||
kModeSendStats,
|
||||
kModeSendUserAction,
|
||||
kModeHasConsent,
|
||||
kModeIsGuestMode
|
||||
} mode = kModeSendStats;
|
||||
|
@ -85,7 +96,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
// Parse arguments
|
||||
int flag;
|
||||
while ((flag = getopt(argc, argv, "abcegt")) != -1) {
|
||||
while ((flag = getopt(argc, argv, "abcegtu")) != -1) {
|
||||
switch (flag) {
|
||||
case 'a':
|
||||
mode = kModeSendStats;
|
||||
|
@ -109,18 +120,23 @@ int main(int argc, char** argv) {
|
|||
case 't':
|
||||
secs_to_msecs = true;
|
||||
break;
|
||||
case 'u':
|
||||
mode = kModeSendUserAction;
|
||||
break;
|
||||
default:
|
||||
print_usage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int name_index = optind;
|
||||
int arg_index = optind;
|
||||
|
||||
int expected_args = 0;
|
||||
if (mode == kModeSendStats)
|
||||
expected_args = send_enum ? 3 : 5;
|
||||
else if (mode == kModeSendUserAction)
|
||||
expected_args = 1;
|
||||
|
||||
if ((name_index + expected_args) != argc) {
|
||||
if ((arg_index + expected_args) != argc) {
|
||||
ShowUsage();
|
||||
}
|
||||
|
||||
|
@ -130,11 +146,13 @@ int main(int argc, char** argv) {
|
|||
ShowUsage();
|
||||
}
|
||||
return SendStats(argv,
|
||||
name_index,
|
||||
arg_index,
|
||||
send_enum,
|
||||
secs_to_msecs,
|
||||
send_to_autotest,
|
||||
send_to_chrome);
|
||||
case kModeSendUserAction:
|
||||
return SendUserAction(argv, arg_index);
|
||||
case kModeHasConsent:
|
||||
return HasConsent();
|
||||
case kModeIsGuestMode:
|
||||
|
|
|
@ -221,7 +221,6 @@ bool MetricsLibrary::SendToUMA(const string& name, int sample,
|
|||
FormatChromeMessage(kBufferSize, message,
|
||||
"histogram%c%s %d %d %d %d", '\0',
|
||||
name.c_str(), sample, min, max, nbuckets);
|
||||
|
||||
if (message_length < 0)
|
||||
return false;
|
||||
|
||||
|
@ -237,7 +236,19 @@ bool MetricsLibrary::SendEnumToUMA(const std::string& name, int sample,
|
|||
FormatChromeMessage(kBufferSize, message,
|
||||
"linearhistogram%c%s %d %d", '\0',
|
||||
name.c_str(), sample, max);
|
||||
|
||||
if (message_length < 0)
|
||||
return false;
|
||||
|
||||
// Send the message.
|
||||
return SendMessageToChrome(message_length, message);
|
||||
}
|
||||
|
||||
bool MetricsLibrary::SendUserActionToUMA(const std::string& action) {
|
||||
// Format the message.
|
||||
char message[kBufferSize];
|
||||
int32_t message_length =
|
||||
FormatChromeMessage(kBufferSize, message,
|
||||
"useraction%c%s", '\0', action.c_str());
|
||||
if (message_length < 0)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -69,6 +69,15 @@ class MetricsLibrary : public MetricsLibraryInterface {
|
|||
// normal, while 100 is high).
|
||||
bool SendEnumToUMA(const std::string& name, int sample, int max);
|
||||
|
||||
// Sends a user action to Chrome for transport to UMA and returns true on
|
||||
// success. This method results in the equivalent of an asynchronous
|
||||
// non-blocking RPC to UserMetrics::RecordAction (see the comments in
|
||||
// chrome/browser/chromeos/external_metrics.cc and
|
||||
// chrome/browser/metrics/user_metrics.h on how to register new user actions).
|
||||
//
|
||||
// |action| is the user-generated event (e.g., "MuteKeyPressed").
|
||||
bool SendUserActionToUMA(const std::string& action);
|
||||
|
||||
// Sends to Autotest and returns true on success.
|
||||
static bool SendToAutotest(const std::string& name, int value);
|
||||
|
||||
|
|
|
@ -214,6 +214,23 @@ TEST_F(MetricsLibraryTest, SendToUMANotEnabled) {
|
|||
EXPECT_FALSE(file_util::PathExists(kTestUMAEventsFile));
|
||||
}
|
||||
|
||||
TEST_F(MetricsLibraryTest, SendUserActionToUMA) {
|
||||
char buf[100];
|
||||
const int kLen = 30;
|
||||
EXPECT_TRUE(lib_.SendUserActionToUMA("SomeKeyPressed"));
|
||||
EXPECT_EQ(kLen, file_util::ReadFile(kTestUMAEventsFile, buf, 100));
|
||||
|
||||
char exp[kLen];
|
||||
sprintf(exp, "%c%c%c%cuseraction%cSomeKeyPressed", kLen, 0, 0, 0, 0);
|
||||
EXPECT_EQ(0, memcmp(exp, buf, kLen));
|
||||
}
|
||||
|
||||
TEST_F(MetricsLibraryTest, SendUserActionToUMANotEnabled) {
|
||||
SetMetricsEnabled(false);
|
||||
EXPECT_TRUE(lib_.SendUserActionToUMA("SomeOtherKeyPressed"));
|
||||
EXPECT_FALSE(file_util::PathExists(kTestUMAEventsFile));
|
||||
}
|
||||
|
||||
class CMetricsLibraryTest : public testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
|
@ -268,6 +285,17 @@ TEST_F(CMetricsLibraryTest, SendToUMA) {
|
|||
EXPECT_EQ(0, memcmp(exp, buf, kLen));
|
||||
}
|
||||
|
||||
TEST_F(CMetricsLibraryTest, SendUserActionToUMA) {
|
||||
char buf[100];
|
||||
const int kLen = 30;
|
||||
EXPECT_TRUE(CMetricsLibrarySendUserActionToUMA(lib_, "SomeKeyPressed"));
|
||||
EXPECT_EQ(kLen, file_util::ReadFile(kTestUMAEventsFile, buf, 100));
|
||||
|
||||
char exp[kLen];
|
||||
sprintf(exp, "%c%c%c%cuseraction%cSomeKeyPressed", kLen, 0, 0, 0, 0);
|
||||
EXPECT_EQ(0, memcmp(exp, buf, kLen));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
|
Loading…
Reference in New Issue