Commit 06aaac23 authored by sky@chromium.org's avatar sky@chromium.org

http://codereview.chromium.org/147084

Implements unique client ID generation for Posix.

Client ID generation happens once-per-install of Chromium (...well, this is
mostly true, at least).  On Windows, the code currently uses some system library
code that generates a GUID.  We don't ACTUALLY need a GUID, something that's
quite random and in the same format will work.  Since we don't want to add a
dependency on libuuid for POSIX, I created a less-random-but-still-good-enough
version.

BUG=15418
TEST=none

Review URL: http://codereview.chromium.org/149343

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20184 0039d316-1c4b-4281-b951-d872f2087c98
parent 837be4ad
...@@ -166,6 +166,7 @@ ...@@ -166,6 +166,7 @@
#include "base/histogram.h" #include "base/histogram.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/platform_thread.h" #include "base/platform_thread.h"
#include "base/rand_util.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/task.h" #include "base/task.h"
#include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_model.h"
...@@ -762,16 +763,29 @@ std::string MetricsService::GenerateClientID() { ...@@ -762,16 +763,29 @@ std::string MetricsService::GenerateClientID() {
DCHECK(result == kGUIDSize); DCHECK(result == kGUIDSize);
return WideToUTF8(guid_string.substr(1, guid_string.length() - 2)); return WideToUTF8(guid_string.substr(1, guid_string.length() - 2));
#elif defined(LINUX2)
uint64 sixteen_bytes[2] = { base::RandUint64(), base::RandUint64() };
return RandomBytesToGUIDString(sixteen_bytes);
#else #else
// TODO(port): Implement for Mac and linux. // TODO(cmasone): enable the above for all OS_POSIX platforms once the
// Rather than actually implementing a random source, might this be a good // first-run dialog text is all up to date.
// time to implement http://code.google.com/p/chromium/issues/detail?id=2278
// ? I think so!
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return std::string(); return std::string();
#endif #endif
} }
#if defined(OS_POSIX)
// TODO(cmasone): Once we're comfortable this works, migrate Windows code to
// use this as well.
std::string MetricsService::RandomBytesToGUIDString(const uint64 bytes[2]) {
return StringPrintf("%08llX-%04llX-%04llX-%04llX-%012llX",
bytes[0] >> 32,
(bytes[0] >> 16) & 0x0000ffff,
bytes[0] & 0x0000ffff,
bytes[1] >> 48,
bytes[1] & 0x0000ffffffffffffULL);
}
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// State save methods // State save methods
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "chrome/browser/net/url_fetcher.h" #include "chrome/browser/net/url_fetcher.h"
#include "chrome/common/notification_registrar.h" #include "chrome/common/notification_registrar.h"
#include "webkit/glue/webplugin.h" #include "webkit/glue/webplugin.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
class BookmarkModel; class BookmarkModel;
class BookmarkNode; class BookmarkNode;
...@@ -160,6 +161,12 @@ class MetricsService : public NotificationObserver, ...@@ -160,6 +161,12 @@ class MetricsService : public NotificationObserver,
// Generates a new client ID to use to identify self to metrics server. // Generates a new client ID to use to identify self to metrics server.
static std::string GenerateClientID(); static std::string GenerateClientID();
#if defined(OS_POSIX)
// Generates a new client ID to use to identify self to metrics server,
// given 128 bits of randomness.
static std::string RandomBytesToGUIDString(const uint64 bytes[2]);
#endif
// Schedule the next save of LocalState information. This is called // Schedule the next save of LocalState information. This is called
// automatically by the task that performs each save to schedule the next one. // automatically by the task that performs each save to schedule the next one.
void ScheduleNextStateSave(); void ScheduleNextStateSave();
...@@ -475,6 +482,9 @@ class MetricsService : public NotificationObserver, ...@@ -475,6 +482,9 @@ class MetricsService : public NotificationObserver,
// Indicate that a timer for sending the next log has already been queued. // Indicate that a timer for sending the next log has already been queued.
bool timer_pending_; bool timer_pending_;
FRIEND_TEST(MetricsServiceTest, ClientIdGeneratesAllZeroes);
FRIEND_TEST(MetricsServiceTest, ClientIdGeneratesCorrectly);
FRIEND_TEST(MetricsServiceTest, ClientIdCorrectlyFormatted);
DISALLOW_COPY_AND_ASSIGN(MetricsService); DISALLOW_COPY_AND_ASSIGN(MetricsService);
}; };
......
// 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/metrics_service.h"
#include <string>
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_POSIX) && defined(LINUX2)
TEST(MetricsServiceTest, ClientIdGeneratesAllZeroes) {
uint64 bytes[] = { 0, 0 };
std::string clientid = MetricsService::RandomBytesToGUIDString(bytes);
EXPECT_EQ("00000000-0000-0000-0000-000000000000", clientid);
}
TEST(MetricsServiceTest, ClientIdGeneratesCorrectly) {
uint64 bytes[] = { 0x0123456789ABCDEFULL, 0xFEDCBA9876543210ULL };
std::string clientid = MetricsService::RandomBytesToGUIDString(bytes);
EXPECT_EQ("01234567-89AB-CDEF-FEDC-BA9876543210", clientid);
}
TEST(MetricsServiceTest, ClientIdCorrectlyFormatted) {
std::string clientid = MetricsService::GenerateClientID();
EXPECT_EQ(36U, clientid.length());
std::string hexchars = "0123456789ABCDEF";
for (uint32 i = 0; i < clientid.length(); i++) {
char current = clientid.at(i);
if (i == 8 || i == 13 || i == 18 || i == 23) {
EXPECT_EQ('-', current);
} else {
EXPECT_TRUE(std::string::npos != hexchars.find(current));
}
}
}
#endif
...@@ -3528,6 +3528,7 @@ ...@@ -3528,6 +3528,7 @@
'browser/meta_table_helper_unittest.cc', 'browser/meta_table_helper_unittest.cc',
'browser/metrics/metrics_log_unittest.cc', 'browser/metrics/metrics_log_unittest.cc',
'browser/metrics/metrics_response_unittest.cc', 'browser/metrics/metrics_response_unittest.cc',
'browser/metrics/metrics_service_unittest.cc',
'browser/net/chrome_url_request_context_unittest.cc', 'browser/net/chrome_url_request_context_unittest.cc',
'browser/net/dns_host_info_unittest.cc', 'browser/net/dns_host_info_unittest.cc',
'browser/net/dns_master_unittest.cc', 'browser/net/dns_master_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment