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 |