| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 return NO_RESPONSE; | 247 return NO_RESPONSE; |
| 248 case 200: | 248 case 200: |
| 249 return SUCCESS; | 249 return SUCCESS; |
| 250 case 400: | 250 case 400: |
| 251 return BAD_REQUEST; | 251 return BAD_REQUEST; |
| 252 default: | 252 default: |
| 253 return UNKNOWN_FAILURE; | 253 return UNKNOWN_FAILURE; |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 void MarkAppCleanShutdownAndCommit(PrefService* local_state) { | 257 void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon, |
| 258 local_state->SetBoolean(metrics::prefs::kStabilityExitedCleanly, true); | 258 PrefService* local_state) { |
| 259 clean_exit_beacon->WriteBeaconValue(true); |
| 259 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 260 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
| 260 MetricsService::SHUTDOWN_COMPLETE); | 261 MetricsService::SHUTDOWN_COMPLETE); |
| 261 // Start writing right away (write happens on a different thread). | 262 // Start writing right away (write happens on a different thread). |
| 262 local_state->CommitPendingWrite(); | 263 local_state->CommitPendingWrite(); |
| 263 } | 264 } |
| 264 | 265 |
| 265 } // namespace | 266 } // namespace |
| 266 | 267 |
| 267 | 268 |
| 268 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, uint32 group) { | 269 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, uint32 group) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 } | 309 } |
| 309 | 310 |
| 310 MetricsService::MetricsService(metrics::MetricsStateManager* state_manager, | 311 MetricsService::MetricsService(metrics::MetricsStateManager* state_manager, |
| 311 metrics::MetricsServiceClient* client, | 312 metrics::MetricsServiceClient* client, |
| 312 PrefService* local_state) | 313 PrefService* local_state) |
| 313 : log_manager_(local_state, kUploadLogAvoidRetransmitSize), | 314 : log_manager_(local_state, kUploadLogAvoidRetransmitSize), |
| 314 histogram_snapshot_manager_(this), | 315 histogram_snapshot_manager_(this), |
| 315 state_manager_(state_manager), | 316 state_manager_(state_manager), |
| 316 client_(client), | 317 client_(client), |
| 317 local_state_(local_state), | 318 local_state_(local_state), |
| 319 clean_exit_beacon_(client->GetRegistryBackupKey(), local_state), |
| 318 recording_active_(false), | 320 recording_active_(false), |
| 319 reporting_active_(false), | 321 reporting_active_(false), |
| 320 test_mode_active_(false), | 322 test_mode_active_(false), |
| 321 state_(INITIALIZED), | 323 state_(INITIALIZED), |
| 322 has_initial_stability_log_(false), | 324 has_initial_stability_log_(false), |
| 323 log_upload_in_progress_(false), | 325 log_upload_in_progress_(false), |
| 324 idle_since_last_transmission_(false), | 326 idle_since_last_transmission_(false), |
| 325 session_id_(-1), | 327 session_id_(-1), |
| 326 self_ptr_factory_(this), | 328 self_ptr_factory_(this), |
| 327 state_saver_factory_(this) { | 329 state_saver_factory_(this) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 493 |
| 492 void MetricsService::RecordCompletedSessionEnd() { | 494 void MetricsService::RecordCompletedSessionEnd() { |
| 493 LogCleanShutdown(); | 495 LogCleanShutdown(); |
| 494 RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, true); | 496 RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, true); |
| 495 } | 497 } |
| 496 | 498 |
| 497 #if defined(OS_ANDROID) || defined(OS_IOS) | 499 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 498 void MetricsService::OnAppEnterBackground() { | 500 void MetricsService::OnAppEnterBackground() { |
| 499 scheduler_->Stop(); | 501 scheduler_->Stop(); |
| 500 | 502 |
| 501 MarkAppCleanShutdownAndCommit(local_state_); | 503 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_); |
| 502 | 504 |
| 503 // At this point, there's no way of knowing when the process will be | 505 // At this point, there's no way of knowing when the process will be |
| 504 // killed, so this has to be treated similar to a shutdown, closing and | 506 // killed, so this has to be treated similar to a shutdown, closing and |
| 505 // persisting all logs. Unlinke a shutdown, the state is primed to be ready | 507 // persisting all logs. Unlinke a shutdown, the state is primed to be ready |
| 506 // to continue logging and uploading if the process does return. | 508 // to continue logging and uploading if the process does return. |
| 507 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { | 509 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { |
| 508 PushPendingLogsToPersistentStorage(); | 510 PushPendingLogsToPersistentStorage(); |
| 509 // Persisting logs closes the current log, so start recording a new log | 511 // Persisting logs closes the current log, so start recording a new log |
| 510 // immediately to capture any background work that might be done before the | 512 // immediately to capture any background work that might be done before the |
| 511 // process is killed. | 513 // process is killed. |
| 512 OpenNewLog(); | 514 OpenNewLog(); |
| 513 } | 515 } |
| 514 } | 516 } |
| 515 | 517 |
| 516 void MetricsService::OnAppEnterForeground() { | 518 void MetricsService::OnAppEnterForeground() { |
| 517 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false); | 519 clean_exit_beacon_.WriteBeaconValue(false); |
| 518 StartSchedulerIfNecessary(); | 520 StartSchedulerIfNecessary(); |
| 519 } | 521 } |
| 520 #else | 522 #else |
| 521 void MetricsService::LogNeedForCleanShutdown() { | 523 void MetricsService::LogNeedForCleanShutdown() { |
| 522 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false); | 524 clean_exit_beacon_.WriteBeaconValue(false); |
| 523 // Redundant setting to be sure we call for a clean shutdown. | 525 // Redundant setting to be sure we call for a clean shutdown. |
| 524 clean_shutdown_status_ = NEED_TO_SHUTDOWN; | 526 clean_shutdown_status_ = NEED_TO_SHUTDOWN; |
| 525 } | 527 } |
| 526 #endif // defined(OS_ANDROID) || defined(OS_IOS) | 528 #endif // defined(OS_ANDROID) || defined(OS_IOS) |
| 527 | 529 |
| 528 // static | 530 // static |
| 529 void MetricsService::SetExecutionPhase(ExecutionPhase execution_phase, | 531 void MetricsService::SetExecutionPhase(ExecutionPhase execution_phase, |
| 530 PrefService* local_state) { | 532 PrefService* local_state) { |
| 531 execution_phase_ = execution_phase; | 533 execution_phase_ = execution_phase; |
| 532 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 534 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 557 | 559 |
| 558 void MetricsService::InitializeMetricsState() { | 560 void MetricsService::InitializeMetricsState() { |
| 559 local_state_->SetString(metrics::prefs::kStabilityStatsVersion, | 561 local_state_->SetString(metrics::prefs::kStabilityStatsVersion, |
| 560 client_->GetVersionString()); | 562 client_->GetVersionString()); |
| 561 local_state_->SetInt64(metrics::prefs::kStabilityStatsBuildTime, | 563 local_state_->SetInt64(metrics::prefs::kStabilityStatsBuildTime, |
| 562 MetricsLog::GetBuildTime()); | 564 MetricsLog::GetBuildTime()); |
| 563 | 565 |
| 564 log_manager_.LoadPersistedUnsentLogs(); | 566 log_manager_.LoadPersistedUnsentLogs(); |
| 565 | 567 |
| 566 session_id_ = local_state_->GetInteger(metrics::prefs::kMetricsSessionID); | 568 session_id_ = local_state_->GetInteger(metrics::prefs::kMetricsSessionID); |
| 567 bool exited_cleanly = true; | 569 |
| 568 if (!local_state_->GetBoolean(metrics::prefs::kStabilityExitedCleanly)) { | 570 if (!clean_exit_beacon_.exited_cleanly()) { |
| 569 IncrementPrefValue(metrics::prefs::kStabilityCrashCount); | 571 IncrementPrefValue(metrics::prefs::kStabilityCrashCount); |
| 570 // Reset flag, and wait until we call LogNeedForCleanShutdown() before | 572 // Reset flag, and wait until we call LogNeedForCleanShutdown() before |
| 571 // monitoring. | 573 // monitoring. |
| 572 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, true); | 574 clean_exit_beacon_.WriteBeaconValue(true); |
| 573 exited_cleanly = false; | |
| 574 } | 575 } |
| 575 | 576 |
| 576 if (!exited_cleanly || ProvidersHaveStabilityMetrics()) { | 577 if (!clean_exit_beacon_.exited_cleanly() || ProvidersHaveStabilityMetrics()) { |
| 577 // TODO(rtenneti): On windows, consider saving/getting execution_phase from | 578 // TODO(rtenneti): On windows, consider saving/getting execution_phase from |
| 578 // the registry. | 579 // the registry. |
| 579 int execution_phase = | 580 int execution_phase = |
| 580 local_state_->GetInteger(metrics::prefs::kStabilityExecutionPhase); | 581 local_state_->GetInteger(metrics::prefs::kStabilityExecutionPhase); |
| 581 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", | 582 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", |
| 582 execution_phase); | 583 execution_phase); |
| 583 | 584 |
| 584 // If the previous session didn't exit cleanly, or if any provider | 585 // If the previous session didn't exit cleanly, or if any provider |
| 585 // explicitly requests it, prepare an initial stability log - | 586 // explicitly requests it, prepare an initial stability log - |
| 586 // provided UMA is enabled. | 587 // provided UMA is enabled. |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 } | 1160 } |
| 1160 | 1161 |
| 1161 void MetricsService::RecordCurrentStabilityHistograms() { | 1162 void MetricsService::RecordCurrentStabilityHistograms() { |
| 1162 DCHECK(log_manager_.current_log()); | 1163 DCHECK(log_manager_.current_log()); |
| 1163 histogram_snapshot_manager_.PrepareDeltas( | 1164 histogram_snapshot_manager_.PrepareDeltas( |
| 1164 base::Histogram::kNoFlags, base::Histogram::kUmaStabilityHistogramFlag); | 1165 base::Histogram::kNoFlags, base::Histogram::kUmaStabilityHistogramFlag); |
| 1165 } | 1166 } |
| 1166 | 1167 |
| 1167 void MetricsService::LogCleanShutdown() { | 1168 void MetricsService::LogCleanShutdown() { |
| 1168 // Redundant hack to write pref ASAP. | 1169 // Redundant hack to write pref ASAP. |
| 1169 MarkAppCleanShutdownAndCommit(local_state_); | 1170 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_); |
| 1170 | 1171 |
| 1171 // Redundant setting to assure that we always reset this value at shutdown | 1172 // Redundant setting to assure that we always reset this value at shutdown |
| 1172 // (and that we don't use some alternate path, and not call LogCleanShutdown). | 1173 // (and that we don't use some alternate path, and not call LogCleanShutdown). |
| 1173 clean_shutdown_status_ = CLEANLY_SHUTDOWN; | 1174 clean_shutdown_status_ = CLEANLY_SHUTDOWN; |
| 1174 | 1175 |
| 1175 RecordBooleanPrefValue(metrics::prefs::kStabilityExitedCleanly, true); | 1176 clean_exit_beacon_.WriteBeaconValue(true); |
| 1177 RecordCurrentState(local_state_); |
| 1176 local_state_->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 1178 local_state_->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
| 1177 MetricsService::SHUTDOWN_COMPLETE); | 1179 MetricsService::SHUTDOWN_COMPLETE); |
| 1178 } | 1180 } |
| 1179 | 1181 |
| 1180 bool MetricsService::ShouldLogEvents() { | 1182 bool MetricsService::ShouldLogEvents() { |
| 1181 // We simply don't log events to UMA if there is a single incognito | 1183 // We simply don't log events to UMA if there is a single incognito |
| 1182 // session visible. The problem is that we always notify using the orginal | 1184 // session visible. The problem is that we always notify using the orginal |
| 1183 // profile in order to simplify notification processing. | 1185 // profile in order to simplify notification processing. |
| 1184 return !client_->IsOffTheRecordSessionActive(); | 1186 return !client_->IsOffTheRecordSessionActive(); |
| 1185 } | 1187 } |
| 1186 | 1188 |
| 1187 void MetricsService::RecordBooleanPrefValue(const char* path, bool value) { | 1189 void MetricsService::RecordBooleanPrefValue(const char* path, bool value) { |
| 1188 DCHECK(IsSingleThreaded()); | 1190 DCHECK(IsSingleThreaded()); |
| 1189 local_state_->SetBoolean(path, value); | 1191 local_state_->SetBoolean(path, value); |
| 1190 RecordCurrentState(local_state_); | 1192 RecordCurrentState(local_state_); |
| 1191 } | 1193 } |
| 1192 | 1194 |
| 1193 void MetricsService::RecordCurrentState(PrefService* pref) { | 1195 void MetricsService::RecordCurrentState(PrefService* pref) { |
| 1194 pref->SetInt64(metrics::prefs::kStabilityLastTimestampSec, | 1196 pref->SetInt64(metrics::prefs::kStabilityLastTimestampSec, |
| 1195 base::Time::Now().ToTimeT()); | 1197 base::Time::Now().ToTimeT()); |
| 1196 } | 1198 } |
| 1197 | 1199 |
| 1198 } // namespace metrics | 1200 } // namespace metrics |
| OLD | NEW |