Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/browser/safe_browsing/srt_fetcher_win.cc

Issue 2226133005: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix case of flags constants Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" 5 #include "chrome/browser/safe_browsing/srt_fetcher_win.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; 113 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS";
114 const char kFoundUwsReadErrorMetricName[] = 114 const char kFoundUwsReadErrorMetricName[] =
115 "SoftwareReporter.FoundUwSReadError"; 115 "SoftwareReporter.FoundUwSReadError";
116 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; 116 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes";
117 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; 117 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed";
118 118
119 // Reports metrics about the software reporter via UMA (and sometimes Rappor). 119 // Reports metrics about the software reporter via UMA (and sometimes Rappor).
120 class UMAHistogramReporter { 120 class UMAHistogramReporter {
121 public: 121 public:
122 explicit UMAHistogramReporter(const std::string& suffix = std::string()) 122 UMAHistogramReporter() : UMAHistogramReporter(std::string()) {}
123
124 explicit UMAHistogramReporter(const std::string& suffix)
123 : suffix_(suffix), 125 : suffix_(suffix),
124 registry_key_(suffix.empty() ? kSoftwareRemovalToolRegistryKey 126 registry_key_(suffix.empty() ? kSoftwareRemovalToolRegistryKey
125 : base::StringPrintf( 127 : base::StringPrintf(
126 L"%ls\\%ls", 128 L"%ls\\%ls",
127 kSoftwareRemovalToolRegistryKey, 129 kSoftwareRemovalToolRegistryKey,
128 base::UTF8ToUTF16(suffix).c_str())) { 130 base::UTF8ToUTF16(suffix).c_str())) {
129 } 131 }
130 132
131 // Reports the software reporter tool's version via UMA. 133 // Reports the software reporter tool's version via UMA.
132 void ReportVersion(const base::Version& version) const { 134 void ReportVersion(const base::Version& version) const {
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 // All the work happens in the self-deleting class below. 583 // All the work happens in the self-deleting class below.
582 new SRTFetcher(profile); 584 new SRTFetcher(profile);
583 } 585 }
584 586
585 // This class tries to run the reporter and reacts to its exit code. It 587 // This class tries to run the reporter and reacts to its exit code. It
586 // schedules subsequent runs as needed, or retries as soon as a browser is 588 // schedules subsequent runs as needed, or retries as soon as a browser is
587 // available when none is on first try. 589 // available when none is on first try.
588 class ReporterRunner : public chrome::BrowserListObserver { 590 class ReporterRunner : public chrome::BrowserListObserver {
589 public: 591 public:
590 // Starts the sequence of attempts to run the reporter. 592 // Starts the sequence of attempts to run the reporter.
591 static void Run(const SwReporterInvocation& invocation, 593 static void Run(const SwReporterQueue& invocations,
grt (UTC plus 2) 2016/09/01 21:08:55 take as value rather than constref?
Joe Mason 2016/09/02 02:24:30 Done.
592 const base::Version& version, 594 const base::Version& version,
593 scoped_refptr<base::TaskRunner> main_thread_task_runner, 595 scoped_refptr<base::TaskRunner> main_thread_task_runner,
594 scoped_refptr<base::TaskRunner> blocking_task_runner) { 596 scoped_refptr<base::TaskRunner> blocking_task_runner) {
595 if (!instance_) 597 if (!instance_)
596 instance_ = new ReporterRunner; 598 instance_ = new ReporterRunner;
597 DCHECK_CURRENTLY_ON(BrowserThread::UI); 599 DCHECK_CURRENTLY_ON(BrowserThread::UI);
598 // There's nothing to do if the path and version of the reporter has not 600 // There's nothing to do if the path and version of the reporter has not
599 // changed, we just keep running the tasks that are running now. 601 // changed, we just keep running the tasks that are running now.
600 if (instance_->invocation_ == invocation && instance_->version_.IsValid() && 602 if (instance_->invocations_ == invocations &&
601 instance_->version_ == version) 603 instance_->version_.IsValid() && instance_->version_ == version)
602 return; 604 return;
603 605
604 instance_->invocation_ = invocation; 606 instance_->invocations_ = invocations;
grt (UTC plus 2) 2016/09/01 21:08:55 std::move here?
Joe Mason 2016/09/02 02:24:30 Done.
605 instance_->version_ = version; 607 instance_->version_ = version;
606 instance_->main_thread_task_runner_ = std::move(main_thread_task_runner); 608 instance_->main_thread_task_runner_ = std::move(main_thread_task_runner);
607 instance_->blocking_task_runner_ = std::move(blocking_task_runner); 609 instance_->blocking_task_runner_ = std::move(blocking_task_runner);
608 610
609 if (instance_->first_run_) { 611 if (instance_->first_run_) {
610 instance_->first_run_ = false; 612 instance_->first_run_ = false;
611 instance_->TryToRun(); 613 instance_->TryToRun();
612 } 614 }
613 } 615 }
614 616
615 private: 617 private:
616 ReporterRunner() {} 618 ReporterRunner() {}
617 ~ReporterRunner() override {} 619 ~ReporterRunner() override {}
618 620
619 // BrowserListObserver. 621 // BrowserListObserver.
620 void OnBrowserSetLastActive(Browser* browser) override {} 622 void OnBrowserSetLastActive(Browser* browser) override {}
621 void OnBrowserRemoved(Browser* browser) override {} 623 void OnBrowserRemoved(Browser* browser) override {}
622 void OnBrowserAdded(Browser* browser) override { 624 void OnBrowserAdded(Browser* browser) override {
623 DCHECK_CURRENTLY_ON(BrowserThread::UI); 625 DCHECK_CURRENTLY_ON(BrowserThread::UI);
624 DCHECK(browser); 626 DCHECK(browser);
625 MaybeFetchSRT(browser, version_); 627 MaybeFetchSRT(browser, version_);
626 BrowserList::RemoveObserver(this); 628 BrowserList::RemoveObserver(this);
627 } 629 }
628 630
631 // Launches the command line at the head of the queue.
632 void LaunchNextInvocation(std::unique_ptr<SwReporterQueue> invocations) {
633 DCHECK(invocations);
634 DCHECK(!invocations->empty());
635 auto next_invocation = invocations->front();
636 invocations->pop();
637
638 if (g_testing_delegate_)
639 g_testing_delegate_->NotifyLaunchReady();
640
641 // It's OK to simply |PostTaskAndReplyWithResult| so that
642 // |LaunchAndWaitForExit| doesn't need to access |main_thread_task_runner_|
643 // since the callback is not delayed and the test task runner won't need to
644 // force it.
645 base::PostTaskAndReplyWithResult(
646 blocking_task_runner_.get(), FROM_HERE,
647
648 // Send the head of the queue to the launch callback.
649 base::Bind(&LaunchAndWaitForExit, next_invocation),
650
651 // Send the tail of the queue to the next callback, which will handle
652 // the results of the first launch and then recursively launch
653 // everything in the tail.
654 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this),
655 base::Time::Now(), version_, next_invocation,
656 base::Passed(std::move(invocations))));
657 }
658
629 // This method is called on the UI thread when the reporter run has completed. 659 // This method is called on the UI thread when the reporter run has completed.
630 // This is run as a task posted from an interruptible worker thread so should 660 // This is run as a task posted from an interruptible worker thread so should
631 // be resilient to unexpected shutdown. 661 // be resilient to unexpected shutdown.
632 void ReporterDone(const base::Time& reporter_start_time, 662 void ReporterDone(const base::Time& reporter_start_time,
633 const base::Version& version, 663 const base::Version& version,
634 const SwReporterInvocation& finished_invocation, 664 const SwReporterInvocation& finished_invocation,
665 std::unique_ptr<SwReporterQueue> remaining_invocations,
635 int exit_code) { 666 int exit_code) {
636 DCHECK_CURRENTLY_ON(BrowserThread::UI); 667 DCHECK_CURRENTLY_ON(BrowserThread::UI);
637 668
638 if (g_testing_delegate_) 669 if (g_testing_delegate_)
639 g_testing_delegate_->NotifyReporterDone(); 670 g_testing_delegate_->NotifyReporterDone();
640 671
641 base::TimeDelta reporter_running_time = 672 base::TimeDelta reporter_running_time =
642 base::Time::Now() - reporter_start_time; 673 base::Time::Now() - reporter_start_time;
643 // Don't continue when the reporter process failed to launch, but still try 674
644 // again after the regular delay. It's not worth retrying earlier, risking 675 // Don't continue the current queue of reporters if one failed to launch.
645 // running too often if it always fails, since not many users fail here. 676 // As soon as we're not running this queue, schedule the next overall queue
646 main_thread_task_runner_->PostDelayedTask( 677 // run after the regular delay. (If there was a failure it's not worth
647 FROM_HERE, 678 // retrying earlier, risking running too often if it always fails, since
648 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), 679 // not many users fail here.)
649 base::TimeDelta::FromDays(days_between_reporter_runs_)); 680 if (!remaining_invocations->empty() &&
681 exit_code != kReporterFailureExitCode) {
682 LaunchNextInvocation(std::move(remaining_invocations));
683 } else {
684 main_thread_task_runner_->PostDelayedTask(
685 FROM_HERE,
686 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)),
687 base::TimeDelta::FromDays(days_between_reporter_runs_));
688 }
689
690 // If the reporter failed to launch, do not process the results. (The exit
691 // code itself doesn't need to be logged in this case because
692 // SW_REPORTER_FAILED_TO_START is logged in |LaunchAndWaitForExit|.)
650 if (exit_code == kReporterFailureExitCode) 693 if (exit_code == kReporterFailureExitCode)
651 return; 694 return;
652 695
653 UMAHistogramReporter uma(finished_invocation.suffix); 696 UMAHistogramReporter uma(finished_invocation.suffix);
654 uma.ReportVersion(version); 697 uma.ReportVersion(version);
655 uma.ReportExitCode(exit_code); 698 uma.ReportExitCode(exit_code);
656 uma.ReportFoundUwS(!finished_invocation.is_experimental /*use_rappor*/); 699 uma.ReportFoundUwS(finished_invocation.flags &
700 SwReporterInvocation::FLAG_LOG_TO_RAPPOR);
657 701
658 // Only save results from the canonical version of the software. 702 // Only save results from the canonical version of the software.
659 PrefService* local_state = g_browser_process->local_state(); 703 PrefService* local_state = g_browser_process->local_state();
660 if (local_state && !finished_invocation.is_experimental) { 704 if (local_state &&
705 (finished_invocation.flags & SwReporterInvocation::FLAG_LOG_TO_PREFS)) {
661 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); 706 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code);
662 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, 707 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered,
663 base::Time::Now().ToInternalValue()); 708 base::Time::Now().ToInternalValue());
664 } 709 }
665 uma.ReportRuntime(reporter_running_time); 710 uma.ReportRuntime(reporter_running_time);
666 uma.ReportScanTimes(); 711 uma.ReportScanTimes();
667 uma.ReportMemoryUsage(); 712 uma.ReportMemoryUsage();
668 713
669 // Only continue to launch the prompt for the canonical version. 714 if (!(finished_invocation.flags &
670 if (finished_invocation.is_experimental) 715 SwReporterInvocation::FLAG_TRIGGER_PROMPT))
671 return; 716 return;
672 717
673 if (!IsInSRTPromptFieldTrialGroups()) { 718 if (!IsInSRTPromptFieldTrialGroups()) {
674 // Knowing about disabled field trial is more important than reporter not 719 // Knowing about disabled field trial is more important than reporter not
675 // finding anything to remove, so check this case first. 720 // finding anything to remove, so check this case first.
676 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); 721 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL);
677 return; 722 return;
678 } 723 }
679 724
680 if (exit_code != kSwReporterPostRebootCleanupNeeded && 725 if (exit_code != kSwReporterPostRebootCleanupNeeded &&
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 RecordReporterStepHistogram(SW_REPORTER_RAN_DAILY); 759 RecordReporterStepHistogram(SW_REPORTER_RAN_DAILY);
715 } else { 760 } else {
716 days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; 761 days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns;
717 } 762 }
718 const base::Time last_time_triggered = base::Time::FromInternalValue( 763 const base::Time last_time_triggered = base::Time::FromInternalValue(
719 local_state->GetInt64(prefs::kSwReporterLastTimeTriggered)); 764 local_state->GetInt64(prefs::kSwReporterLastTimeTriggered));
720 base::TimeDelta next_trigger_delay( 765 base::TimeDelta next_trigger_delay(
721 last_time_triggered + 766 last_time_triggered +
722 base::TimeDelta::FromDays(days_between_reporter_runs_) - 767 base::TimeDelta::FromDays(days_between_reporter_runs_) -
723 base::Time::Now()); 768 base::Time::Now());
724 if (next_trigger_delay.ToInternalValue() <= 0 || 769 if (!invocations_.empty() &&
725 // Also make sure the kSwReporterLastTimeTriggered value is not set in 770 (next_trigger_delay.ToInternalValue() <= 0 ||
726 // the future. 771 // Also make sure the kSwReporterLastTimeTriggered value is not set in
727 last_time_triggered > base::Time::Now()) { 772 // the future.
728 if (g_testing_delegate_) 773 last_time_triggered > base::Time::Now())) {
729 g_testing_delegate_->NotifyLaunchReady(); 774 // Make a copy of the queue, since LaunchNextInvocation will pop items
730 775 // from it. We need to save the full original for the comparison in
731 // It's OK to simply |PostTaskAndReplyWithResult| so that 776 // Run.
732 // |LaunchAndWaitForExit| doesn't need to access 777 auto invocations = std::make_unique<SwReporterQueue>(invocations_);
733 // |main_thread_task_runner_| since the callback is not delayed and the 778 LaunchNextInvocation(std::move(invocations));
734 // test task runner won't need to force it.
735 base::PostTaskAndReplyWithResult(
736 blocking_task_runner_.get(), FROM_HERE,
737 base::Bind(&LaunchAndWaitForExit, invocation_),
738 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this),
739 base::Time::Now(), version_, invocation_));
740 } else { 779 } else {
741 main_thread_task_runner_->PostDelayedTask( 780 main_thread_task_runner_->PostDelayedTask(
742 FROM_HERE, 781 FROM_HERE,
743 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), 782 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)),
744 next_trigger_delay); 783 next_trigger_delay);
745 } 784 }
746 } 785 }
747 786
748 bool first_run_ = true; 787 bool first_run_ = true;
749 SwReporterInvocation invocation_; 788 SwReporterQueue invocations_;
750 base::Version version_; 789 base::Version version_;
751 scoped_refptr<base::TaskRunner> main_thread_task_runner_; 790 scoped_refptr<base::TaskRunner> main_thread_task_runner_;
752 scoped_refptr<base::TaskRunner> blocking_task_runner_; 791 scoped_refptr<base::TaskRunner> blocking_task_runner_;
753 792
754 // This value is used to identify how long to wait before starting a new run 793 // This value is used to identify how long to wait before starting a new run
755 // of the reporter. It's initialized with the default value and may be changed 794 // of the reporter. It's initialized with the default value and may be changed
756 // to a different value when a prompt is pending and the reporter should be 795 // to a different value when a prompt is pending and the reporter should be
757 // run before adding the global error to the Chrome menu. 796 // run before adding the global error to the Chrome menu.
758 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; 797 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns;
759 798
(...skipping 19 matching lines...) Expand all
779 818
780 SwReporterInvocation SwReporterInvocation::FromCommandLine( 819 SwReporterInvocation SwReporterInvocation::FromCommandLine(
781 const base::CommandLine& command_line) { 820 const base::CommandLine& command_line) {
782 SwReporterInvocation invocation; 821 SwReporterInvocation invocation;
783 invocation.command_line = command_line; 822 invocation.command_line = command_line;
784 return invocation; 823 return invocation;
785 } 824 }
786 825
787 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { 826 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const {
788 return command_line.argv() == other.command_line.argv() && 827 return command_line.argv() == other.command_line.argv() &&
789 suffix == other.suffix && is_experimental == other.is_experimental; 828 suffix == other.suffix && flags == other.flags;
790 } 829 }
791 830
792 void RunSwReporter(const SwReporterInvocation& invocation, 831 void RunSwReporters(const SwReporterQueue& invocations,
793 const base::Version& version, 832 const base::Version& version,
794 scoped_refptr<base::TaskRunner> main_thread_task_runner, 833 scoped_refptr<base::TaskRunner> main_thread_task_runner,
795 scoped_refptr<base::TaskRunner> blocking_task_runner) { 834 scoped_refptr<base::TaskRunner> blocking_task_runner) {
796 ReporterRunner::Run(invocation, version, std::move(main_thread_task_runner), 835 ReporterRunner::Run(invocations, version, std::move(main_thread_task_runner),
797 std::move(blocking_task_runner)); 836 std::move(blocking_task_runner));
798 } 837 }
799 838
800 bool ReporterFoundUws() { 839 bool ReporterFoundUws() {
801 PrefService* local_state = g_browser_process->local_state(); 840 PrefService* local_state = g_browser_process->local_state();
802 if (!local_state) 841 if (!local_state)
803 return false; 842 return false;
804 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); 843 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode);
805 return exit_code == kSwReporterCleanupNeeded; 844 return exit_code == kSwReporterCleanupNeeded;
806 } 845 }
807 846
808 bool UserHasRunCleaner() { 847 bool UserHasRunCleaner() {
809 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); 848 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey);
810 cleaner_key_path.append(L"\\").append(kCleanerSubKey); 849 cleaner_key_path.append(L"\\").append(kCleanerSubKey);
811 850
812 base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(), 851 base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(),
813 KEY_QUERY_VALUE); 852 KEY_QUERY_VALUE);
814 853
815 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; 854 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0;
816 } 855 }
817 856
818 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { 857 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) {
819 g_testing_delegate_ = delegate; 858 g_testing_delegate_ = delegate;
820 } 859 }
821 860
822 } // namespace safe_browsing 861 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698