| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 //------------------------------------------------------------------------------ | 5 //------------------------------------------------------------------------------ |
| 6 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
| 7 // | 7 // |
| 8 // OVERVIEW | 8 // OVERVIEW |
| 9 // | 9 // |
| 10 // A MetricsService instance is typically created at application startup. It is | 10 // A MetricsService instance is typically created at application startup. It is |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // | 161 // |
| 162 //------------------------------------------------------------------------------ | 162 //------------------------------------------------------------------------------ |
| 163 | 163 |
| 164 #include "chrome/browser/metrics/metrics_service.h" | 164 #include "chrome/browser/metrics/metrics_service.h" |
| 165 | 165 |
| 166 #include <algorithm> | 166 #include <algorithm> |
| 167 | 167 |
| 168 #include "base/bind.h" | 168 #include "base/bind.h" |
| 169 #include "base/callback.h" | 169 #include "base/callback.h" |
| 170 #include "base/command_line.h" | 170 #include "base/command_line.h" |
| 171 #include "base/guid.h" |
| 171 #include "base/metrics/histogram.h" | 172 #include "base/metrics/histogram.h" |
| 172 #include "base/metrics/sparse_histogram.h" | 173 #include "base/metrics/sparse_histogram.h" |
| 173 #include "base/metrics/statistics_recorder.h" | 174 #include "base/metrics/statistics_recorder.h" |
| 174 #include "base/prefs/pref_registry_simple.h" | 175 #include "base/prefs/pref_registry_simple.h" |
| 175 #include "base/prefs/pref_service.h" | 176 #include "base/prefs/pref_service.h" |
| 176 #include "base/prefs/scoped_user_pref_update.h" | 177 #include "base/prefs/scoped_user_pref_update.h" |
| 178 #include "base/rand_util.h" |
| 177 #include "base/strings/string_number_conversions.h" | 179 #include "base/strings/string_number_conversions.h" |
| 178 #include "base/strings/utf_string_conversions.h" | 180 #include "base/strings/utf_string_conversions.h" |
| 179 #include "base/threading/platform_thread.h" | 181 #include "base/threading/platform_thread.h" |
| 180 #include "base/threading/thread.h" | 182 #include "base/threading/thread.h" |
| 181 #include "base/threading/thread_restrictions.h" | 183 #include "base/threading/thread_restrictions.h" |
| 182 #include "base/tracked_objects.h" | 184 #include "base/tracked_objects.h" |
| 183 #include "base/values.h" | 185 #include "base/values.h" |
| 184 #include "chrome/browser/browser_process.h" | 186 #include "chrome/browser/browser_process.h" |
| 185 #include "chrome/browser/chrome_notification_types.h" | 187 #include "chrome/browser/chrome_notification_types.h" |
| 186 #include "chrome/browser/io_thread.h" | 188 #include "chrome/browser/io_thread.h" |
| 187 #include "chrome/browser/memory_details.h" | 189 #include "chrome/browser/memory_details.h" |
| 190 #include "chrome/browser/metrics/cloned_install_detector.h" |
| 188 #include "chrome/browser/metrics/compression_utils.h" | 191 #include "chrome/browser/metrics/compression_utils.h" |
| 192 #include "chrome/browser/metrics/machine_id_provider.h" |
| 189 #include "chrome/browser/metrics/metrics_log.h" | 193 #include "chrome/browser/metrics/metrics_log.h" |
| 190 #include "chrome/browser/metrics/metrics_log_serializer.h" | 194 #include "chrome/browser/metrics/metrics_log_serializer.h" |
| 191 #include "chrome/browser/metrics/metrics_reporting_scheduler.h" | 195 #include "chrome/browser/metrics/metrics_reporting_scheduler.h" |
| 192 #include "chrome/browser/metrics/metrics_state_manager.h" | |
| 193 #include "chrome/browser/metrics/time_ticks_experiment_win.h" | 196 #include "chrome/browser/metrics/time_ticks_experiment_win.h" |
| 194 #include "chrome/browser/metrics/tracking_synchronizer.h" | 197 #include "chrome/browser/metrics/tracking_synchronizer.h" |
| 195 #include "chrome/common/metrics/variations/variations_util.h" | 198 #include "chrome/common/metrics/variations/variations_util.h" |
| 196 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | 199 #include "chrome/browser/net/http_pipelining_compatibility_client.h" |
| 197 #include "chrome/browser/net/network_stats.h" | 200 #include "chrome/browser/net/network_stats.h" |
| 198 #include "chrome/browser/omnibox/omnibox_log.h" | 201 #include "chrome/browser/omnibox/omnibox_log.h" |
| 199 #include "chrome/browser/ui/browser_list.h" | 202 #include "chrome/browser/ui/browser_list.h" |
| 200 #include "chrome/browser/ui/browser_otr_state.h" | 203 #include "chrome/browser/ui/browser_otr_state.h" |
| 201 #include "chrome/browser/ui/search/search_tab_helper.h" | 204 #include "chrome/browser/ui/search/search_tab_helper.h" |
| 202 #include "chrome/common/chrome_constants.h" | 205 #include "chrome/common/chrome_constants.h" |
| 203 #include "chrome/common/chrome_result_codes.h" | 206 #include "chrome/common/chrome_result_codes.h" |
| 204 #include "chrome/common/chrome_switches.h" | 207 #include "chrome/common/chrome_switches.h" |
| 205 #include "chrome/common/crash_keys.h" | 208 #include "chrome/common/crash_keys.h" |
| 209 #include "chrome/common/metrics/caching_permuted_entropy_provider.h" |
| 206 #include "chrome/common/net/test_server_locations.h" | 210 #include "chrome/common/net/test_server_locations.h" |
| 207 #include "chrome/common/pref_names.h" | 211 #include "chrome/common/pref_names.h" |
| 208 #include "chrome/common/render_messages.h" | 212 #include "chrome/common/render_messages.h" |
| 209 #include "components/metrics/metrics_log_manager.h" | 213 #include "components/metrics/metrics_log_manager.h" |
| 210 #include "components/variations/entropy_provider.h" | 214 #include "components/variations/entropy_provider.h" |
| 211 #include "components/variations/metrics_util.h" | 215 #include "components/variations/metrics_util.h" |
| 212 #include "content/public/browser/child_process_data.h" | 216 #include "content/public/browser/child_process_data.h" |
| 213 #include "content/public/browser/histogram_fetcher.h" | 217 #include "content/public/browser/histogram_fetcher.h" |
| 214 #include "content/public/browser/load_notification_details.h" | 218 #include "content/public/browser/load_notification_details.h" |
| 215 #include "content/public/browser/notification_service.h" | 219 #include "content/public/browser/notification_service.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 return SUCCESS; | 306 return SUCCESS; |
| 303 case 400: | 307 case 400: |
| 304 return BAD_REQUEST; | 308 return BAD_REQUEST; |
| 305 case net::URLFetcher::RESPONSE_CODE_INVALID: | 309 case net::URLFetcher::RESPONSE_CODE_INVALID: |
| 306 return NO_RESPONSE; | 310 return NO_RESPONSE; |
| 307 default: | 311 default: |
| 308 return UNKNOWN_FAILURE; | 312 return UNKNOWN_FAILURE; |
| 309 } | 313 } |
| 310 } | 314 } |
| 311 | 315 |
| 316 // The argument used to generate a non-identifying entropy source. We want no |
| 317 // more than 13 bits of entropy, so use this max to return a number in the range |
| 318 // [0, 7999] as the entropy source (12.97 bits of entropy). |
| 319 const int kMaxLowEntropySize = 8000; |
| 320 |
| 321 // Default prefs value for prefs::kMetricsLowEntropySource to indicate that the |
| 322 // value has not yet been set. |
| 323 const int kLowEntropySourceNotSet = -1; |
| 324 |
| 325 // Generates a new non-identifying entropy source used to seed persistent |
| 326 // activities. |
| 327 int GenerateLowEntropySource() { |
| 328 return base::RandInt(0, kMaxLowEntropySize - 1); |
| 329 } |
| 330 |
| 312 // Converts an exit code into something that can be inserted into our | 331 // Converts an exit code into something that can be inserted into our |
| 313 // histograms (which expect non-negative numbers less than MAX_INT). | 332 // histograms (which expect non-negative numbers less than MAX_INT). |
| 314 int MapCrashExitCodeForHistogram(int exit_code) { | 333 int MapCrashExitCodeForHistogram(int exit_code) { |
| 315 #if defined(OS_WIN) | 334 #if defined(OS_WIN) |
| 316 // Since |abs(STATUS_GUARD_PAGE_VIOLATION) == MAX_INT| it causes problems in | 335 // Since |abs(STATUS_GUARD_PAGE_VIOLATION) == MAX_INT| it causes problems in |
| 317 // histograms.cc. Solve this by remapping it to a smaller value, which | 336 // histograms.cc. Solve this by remapping it to a smaller value, which |
| 318 // hopefully doesn't conflict with other codes. | 337 // hopefully doesn't conflict with other codes. |
| 319 if (exit_code == STATUS_GUARD_PAGE_VIOLATION) | 338 if (exit_code == STATUS_GUARD_PAGE_VIOLATION) |
| 320 return 0x1FCF7EC3; // Randomly picked number. | 339 return 0x1FCF7EC3; // Randomly picked number. |
| 321 #endif | 340 #endif |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 private: | 423 private: |
| 405 virtual ~MetricsMemoryDetails() {} | 424 virtual ~MetricsMemoryDetails() {} |
| 406 | 425 |
| 407 base::Closure callback_; | 426 base::Closure callback_; |
| 408 DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails); | 427 DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails); |
| 409 }; | 428 }; |
| 410 | 429 |
| 411 // static | 430 // static |
| 412 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { | 431 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { |
| 413 DCHECK(IsSingleThreaded()); | 432 DCHECK(IsSingleThreaded()); |
| 414 metrics::MetricsStateManager::RegisterPrefs(registry); | 433 registry->RegisterBooleanPref(prefs::kMetricsResetIds, false); |
| 415 | 434 registry->RegisterStringPref(prefs::kMetricsClientID, std::string()); |
| 435 registry->RegisterInt64Pref(prefs::kMetricsReportingEnabledTimestamp, 0); |
| 436 registry->RegisterIntegerPref(prefs::kMetricsLowEntropySource, |
| 437 kLowEntropySourceNotSet); |
| 416 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); | 438 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); |
| 417 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); | 439 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); |
| 418 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); | 440 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); |
| 419 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); | 441 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); |
| 420 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); | 442 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); |
| 421 registry->RegisterIntegerPref(prefs::kStabilityExecutionPhase, | 443 registry->RegisterIntegerPref(prefs::kStabilityExecutionPhase, |
| 422 UNINITIALIZED_PHASE); | 444 UNINITIALIZED_PHASE); |
| 423 registry->RegisterBooleanPref(prefs::kStabilitySessionEndCompleted, true); | 445 registry->RegisterBooleanPref(prefs::kStabilitySessionEndCompleted, true); |
| 424 registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1); | 446 registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1); |
| 425 registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0); | 447 registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 450 registry->RegisterListPref(prefs::kMetricsInitialLogs); | 472 registry->RegisterListPref(prefs::kMetricsInitialLogs); |
| 451 registry->RegisterListPref(prefs::kMetricsOngoingLogs); | 473 registry->RegisterListPref(prefs::kMetricsOngoingLogs); |
| 452 | 474 |
| 453 registry->RegisterInt64Pref(prefs::kInstallDate, 0); | 475 registry->RegisterInt64Pref(prefs::kInstallDate, 0); |
| 454 registry->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0); | 476 registry->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0); |
| 455 registry->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0); | 477 registry->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0); |
| 456 registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0); | 478 registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0); |
| 457 registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0); | 479 registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0); |
| 458 registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0); | 480 registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0); |
| 459 | 481 |
| 482 // TODO(asvitkine): Remove these once a couple of releases have passed. |
| 483 // http://crbug.com/357704 |
| 484 registry->RegisterStringPref(prefs::kMetricsOldClientID, std::string()); |
| 485 registry->RegisterIntegerPref(prefs::kMetricsOldLowEntropySource, 0); |
| 486 |
| 460 #if defined(OS_ANDROID) | 487 #if defined(OS_ANDROID) |
| 461 RegisterPrefsAndroid(registry); | 488 RegisterPrefsAndroid(registry); |
| 462 #endif // defined(OS_ANDROID) | 489 #endif // defined(OS_ANDROID) |
| 463 } | 490 } |
| 464 | 491 |
| 465 MetricsService::MetricsService() | 492 MetricsService::MetricsService() |
| 466 : state_manager_(metrics::MetricsStateManager::Create( | 493 : metrics_ids_reset_check_performed_(false), |
| 467 g_browser_process->local_state())), | |
| 468 recording_active_(false), | 494 recording_active_(false), |
| 469 reporting_active_(false), | 495 reporting_active_(false), |
| 470 test_mode_active_(false), | 496 test_mode_active_(false), |
| 471 state_(INITIALIZED), | 497 state_(INITIALIZED), |
| 472 has_initial_stability_log_(false), | 498 has_initial_stability_log_(false), |
| 499 low_entropy_source_(kLowEntropySourceNotSet), |
| 473 idle_since_last_transmission_(false), | 500 idle_since_last_transmission_(false), |
| 474 session_id_(-1), | 501 session_id_(-1), |
| 475 next_window_id_(0), | 502 next_window_id_(0), |
| 476 self_ptr_factory_(this), | 503 self_ptr_factory_(this), |
| 477 state_saver_factory_(this), | 504 state_saver_factory_(this), |
| 478 waiting_for_asynchronous_reporting_step_(false), | 505 waiting_for_asynchronous_reporting_step_(false), |
| 479 num_async_histogram_fetches_in_progress_(0) { | 506 num_async_histogram_fetches_in_progress_(0), |
| 507 entropy_source_returned_(LAST_ENTROPY_NONE) { |
| 480 DCHECK(IsSingleThreaded()); | 508 DCHECK(IsSingleThreaded()); |
| 481 DCHECK(state_manager_); | |
| 482 | 509 |
| 483 log_manager_.set_log_serializer(new MetricsLogSerializer); | 510 log_manager_.set_log_serializer(new MetricsLogSerializer); |
| 484 log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize); | 511 log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize); |
| 485 | 512 |
| 486 BrowserChildProcessObserver::Add(this); | 513 BrowserChildProcessObserver::Add(this); |
| 487 } | 514 } |
| 488 | 515 |
| 489 MetricsService::~MetricsService() { | 516 MetricsService::~MetricsService() { |
| 490 DisableRecording(); | 517 DisableRecording(); |
| 491 | 518 |
| 492 BrowserChildProcessObserver::Remove(this); | 519 BrowserChildProcessObserver::Remove(this); |
| 493 } | 520 } |
| 494 | 521 |
| 495 void MetricsService::InitializeMetricsRecordingState() { | 522 void MetricsService::InitializeMetricsRecordingState( |
| 496 InitializeMetricsState(); | 523 ReportingState reporting_state) { |
| 524 InitializeMetricsState(reporting_state); |
| 497 | 525 |
| 498 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, | 526 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, |
| 499 self_ptr_factory_.GetWeakPtr()); | 527 self_ptr_factory_.GetWeakPtr()); |
| 500 scheduler_.reset(new MetricsReportingScheduler(callback)); | 528 scheduler_.reset(new MetricsReportingScheduler(callback)); |
| 501 } | 529 } |
| 502 | 530 |
| 503 void MetricsService::Start() { | 531 void MetricsService::Start() { |
| 504 HandleIdleSinceLastTransmission(false); | 532 HandleIdleSinceLastTransmission(false); |
| 505 EnableRecording(); | 533 EnableRecording(); |
| 506 EnableReporting(); | 534 EnableReporting(); |
| 507 } | 535 } |
| 508 | 536 |
| 509 bool MetricsService::StartIfMetricsReportingEnabled() { | |
| 510 const bool enabled = state_manager_->IsMetricsReportingEnabled(); | |
| 511 if (enabled) | |
| 512 Start(); | |
| 513 return enabled; | |
| 514 } | |
| 515 | |
| 516 void MetricsService::StartRecordingForTests() { | 537 void MetricsService::StartRecordingForTests() { |
| 517 test_mode_active_ = true; | 538 test_mode_active_ = true; |
| 518 EnableRecording(); | 539 EnableRecording(); |
| 519 DisableReporting(); | 540 DisableReporting(); |
| 520 } | 541 } |
| 521 | 542 |
| 522 void MetricsService::Stop() { | 543 void MetricsService::Stop() { |
| 523 HandleIdleSinceLastTransmission(false); | 544 HandleIdleSinceLastTransmission(false); |
| 524 DisableReporting(); | 545 DisableReporting(); |
| 525 DisableRecording(); | 546 DisableRecording(); |
| 526 } | 547 } |
| 527 | 548 |
| 528 void MetricsService::EnableReporting() { | 549 void MetricsService::EnableReporting() { |
| 529 if (reporting_active_) | 550 if (reporting_active_) |
| 530 return; | 551 return; |
| 531 reporting_active_ = true; | 552 reporting_active_ = true; |
| 532 StartSchedulerIfNecessary(); | 553 StartSchedulerIfNecessary(); |
| 533 } | 554 } |
| 534 | 555 |
| 535 void MetricsService::DisableReporting() { | 556 void MetricsService::DisableReporting() { |
| 536 reporting_active_ = false; | 557 reporting_active_ = false; |
| 537 } | 558 } |
| 538 | 559 |
| 539 std::string MetricsService::GetClientId() { | 560 std::string MetricsService::GetClientId() { |
| 540 return state_manager_->client_id(); | 561 return client_id_; |
| 541 } | 562 } |
| 542 | 563 |
| 543 scoped_ptr<const base::FieldTrial::EntropyProvider> | 564 scoped_ptr<const base::FieldTrial::EntropyProvider> |
| 544 MetricsService::CreateEntropyProvider() { | 565 MetricsService::CreateEntropyProvider(ReportingState reporting_state) { |
| 545 // TODO(asvitkine): Refactor the code so that MetricsService does not expose | 566 // For metrics reporting-enabled users, we combine the client ID and low |
| 546 // this method. | 567 // entropy source to get the final entropy source. Otherwise, only use the low |
| 547 return state_manager_->CreateEntropyProvider(); | 568 // entropy source. |
| 569 // This has two useful properties: |
| 570 // 1) It makes the entropy source less identifiable for parties that do not |
| 571 // know the low entropy source. |
| 572 // 2) It makes the final entropy source resettable. |
| 573 const int low_entropy_source_value = GetLowEntropySource(); |
| 574 UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue", |
| 575 low_entropy_source_value); |
| 576 if (reporting_state == REPORTING_ENABLED) { |
| 577 if (entropy_source_returned_ == LAST_ENTROPY_NONE) |
| 578 entropy_source_returned_ = LAST_ENTROPY_HIGH; |
| 579 DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_); |
| 580 const std::string high_entropy_source = |
| 581 client_id_ + base::IntToString(low_entropy_source_value); |
| 582 return scoped_ptr<const base::FieldTrial::EntropyProvider>( |
| 583 new metrics::SHA1EntropyProvider(high_entropy_source)); |
| 584 } |
| 585 |
| 586 if (entropy_source_returned_ == LAST_ENTROPY_NONE) |
| 587 entropy_source_returned_ = LAST_ENTROPY_LOW; |
| 588 DCHECK_EQ(LAST_ENTROPY_LOW, entropy_source_returned_); |
| 589 |
| 590 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 591 return scoped_ptr<const base::FieldTrial::EntropyProvider>( |
| 592 new metrics::CachingPermutedEntropyProvider( |
| 593 g_browser_process->local_state(), |
| 594 low_entropy_source_value, |
| 595 kMaxLowEntropySize)); |
| 596 #else |
| 597 return scoped_ptr<const base::FieldTrial::EntropyProvider>( |
| 598 new metrics::PermutedEntropyProvider(low_entropy_source_value, |
| 599 kMaxLowEntropySize)); |
| 600 #endif |
| 601 } |
| 602 |
| 603 void MetricsService::ForceClientIdCreation() { |
| 604 if (!client_id_.empty()) |
| 605 return; |
| 606 |
| 607 ResetMetricsIDsIfNecessary(); |
| 608 |
| 609 PrefService* pref = g_browser_process->local_state(); |
| 610 client_id_ = pref->GetString(prefs::kMetricsClientID); |
| 611 if (!client_id_.empty()) |
| 612 return; |
| 613 |
| 614 client_id_ = GenerateClientID(); |
| 615 pref->SetString(prefs::kMetricsClientID, client_id_); |
| 616 |
| 617 if (pref->GetString(prefs::kMetricsOldClientID).empty()) { |
| 618 // Record the timestamp of when the user opted in to UMA. |
| 619 pref->SetInt64(prefs::kMetricsReportingEnabledTimestamp, |
| 620 Time::Now().ToTimeT()); |
| 621 } else { |
| 622 UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdMigrated", true); |
| 623 } |
| 624 pref->ClearPref(prefs::kMetricsOldClientID); |
| 548 } | 625 } |
| 549 | 626 |
| 550 void MetricsService::EnableRecording() { | 627 void MetricsService::EnableRecording() { |
| 551 DCHECK(IsSingleThreaded()); | 628 DCHECK(IsSingleThreaded()); |
| 552 | 629 |
| 553 if (recording_active_) | 630 if (recording_active_) |
| 554 return; | 631 return; |
| 555 recording_active_ = true; | 632 recording_active_ = true; |
| 556 | 633 |
| 557 state_manager_->ForceClientIdCreation(); | 634 ForceClientIdCreation(); |
| 558 crash_keys::SetClientID(state_manager_->client_id()); | 635 crash_keys::SetClientID(client_id_); |
| 559 if (!log_manager_.current_log()) | 636 if (!log_manager_.current_log()) |
| 560 OpenNewLog(); | 637 OpenNewLog(); |
| 561 | 638 |
| 562 SetUpNotifications(®istrar_, this); | 639 SetUpNotifications(®istrar_, this); |
| 563 base::RemoveActionCallback(action_callback_); | 640 base::RemoveActionCallback(action_callback_); |
| 564 action_callback_ = base::Bind(&MetricsService::OnUserAction, | 641 action_callback_ = base::Bind(&MetricsService::OnUserAction, |
| 565 base::Unretained(this)); | 642 base::Unretained(this)); |
| 566 base::AddActionCallback(action_callback_); | 643 base::AddActionCallback(action_callback_); |
| 567 } | 644 } |
| 568 | 645 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 #endif // defined(OS_WIN) | 911 #endif // defined(OS_WIN) |
| 835 | 912 |
| 836 //------------------------------------------------------------------------------ | 913 //------------------------------------------------------------------------------ |
| 837 // private methods | 914 // private methods |
| 838 //------------------------------------------------------------------------------ | 915 //------------------------------------------------------------------------------ |
| 839 | 916 |
| 840 | 917 |
| 841 //------------------------------------------------------------------------------ | 918 //------------------------------------------------------------------------------ |
| 842 // Initialization methods | 919 // Initialization methods |
| 843 | 920 |
| 844 void MetricsService::InitializeMetricsState() { | 921 void MetricsService::InitializeMetricsState(ReportingState reporting_state) { |
| 845 #if defined(OS_POSIX) | 922 #if defined(OS_POSIX) |
| 846 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; | 923 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; |
| 847 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; | 924 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; |
| 848 #else | 925 #else |
| 849 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 926 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 850 network_stats_server_ = dist->GetNetworkStatsServer(); | 927 network_stats_server_ = dist->GetNetworkStatsServer(); |
| 851 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); | 928 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); |
| 852 #endif | 929 #endif |
| 853 | 930 |
| 854 PrefService* pref = g_browser_process->local_state(); | 931 PrefService* pref = g_browser_process->local_state(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 871 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); | 948 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); |
| 872 | 949 |
| 873 // TODO(rtenneti): On windows, consider saving/getting execution_phase from | 950 // TODO(rtenneti): On windows, consider saving/getting execution_phase from |
| 874 // the registry. | 951 // the registry. |
| 875 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); | 952 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); |
| 876 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", | 953 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", |
| 877 execution_phase); | 954 execution_phase); |
| 878 | 955 |
| 879 // If the previous session didn't exit cleanly, then prepare an initial | 956 // If the previous session didn't exit cleanly, then prepare an initial |
| 880 // stability log if UMA is enabled. | 957 // stability log if UMA is enabled. |
| 881 if (state_manager_->IsMetricsReportingEnabled()) | 958 if (reporting_state == REPORTING_ENABLED) |
| 882 PrepareInitialStabilityLog(); | 959 PrepareInitialStabilityLog(); |
| 883 } | 960 } |
| 884 | 961 |
| 885 // Update session ID. | 962 // Update session ID. |
| 886 ++session_id_; | 963 ++session_id_; |
| 887 pref->SetInteger(prefs::kMetricsSessionID, session_id_); | 964 pref->SetInteger(prefs::kMetricsSessionID, session_id_); |
| 888 | 965 |
| 889 // Stability bookkeeping | 966 // Stability bookkeeping |
| 890 IncrementPrefValue(prefs::kStabilityLaunchCount); | 967 IncrementPrefValue(prefs::kStabilityLaunchCount); |
| 891 | 968 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 | 1112 |
| 1036 void MetricsService::ReceivedProfilerData( | 1113 void MetricsService::ReceivedProfilerData( |
| 1037 const tracked_objects::ProcessDataSnapshot& process_data, | 1114 const tracked_objects::ProcessDataSnapshot& process_data, |
| 1038 int process_type) { | 1115 int process_type) { |
| 1039 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1116 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1040 | 1117 |
| 1041 // Upon the first callback, create the initial log so that we can immediately | 1118 // Upon the first callback, create the initial log so that we can immediately |
| 1042 // save the profiler data. | 1119 // save the profiler data. |
| 1043 if (!initial_metrics_log_.get()) { | 1120 if (!initial_metrics_log_.get()) { |
| 1044 initial_metrics_log_.reset( | 1121 initial_metrics_log_.reset( |
| 1045 new MetricsLog(state_manager_->client_id(), session_id_, | 1122 new MetricsLog(client_id_, session_id_, MetricsLog::ONGOING_LOG)); |
| 1046 MetricsLog::ONGOING_LOG)); | |
| 1047 } | 1123 } |
| 1048 | 1124 |
| 1049 initial_metrics_log_->RecordProfilerData(process_data, process_type); | 1125 initial_metrics_log_->RecordProfilerData(process_data, process_type); |
| 1050 } | 1126 } |
| 1051 | 1127 |
| 1052 void MetricsService::FinishedReceivingProfilerData() { | 1128 void MetricsService::FinishedReceivingProfilerData() { |
| 1053 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1129 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1054 state_ = INIT_TASK_DONE; | 1130 state_ = INIT_TASK_DONE; |
| 1055 scheduler_->InitTaskComplete(); | 1131 scheduler_->InitTaskComplete(); |
| 1056 } | 1132 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1070 last_updated_time_ = now; | 1146 last_updated_time_ = now; |
| 1071 | 1147 |
| 1072 const int64 incremental_time_secs = incremental_uptime->InSeconds(); | 1148 const int64 incremental_time_secs = incremental_uptime->InSeconds(); |
| 1073 if (incremental_time_secs > 0) { | 1149 if (incremental_time_secs > 0) { |
| 1074 int64 metrics_uptime = pref->GetInt64(prefs::kUninstallMetricsUptimeSec); | 1150 int64 metrics_uptime = pref->GetInt64(prefs::kUninstallMetricsUptimeSec); |
| 1075 metrics_uptime += incremental_time_secs; | 1151 metrics_uptime += incremental_time_secs; |
| 1076 pref->SetInt64(prefs::kUninstallMetricsUptimeSec, metrics_uptime); | 1152 pref->SetInt64(prefs::kUninstallMetricsUptimeSec, metrics_uptime); |
| 1077 } | 1153 } |
| 1078 } | 1154 } |
| 1079 | 1155 |
| 1156 void MetricsService::ResetMetricsIDsIfNecessary() { |
| 1157 if (metrics_ids_reset_check_performed_) |
| 1158 return; |
| 1159 |
| 1160 metrics_ids_reset_check_performed_ = true; |
| 1161 |
| 1162 PrefService* local_state = g_browser_process->local_state(); |
| 1163 if (!local_state->GetBoolean(prefs::kMetricsResetIds)) |
| 1164 return; |
| 1165 |
| 1166 UMA_HISTOGRAM_BOOLEAN("UMA.MetricsIDsReset", true); |
| 1167 |
| 1168 DCHECK(client_id_.empty()); |
| 1169 DCHECK_EQ(kLowEntropySourceNotSet, low_entropy_source_); |
| 1170 |
| 1171 local_state->ClearPref(prefs::kMetricsClientID); |
| 1172 local_state->ClearPref(prefs::kMetricsLowEntropySource); |
| 1173 local_state->ClearPref(prefs::kMetricsResetIds); |
| 1174 } |
| 1175 |
| 1176 int MetricsService::GetLowEntropySource() { |
| 1177 // Note that the default value for the low entropy source and the default pref |
| 1178 // value are both kLowEntropySourceNotSet, which is used to identify if the |
| 1179 // value has been set or not. |
| 1180 if (low_entropy_source_ != kLowEntropySourceNotSet) |
| 1181 return low_entropy_source_; |
| 1182 |
| 1183 ResetMetricsIDsIfNecessary(); |
| 1184 |
| 1185 PrefService* local_state = g_browser_process->local_state(); |
| 1186 const CommandLine* command_line(CommandLine::ForCurrentProcess()); |
| 1187 // Only try to load the value from prefs if the user did not request a reset. |
| 1188 // Otherwise, skip to generating a new value. |
| 1189 if (!command_line->HasSwitch(switches::kResetVariationState)) { |
| 1190 int value = local_state->GetInteger(prefs::kMetricsLowEntropySource); |
| 1191 // If the value is outside the [0, kMaxLowEntropySize) range, re-generate |
| 1192 // it below. |
| 1193 if (value >= 0 && value < kMaxLowEntropySize) { |
| 1194 low_entropy_source_ = value; |
| 1195 UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", false); |
| 1196 return low_entropy_source_; |
| 1197 } |
| 1198 } |
| 1199 |
| 1200 UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", true); |
| 1201 low_entropy_source_ = GenerateLowEntropySource(); |
| 1202 local_state->SetInteger(prefs::kMetricsLowEntropySource, low_entropy_source_); |
| 1203 local_state->ClearPref(prefs::kMetricsOldLowEntropySource); |
| 1204 metrics::CachingPermutedEntropyProvider::ClearCache(local_state); |
| 1205 |
| 1206 return low_entropy_source_; |
| 1207 } |
| 1208 |
| 1209 // static |
| 1210 std::string MetricsService::GenerateClientID() { |
| 1211 return base::GenerateGUID(); |
| 1212 } |
| 1213 |
| 1080 //------------------------------------------------------------------------------ | 1214 //------------------------------------------------------------------------------ |
| 1081 // State save methods | 1215 // State save methods |
| 1082 | 1216 |
| 1083 void MetricsService::ScheduleNextStateSave() { | 1217 void MetricsService::ScheduleNextStateSave() { |
| 1084 state_saver_factory_.InvalidateWeakPtrs(); | 1218 state_saver_factory_.InvalidateWeakPtrs(); |
| 1085 | 1219 |
| 1086 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | 1220 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 1087 base::Bind(&MetricsService::SaveLocalState, | 1221 base::Bind(&MetricsService::SaveLocalState, |
| 1088 state_saver_factory_.GetWeakPtr()), | 1222 state_saver_factory_.GetWeakPtr()), |
| 1089 base::TimeDelta::FromMinutes(kSaveStateIntervalMinutes)); | 1223 base::TimeDelta::FromMinutes(kSaveStateIntervalMinutes)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1103 } | 1237 } |
| 1104 | 1238 |
| 1105 | 1239 |
| 1106 //------------------------------------------------------------------------------ | 1240 //------------------------------------------------------------------------------ |
| 1107 // Recording control methods | 1241 // Recording control methods |
| 1108 | 1242 |
| 1109 void MetricsService::OpenNewLog() { | 1243 void MetricsService::OpenNewLog() { |
| 1110 DCHECK(!log_manager_.current_log()); | 1244 DCHECK(!log_manager_.current_log()); |
| 1111 | 1245 |
| 1112 log_manager_.BeginLoggingWithLog( | 1246 log_manager_.BeginLoggingWithLog( |
| 1113 new MetricsLog(state_manager_->client_id(), session_id_, | 1247 new MetricsLog(client_id_, session_id_, MetricsLog::ONGOING_LOG)); |
| 1114 MetricsLog::ONGOING_LOG)); | |
| 1115 if (state_ == INITIALIZED) { | 1248 if (state_ == INITIALIZED) { |
| 1116 // We only need to schedule that run once. | 1249 // We only need to schedule that run once. |
| 1117 state_ = INIT_TASK_SCHEDULED; | 1250 state_ = INIT_TASK_SCHEDULED; |
| 1118 | 1251 |
| 1119 // Schedules a task on the file thread for execution of slower | 1252 // Schedules a task on the file thread for execution of slower |
| 1120 // initialization steps (such as plugin list generation) necessary | 1253 // initialization steps (such as plugin list generation) necessary |
| 1121 // for sending the initial log. This avoids blocking the main UI | 1254 // for sending the initial log. This avoids blocking the main UI |
| 1122 // thread. | 1255 // thread. |
| 1123 BrowserThread::PostDelayedTask( | 1256 BrowserThread::PostDelayedTask( |
| 1124 BrowserThread::FILE, | 1257 BrowserThread::FILE, |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 | 1533 |
| 1401 DCHECK(log_manager_.has_staged_log()); | 1534 DCHECK(log_manager_.has_staged_log()); |
| 1402 } | 1535 } |
| 1403 | 1536 |
| 1404 void MetricsService::PrepareInitialStabilityLog() { | 1537 void MetricsService::PrepareInitialStabilityLog() { |
| 1405 DCHECK_EQ(INITIALIZED, state_); | 1538 DCHECK_EQ(INITIALIZED, state_); |
| 1406 PrefService* pref = g_browser_process->local_state(); | 1539 PrefService* pref = g_browser_process->local_state(); |
| 1407 DCHECK_NE(0, pref->GetInteger(prefs::kStabilityCrashCount)); | 1540 DCHECK_NE(0, pref->GetInteger(prefs::kStabilityCrashCount)); |
| 1408 | 1541 |
| 1409 scoped_ptr<MetricsLog> initial_stability_log( | 1542 scoped_ptr<MetricsLog> initial_stability_log( |
| 1410 new MetricsLog(state_manager_->client_id(), session_id_, | 1543 new MetricsLog(client_id_, session_id_, |
| 1411 MetricsLog::INITIAL_STABILITY_LOG)); | 1544 MetricsLog::INITIAL_STABILITY_LOG)); |
| 1412 if (!initial_stability_log->LoadSavedEnvironmentFromPrefs()) | 1545 if (!initial_stability_log->LoadSavedEnvironmentFromPrefs()) |
| 1413 return; | 1546 return; |
| 1414 initial_stability_log->RecordStabilityMetrics(base::TimeDelta(), | 1547 initial_stability_log->RecordStabilityMetrics(base::TimeDelta(), |
| 1415 base::TimeDelta()); | 1548 base::TimeDelta()); |
| 1416 log_manager_.LoadPersistedUnsentLogs(); | 1549 log_manager_.LoadPersistedUnsentLogs(); |
| 1417 | 1550 |
| 1418 log_manager_.PauseCurrentLog(); | 1551 log_manager_.PauseCurrentLog(); |
| 1419 log_manager_.BeginLoggingWithLog(initial_stability_log.release()); | 1552 log_manager_.BeginLoggingWithLog(initial_stability_log.release()); |
| 1420 #if defined(OS_ANDROID) | 1553 #if defined(OS_ANDROID) |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 return; | 1832 return; |
| 1700 } | 1833 } |
| 1701 } | 1834 } |
| 1702 | 1835 |
| 1703 SyntheticTrialGroup trial_group = trial; | 1836 SyntheticTrialGroup trial_group = trial; |
| 1704 trial_group.start_time = base::TimeTicks::Now(); | 1837 trial_group.start_time = base::TimeTicks::Now(); |
| 1705 synthetic_trial_groups_.push_back(trial_group); | 1838 synthetic_trial_groups_.push_back(trial_group); |
| 1706 } | 1839 } |
| 1707 | 1840 |
| 1708 void MetricsService::CheckForClonedInstall() { | 1841 void MetricsService::CheckForClonedInstall() { |
| 1709 state_manager_->CheckForClonedInstall(); | 1842 DCHECK(!cloned_install_detector_); |
| 1843 |
| 1844 metrics::MachineIdProvider* provider = |
| 1845 metrics::MachineIdProvider::CreateInstance(); |
| 1846 if (!provider) |
| 1847 return; |
| 1848 |
| 1849 cloned_install_detector_.reset( |
| 1850 new metrics::ClonedInstallDetector(provider)); |
| 1851 |
| 1852 PrefService* local_state = g_browser_process->local_state(); |
| 1853 cloned_install_detector_->CheckForClonedInstall(local_state); |
| 1710 } | 1854 } |
| 1711 | 1855 |
| 1712 void MetricsService::GetCurrentSyntheticFieldTrials( | 1856 void MetricsService::GetCurrentSyntheticFieldTrials( |
| 1713 std::vector<chrome_variations::ActiveGroupId>* synthetic_trials) { | 1857 std::vector<chrome_variations::ActiveGroupId>* synthetic_trials) { |
| 1714 DCHECK(synthetic_trials); | 1858 DCHECK(synthetic_trials); |
| 1715 synthetic_trials->clear(); | 1859 synthetic_trials->clear(); |
| 1716 const MetricsLog* current_log = | 1860 const MetricsLog* current_log = |
| 1717 static_cast<const MetricsLog*>(log_manager_.current_log()); | 1861 static_cast<const MetricsLog*>(log_manager_.current_log()); |
| 1718 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { | 1862 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { |
| 1719 if (synthetic_trial_groups_[i].start_time <= current_log->creation_time()) | 1863 if (synthetic_trial_groups_[i].start_time <= current_log->creation_time()) |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 // Android has its own settings for metrics / crash uploading. | 2075 // Android has its own settings for metrics / crash uploading. |
| 1932 const PrefService* prefs = g_browser_process->local_state(); | 2076 const PrefService* prefs = g_browser_process->local_state(); |
| 1933 return prefs->GetBoolean(prefs::kCrashReportingEnabled); | 2077 return prefs->GetBoolean(prefs::kCrashReportingEnabled); |
| 1934 #else | 2078 #else |
| 1935 return MetricsServiceHelper::IsMetricsReportingEnabled(); | 2079 return MetricsServiceHelper::IsMetricsReportingEnabled(); |
| 1936 #endif | 2080 #endif |
| 1937 #else | 2081 #else |
| 1938 return false; | 2082 return false; |
| 1939 #endif | 2083 #endif |
| 1940 } | 2084 } |
| OLD | NEW |