| 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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 // Even if reporting is disabled, the scheduler is needed to trigger the | 755 // Even if reporting is disabled, the scheduler is needed to trigger the |
| 756 // creation of the initial log, which must be done in order for any logs to be | 756 // creation of the initial log, which must be done in order for any logs to be |
| 757 // persisted on shutdown or backgrounding. | 757 // persisted on shutdown or backgrounding. |
| 758 if (recording_active() && | 758 if (recording_active() && |
| 759 (reporting_active() || state_ < SENDING_LOGS)) { | 759 (reporting_active() || state_ < SENDING_LOGS)) { |
| 760 scheduler_->Start(); | 760 scheduler_->Start(); |
| 761 } | 761 } |
| 762 } | 762 } |
| 763 | 763 |
| 764 void MetricsService::StartScheduledUpload() { | 764 void MetricsService::StartScheduledUpload() { |
| 765 DCHECK(state_ >= INIT_TASK_DONE); |
| 765 // If we're getting no notifications, then the log won't have much in it, and | 766 // If we're getting no notifications, then the log won't have much in it, and |
| 766 // it's possible the computer is about to go to sleep, so don't upload and | 767 // it's possible the computer is about to go to sleep, so don't upload and |
| 767 // stop the scheduler. | 768 // stop the scheduler. |
| 768 // If recording has been turned off, the scheduler doesn't need to run. | 769 // If recording has been turned off, the scheduler doesn't need to run. |
| 769 // If reporting is off, proceed if the initial log hasn't been created, since | 770 // If reporting is off, proceed if the initial log hasn't been created, since |
| 770 // that has to happen in order for logs to be cut and stored when persisting. | 771 // that has to happen in order for logs to be cut and stored when persisting. |
| 771 // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or | 772 // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or |
| 772 // recording are turned off instead of letting it fire and then aborting. | 773 // recording are turned off instead of letting it fire and then aborting. |
| 773 if (idle_since_last_transmission_ || | 774 if (idle_since_last_transmission_ || |
| 774 !recording_active() || | 775 !recording_active() || |
| 775 (!reporting_active() && state_ >= SENDING_LOGS)) { | 776 (!reporting_active() && state_ >= SENDING_LOGS)) { |
| 776 scheduler_->Stop(); | 777 scheduler_->Stop(); |
| 777 scheduler_->UploadCancelled(); | 778 scheduler_->UploadCancelled(); |
| 778 return; | 779 return; |
| 779 } | 780 } |
| 780 | 781 |
| 781 // If there are unsent logs, send the next one. If not, start the asynchronous | 782 // If there are unsent logs, send the next one. If not, start the asynchronous |
| 782 // process of finalizing the current log for upload. | 783 // process of finalizing the current log for upload. |
| 783 if (state_ == SENDING_LOGS && log_manager_.has_unsent_logs()) { | 784 if (state_ == SENDING_LOGS && log_manager_.has_unsent_logs()) { |
| 784 log_manager_.StageNextLogForUpload(); | 785 SendNextLog(); |
| 785 SendStagedLog(); | |
| 786 } else { | 786 } else { |
| 787 // There are no logs left to send, so start creating a new one. |
| 787 client_->CollectFinalMetrics( | 788 client_->CollectFinalMetrics( |
| 788 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone, | 789 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone, |
| 789 self_ptr_factory_.GetWeakPtr())); | 790 self_ptr_factory_.GetWeakPtr())); |
| 790 } | 791 } |
| 791 } | 792 } |
| 792 | 793 |
| 793 void MetricsService::OnFinalLogInfoCollectionDone() { | 794 void MetricsService::OnFinalLogInfoCollectionDone() { |
| 794 // If somehow there is a log upload in progress, we return and hope things | 795 // If somehow there is a log upload in progress, we return and hope things |
| 795 // work out. The scheduler isn't informed since if this happens, the scheduler | 796 // work out. The scheduler isn't informed since if this happens, the scheduler |
| 796 // will get a response from the upload. | 797 // will get a response from the upload. |
| 797 DCHECK(!log_upload_in_progress_); | 798 DCHECK(!log_upload_in_progress_); |
| 798 if (log_upload_in_progress_) | 799 if (log_upload_in_progress_) |
| 799 return; | 800 return; |
| 800 | 801 |
| 801 // Abort if metrics were turned off during the final info gathering. | 802 // Abort if metrics were turned off during the final info gathering. |
| 802 if (!recording_active()) { | 803 if (!recording_active()) { |
| 803 scheduler_->Stop(); | 804 scheduler_->Stop(); |
| 804 scheduler_->UploadCancelled(); | 805 scheduler_->UploadCancelled(); |
| 805 return; | 806 return; |
| 806 } | 807 } |
| 807 | 808 |
| 808 StageNewLog(); | 809 if (state_ == INIT_TASK_DONE) { |
| 810 PrepareInitialMetricsLog(); |
| 811 } else { |
| 812 DCHECK_EQ(SENDING_LOGS, state_); |
| 813 CloseCurrentLog(); |
| 814 OpenNewLog(); |
| 815 } |
| 816 SendNextLog(); |
| 817 } |
| 809 | 818 |
| 810 // If logs shouldn't be uploaded, stop here. It's important that this check | 819 void MetricsService::SendNextLog() { |
| 811 // be after StageNewLog(), otherwise the previous logs will never be loaded, | 820 DCHECK_EQ(SENDING_LOGS, state_); |
| 812 // and thus the open log won't be persisted. | |
| 813 // TODO(stuartmorgan): This is unnecessarily complicated; restructure loading | |
| 814 // of previous logs to not require running part of the upload logic. | |
| 815 // http://crbug.com/157337 | |
| 816 if (!reporting_active()) { | 821 if (!reporting_active()) { |
| 817 scheduler_->Stop(); | 822 scheduler_->Stop(); |
| 818 scheduler_->UploadCancelled(); | 823 scheduler_->UploadCancelled(); |
| 819 return; | 824 return; |
| 820 } | 825 } |
| 821 | 826 if (!log_manager_.has_unsent_logs()) { |
| 827 // Should only get here if serializing the log failed somehow. |
| 828 // Just tell the scheduler it was uploaded and wait for the next log |
| 829 // interval. |
| 830 scheduler_->UploadFinished(true, log_manager_.has_unsent_logs()); |
| 831 return; |
| 832 } |
| 833 if (!log_manager_.has_staged_log()) |
| 834 log_manager_.StageNextLogForUpload(); |
| 822 SendStagedLog(); | 835 SendStagedLog(); |
| 823 } | 836 } |
| 824 | 837 |
| 825 void MetricsService::StageNewLog() { | |
| 826 if (log_manager_.has_staged_log()) | |
| 827 return; | |
| 828 | |
| 829 switch (state_) { | |
| 830 case INITIALIZED: | |
| 831 case INIT_TASK_SCHEDULED: // We should be further along by now. | |
| 832 NOTREACHED(); | |
| 833 return; | |
| 834 | |
| 835 case INIT_TASK_DONE: | |
| 836 PrepareInitialMetricsLog(); | |
| 837 // Stage the first log, which could be a stability log (either one | |
| 838 // for created in this session or from a previous session) or the | |
| 839 // initial metrics log that was just created. | |
| 840 log_manager_.StageNextLogForUpload(); | |
| 841 state_ = SENDING_LOGS; | |
| 842 break; | |
| 843 | |
| 844 case SENDING_LOGS: | |
| 845 CloseCurrentLog(); | |
| 846 OpenNewLog(); | |
| 847 log_manager_.StageNextLogForUpload(); | |
| 848 break; | |
| 849 | |
| 850 default: | |
| 851 NOTREACHED(); | |
| 852 return; | |
| 853 } | |
| 854 | |
| 855 DCHECK(log_manager_.has_staged_log()); | |
| 856 } | |
| 857 | |
| 858 bool MetricsService::ProvidersHaveStabilityMetrics() { | 838 bool MetricsService::ProvidersHaveStabilityMetrics() { |
| 859 // Check whether any metrics provider has stability metrics. | 839 // Check whether any metrics provider has stability metrics. |
| 860 for (size_t i = 0; i < metrics_providers_.size(); ++i) { | 840 for (size_t i = 0; i < metrics_providers_.size(); ++i) { |
| 861 if (metrics_providers_[i]->HasStabilityMetrics()) | 841 if (metrics_providers_[i]->HasStabilityMetrics()) |
| 862 return true; | 842 return true; |
| 863 } | 843 } |
| 864 | 844 |
| 865 return false; | 845 return false; |
| 866 } | 846 } |
| 867 | 847 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 base::TimeDelta(), base::TimeDelta()); | 899 base::TimeDelta(), base::TimeDelta()); |
| 920 current_log->RecordGeneralMetrics(metrics_providers_.get()); | 900 current_log->RecordGeneralMetrics(metrics_providers_.get()); |
| 921 RecordCurrentHistograms(); | 901 RecordCurrentHistograms(); |
| 922 | 902 |
| 923 log_manager_.FinishCurrentLog(); | 903 log_manager_.FinishCurrentLog(); |
| 924 log_manager_.ResumePausedLog(); | 904 log_manager_.ResumePausedLog(); |
| 925 | 905 |
| 926 // Store unsent logs, including the initial log that was just saved, so | 906 // Store unsent logs, including the initial log that was just saved, so |
| 927 // that they're not lost in case of a crash before upload time. | 907 // that they're not lost in case of a crash before upload time. |
| 928 log_manager_.PersistUnsentLogs(); | 908 log_manager_.PersistUnsentLogs(); |
| 909 |
| 910 state_ = SENDING_LOGS; |
| 929 } | 911 } |
| 930 | 912 |
| 931 void MetricsService::SendStagedLog() { | 913 void MetricsService::SendStagedLog() { |
| 932 DCHECK(log_manager_.has_staged_log()); | 914 DCHECK(log_manager_.has_staged_log()); |
| 933 if (!log_manager_.has_staged_log()) | 915 if (!log_manager_.has_staged_log()) |
| 934 return; | 916 return; |
| 935 | 917 |
| 936 DCHECK(!log_upload_in_progress_); | 918 DCHECK(!log_upload_in_progress_); |
| 937 log_upload_in_progress_ = true; | 919 log_upload_in_progress_ = true; |
| 938 | 920 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 local_state_->SetBoolean(path, value); | 1111 local_state_->SetBoolean(path, value); |
| 1130 RecordCurrentState(local_state_); | 1112 RecordCurrentState(local_state_); |
| 1131 } | 1113 } |
| 1132 | 1114 |
| 1133 void MetricsService::RecordCurrentState(PrefService* pref) { | 1115 void MetricsService::RecordCurrentState(PrefService* pref) { |
| 1134 pref->SetInt64(prefs::kStabilityLastTimestampSec, | 1116 pref->SetInt64(prefs::kStabilityLastTimestampSec, |
| 1135 base::Time::Now().ToTimeT()); | 1117 base::Time::Now().ToTimeT()); |
| 1136 } | 1118 } |
| 1137 | 1119 |
| 1138 } // namespace metrics | 1120 } // namespace metrics |
| OLD | NEW |