OLD | NEW |
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/chrome_cleaner/reporter_runner_win.h" | 5 #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
11 #include <utility> | 11 #include <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/debug/leak_annotations.h" | 18 #include "base/debug/leak_annotations.h" |
19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
20 #include "base/macros.h" | 20 #include "base/macros.h" |
21 #include "base/memory/ptr_util.h" | 21 #include "base/memory/ptr_util.h" |
22 #include "base/metrics/field_trial.h" | 22 #include "base/metrics/field_trial.h" |
23 #include "base/metrics/histogram_macros.h" | 23 #include "base/metrics/histogram_macros.h" |
24 #include "base/metrics/sparse_histogram.h" | 24 #include "base/metrics/sparse_histogram.h" |
| 25 #include "base/process/launch.h" |
| 26 #include "base/process/process.h" |
25 #include "base/strings/string_number_conversions.h" | 27 #include "base/strings/string_number_conversions.h" |
26 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
27 #include "base/strings/utf_string_conversions.h" | 29 #include "base/strings/utf_string_conversions.h" |
28 #include "base/task_runner_util.h" | 30 #include "base/task_runner_util.h" |
29 #include "base/task_scheduler/post_task.h" | 31 #include "base/task_scheduler/post_task.h" |
30 #include "base/task_scheduler/task_traits.h" | 32 #include "base/task_scheduler/task_traits.h" |
31 #include "base/time/time.h" | |
32 #include "base/version.h" | 33 #include "base/version.h" |
33 #include "base/win/registry.h" | 34 #include "base/win/registry.h" |
34 #include "chrome/browser/browser_process.h" | 35 #include "chrome/browser/browser_process.h" |
35 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" | 36 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" |
36 #include "chrome/browser/profiles/profile.h" | 37 #include "chrome/browser/profiles/profile.h" |
37 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win
.h" | 38 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win
.h" |
38 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h" | |
39 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_client_info_win.h" | 39 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_client_info_win.h" |
| 40 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" |
40 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.h" | 41 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.h" |
41 #include "chrome/browser/ui/browser_finder.h" | 42 #include "chrome/browser/ui/browser_finder.h" |
42 #include "chrome/browser/ui/browser_list.h" | 43 #include "chrome/browser/ui/browser_list.h" |
43 #include "chrome/browser/ui/browser_list_observer.h" | 44 #include "chrome/browser/ui/browser_list_observer.h" |
44 #include "chrome/browser/ui/global_error/global_error_service.h" | 45 #include "chrome/browser/ui/global_error/global_error_service.h" |
45 #include "chrome/browser/ui/global_error/global_error_service_factory.h" | 46 #include "chrome/browser/ui/global_error/global_error_service_factory.h" |
46 #include "chrome/common/pref_names.h" | 47 #include "chrome/common/pref_names.h" |
47 #include "components/chrome_cleaner/public/constants/constants.h" | 48 #include "components/chrome_cleaner/public/constants/constants.h" |
48 #include "components/component_updater/pref_names.h" | 49 #include "components/component_updater/pref_names.h" |
49 #include "components/prefs/pref_service.h" | 50 #include "components/prefs/pref_service.h" |
50 #include "components/version_info/version_info.h" | 51 #include "components/version_info/version_info.h" |
51 #include "content/public/browser/browser_thread.h" | 52 #include "content/public/browser/browser_thread.h" |
52 #include "mojo/edk/embedder/connection_params.h" | |
53 #include "mojo/edk/embedder/outgoing_broker_client_invitation.h" | |
54 #include "mojo/edk/embedder/platform_channel_pair.h" | |
55 #include "mojo/public/cpp/system/message_pipe.h" | |
56 #include "net/http/http_status_code.h" | 53 #include "net/http/http_status_code.h" |
57 | 54 |
58 using content::BrowserThread; | 55 using content::BrowserThread; |
59 | 56 |
60 namespace safe_browsing { | 57 namespace safe_browsing { |
61 | 58 |
62 const base::Feature kInBrowserCleanerUIFeature{ | |
63 "InBrowserCleanerUI", base::FEATURE_DISABLED_BY_DEFAULT}; | |
64 | |
65 namespace { | 59 namespace { |
66 | 60 |
67 // Used to send UMA information about missing start and end time registry | 61 // Used to send UMA information about missing start and end time registry |
68 // values for the reporter. Replicated in the histograms.xml file, so the order | 62 // values for the reporter. Replicated in the histograms.xml file, so the order |
69 // MUST NOT CHANGE. | 63 // MUST NOT CHANGE. |
70 enum SwReporterRunningTimeRegistryError { | 64 enum SwReporterRunningTimeRegistryError { |
71 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, | 65 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, |
72 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, | 66 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, |
73 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, | 67 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, |
74 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, | 68 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 if (error->GetBubbleView()) { | 537 if (error->GetBubbleView()) { |
544 show_bubble = false; | 538 show_bubble = false; |
545 break; | 539 break; |
546 } | 540 } |
547 } | 541 } |
548 } | 542 } |
549 if (show_bubble) | 543 if (show_bubble) |
550 global_error->ShowBubbleView(browser); | 544 global_error->ShowBubbleView(browser); |
551 } | 545 } |
552 | 546 |
553 // Handles the case when the remote end has been closed, by performing the | 547 // This function is called from a worker thread to launch the SwReporter and |
554 // necessary cleanups if the prompt dialog is being shown to the user. | 548 // wait for termination to collect its exit code. This task could be |
555 void OnConnectionClosed() { | 549 // interrupted by a shutdown at any time, so it shouldn't depend on anything |
556 // Placeholder. This should handle cases when the reporter process is | 550 // external that could be shut down beforehand. |
557 // disconnected (e.g. due to a crash) and the prompt dialog is being shown | 551 int LaunchAndWaitForExitOnBackgroundThread( |
558 // to the user. | 552 const SwReporterInvocation& invocation) { |
559 } | 553 if (g_testing_delegate_) |
560 | 554 return g_testing_delegate_->LaunchReporter(invocation); |
561 // Handles the case when a mojo::ReportBadMessage has been explicitly reported. | |
562 void OnConnectionError(const std::string& message) { | |
563 // Placeholder. This should handle cases when the reporter process sends | |
564 // a bad message and the prompt dialog is being shown to the user. | |
565 } | |
566 | |
567 // Class responsible for launching the reporter process and waiting for its | |
568 // completion. If feature InBrowserCleanerUI is enabled, this object will also | |
569 // be responsible for starting the ChromePromptImpl object on the IO thread and | |
570 // controlling its lifetime. | |
571 // | |
572 // Expected lifecycle of a SwReporterProcess: | |
573 // - created on the UI thread before the reporter process launch is posted | |
574 // (method ScheduleNextInvocation); | |
575 // - deleted on the UI thread once ReporterDone() finishes (the method is | |
576 // called after the reporter process exits). | |
577 // | |
578 // If feature InBrowserCleanerUI feature is enabled, the following tasks will | |
579 // be posted in sequence to the IO Thread and will retain the SwReporterProcess | |
580 // object: | |
581 // - creation of a ChromePromptImpl object right after the reporter process is | |
582 // launched (that object will be responsible for handling IPC requests from | |
583 // the reporter process); | |
584 // - deletion of the ChromePromptImpl object on ReporterDone(). | |
585 // As a consequence, the SwReporterProcess object can outlive ReporterDone() | |
586 // and will only be deleted after the ChromePromptImpl object is released on | |
587 // the IO thread. | |
588 class SwReporterProcess : public base::RefCountedThreadSafe<SwReporterProcess> { | |
589 public: | |
590 explicit SwReporterProcess(const SwReporterInvocation& invocation) | |
591 : invocation_(invocation) {} | |
592 | |
593 // This function is called from a worker thread to launch the SwReporter and | |
594 // wait for termination to collect its exit code. This task could be | |
595 // interrupted by a shutdown at any time, so it shouldn't depend on anything | |
596 // external that could be shut down beforehand. | |
597 int LaunchAndWaitForExitOnBackgroundThread(); | |
598 | |
599 // Schedules to release the instance of ChromePromptImpl on the IO thread. | |
600 void OnReporterDone(); | |
601 | |
602 const SwReporterInvocation& invocation() const { return invocation_; } | |
603 | |
604 private: | |
605 friend class base::RefCountedThreadSafe<SwReporterProcess>; | |
606 ~SwReporterProcess() = default; | |
607 | |
608 // Starts a new IPC service implementing the ChromePrompt interface and | |
609 // launches a new reporter process that can connect to the IPC. | |
610 base::Process LaunchConnectedReporterProcess(); | |
611 | |
612 // Starts a new instance of ChromePromptImpl to receive requests from the | |
613 // reporter and establishes the mojo connection to it. | |
614 // Must be run on the IO thread. | |
615 void CreateChromePromptImpl( | |
616 chrome_cleaner::mojom::ChromePromptRequest chrome_prompt_request); | |
617 | |
618 // Releases the instance of ChromePromptImpl. Must be run on the IO thread. | |
619 void ReleaseChromePromptImpl(); | |
620 | |
621 // Launches a new process with the command line in the invocation and | |
622 // provided launch options. Uses g_testing_delegate_ if not null. | |
623 base::Process LaunchReporterProcess( | |
624 const SwReporterInvocation& invocation, | |
625 const base::LaunchOptions& launch_options); | |
626 | |
627 // The invocation for the current reporter process. | |
628 SwReporterInvocation invocation_; | |
629 | |
630 // Implementation of the ChromePrompt service to be used by the current | |
631 // reporter process. Can only be accessed on the IO thread. | |
632 std::unique_ptr<ChromePromptImpl> chrome_prompt_impl_; | |
633 }; | |
634 | |
635 int SwReporterProcess::LaunchAndWaitForExitOnBackgroundThread() { | |
636 base::Process reporter_process = | 555 base::Process reporter_process = |
637 base::FeatureList::IsEnabled(kInBrowserCleanerUIFeature) | 556 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); |
638 ? LaunchConnectedReporterProcess() | |
639 : LaunchReporterProcess(invocation_, base::LaunchOptions()); | |
640 | |
641 // This exit code is used to identify that a reporter run didn't happen, so | 557 // This exit code is used to identify that a reporter run didn't happen, so |
642 // the result should be ignored and a rerun scheduled for the usual delay. | 558 // the result should be ignored and a rerun scheduled for the usual delay. |
643 int exit_code = kReporterNotLaunchedExitCode; | 559 int exit_code = kReporterNotLaunchedExitCode; |
644 UMAHistogramReporter uma(invocation_.suffix); | 560 UMAHistogramReporter uma(invocation.suffix); |
645 if (reporter_process.IsValid()) { | 561 if (reporter_process.IsValid()) { |
646 uma.RecordReporterStep(SW_REPORTER_START_EXECUTION); | 562 uma.RecordReporterStep(SW_REPORTER_START_EXECUTION); |
647 bool success = reporter_process.WaitForExit(&exit_code); | 563 bool success = reporter_process.WaitForExit(&exit_code); |
648 DCHECK(success); | 564 DCHECK(success); |
649 } else { | 565 } else { |
650 uma.RecordReporterStep(SW_REPORTER_FAILED_TO_START); | 566 uma.RecordReporterStep(SW_REPORTER_FAILED_TO_START); |
651 } | 567 } |
652 return exit_code; | 568 return exit_code; |
653 } | 569 } |
654 | 570 |
655 void SwReporterProcess::OnReporterDone() { | |
656 if (base::FeatureList::IsEnabled(kInBrowserCleanerUIFeature)) { | |
657 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO) | |
658 ->PostTask(FROM_HERE, | |
659 base::Bind(&SwReporterProcess::ReleaseChromePromptImpl, | |
660 base::RetainedRef(this))); | |
661 } | |
662 } | |
663 | |
664 base::Process SwReporterProcess::LaunchConnectedReporterProcess() { | |
665 DCHECK(base::FeatureList::IsEnabled(kInBrowserCleanerUIFeature)); | |
666 | |
667 mojo::edk::OutgoingBrokerClientInvitation invitation; | |
668 std::string mojo_pipe_token = mojo::edk::GenerateRandomToken(); | |
669 mojo::ScopedMessagePipeHandle mojo_pipe = | |
670 invitation.AttachMessagePipe(mojo_pipe_token); | |
671 invocation_.command_line.AppendSwitchASCII( | |
672 chrome_cleaner::kChromeMojoPipeTokenSwitch, mojo_pipe_token); | |
673 invocation_.command_line.AppendSwitchASCII( | |
674 chrome_cleaner::kExecutionModeSwitch, | |
675 base::IntToString( | |
676 static_cast<int>(chrome_cleaner::ExecutionMode::kScanning))); | |
677 | |
678 mojo::edk::PlatformChannelPair channel; | |
679 base::HandlesToInheritVector handles_to_inherit; | |
680 channel.PrepareToPassClientHandleToChildProcess(&invocation_.command_line, | |
681 &handles_to_inherit); | |
682 | |
683 base::LaunchOptions launch_options; | |
684 launch_options.handles_to_inherit = &handles_to_inherit; | |
685 base::Process reporter_process = | |
686 LaunchReporterProcess(invocation_, launch_options); | |
687 | |
688 if (!reporter_process.IsValid()) | |
689 return reporter_process; | |
690 | |
691 // ChromePromptImpl tasks will need to run on the IO thread. There is no | |
692 // need to synchronize its creation, since the client end will wait for this | |
693 // initialization to be done before sending requests. | |
694 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO) | |
695 ->PostTask(FROM_HERE, | |
696 base::BindOnce(&SwReporterProcess::CreateChromePromptImpl, | |
697 base::RetainedRef(this), | |
698 chrome_cleaner::mojom::ChromePromptRequest( | |
699 std::move(mojo_pipe)))); | |
700 | |
701 mojo::edk::ProcessErrorCallback on_connection_error = | |
702 g_testing_delegate_ | |
703 ? base::Bind(&SwReporterTestingDelegate::OnConnectionError, | |
704 base::Unretained(g_testing_delegate_)) | |
705 : base::Bind(&OnConnectionError); | |
706 invitation.Send( | |
707 reporter_process.Handle(), | |
708 mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy, | |
709 channel.PassServerHandle()), | |
710 on_connection_error); | |
711 | |
712 return reporter_process; | |
713 } | |
714 | |
715 base::Process SwReporterProcess::LaunchReporterProcess( | |
716 const SwReporterInvocation& invocation, | |
717 const base::LaunchOptions& launch_options) { | |
718 return g_testing_delegate_ | |
719 ? g_testing_delegate_->LaunchReporter(invocation, launch_options) | |
720 : base::LaunchProcess(invocation.command_line, launch_options); | |
721 } | |
722 | |
723 void SwReporterProcess::CreateChromePromptImpl( | |
724 chrome_cleaner::mojom::ChromePromptRequest chrome_prompt_request) { | |
725 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
726 DCHECK(base::FeatureList::IsEnabled(kInBrowserCleanerUIFeature)); | |
727 | |
728 chrome_prompt_impl_ = | |
729 g_testing_delegate_ | |
730 ? g_testing_delegate_->CreateChromePromptImpl( | |
731 std::move(chrome_prompt_request)) | |
732 : base::MakeUnique<ChromePromptImpl>(std::move(chrome_prompt_request), | |
733 base::Bind(&OnConnectionClosed)); | |
734 } | |
735 | |
736 void SwReporterProcess::ReleaseChromePromptImpl() { | |
737 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
738 DCHECK(base::FeatureList::IsEnabled(kInBrowserCleanerUIFeature)); | |
739 | |
740 chrome_prompt_impl_.release(); | |
741 } | |
742 | |
743 } // namespace | 571 } // namespace |
744 | 572 |
745 void DisplaySRTPromptForTesting(const base::FilePath& download_path) { | 573 void DisplaySRTPromptForTesting(const base::FilePath& download_path) { |
746 DisplaySRTPrompt(download_path, net::HTTP_OK); | 574 DisplaySRTPrompt(download_path, net::HTTP_OK); |
747 } | 575 } |
748 | 576 |
749 namespace { | 577 namespace { |
750 | 578 |
751 // Try to fetch the SRT, and on success, show the prompt to run it. | 579 // Try to fetch the SRT, and on success, show the prompt to run it. |
752 void MaybeFetchSRT(Browser* browser, const base::Version& reporter_version) { | 580 void MaybeFetchSRT(Browser* browser, const base::Version& reporter_version) { |
(...skipping 25 matching lines...) Expand all Loading... |
778 prefs->SetString(prefs::kSwReporterPromptSeed, incoming_seed); | 606 prefs->SetString(prefs::kSwReporterPromptSeed, incoming_seed); |
779 // Forget about pending prompts if prompt seed has changed. | 607 // Forget about pending prompts if prompt seed has changed. |
780 if (local_state) | 608 if (local_state) |
781 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); | 609 local_state->SetBoolean(prefs::kSwReporterPendingPrompt, false); |
782 } | 610 } |
783 prefs->SetString(prefs::kSwReporterPromptVersion, | 611 prefs->SetString(prefs::kSwReporterPromptVersion, |
784 reporter_version.GetString()); | 612 reporter_version.GetString()); |
785 | 613 |
786 // Download the SRT. | 614 // Download the SRT. |
787 RecordReporterStepHistogram(SW_REPORTER_DOWNLOAD_START); | 615 RecordReporterStepHistogram(SW_REPORTER_DOWNLOAD_START); |
788 | |
789 // All the work happens in the self-deleting class below. | |
790 FetchChromeCleaner(base::Bind(DisplaySRTPrompt)); | 616 FetchChromeCleaner(base::Bind(DisplaySRTPrompt)); |
791 } | 617 } |
792 | 618 |
793 base::Time Now() { | 619 base::Time Now() { |
794 return g_testing_delegate_ ? g_testing_delegate_->Now() : base::Time::Now(); | 620 return g_testing_delegate_ ? g_testing_delegate_->Now() : base::Time::Now(); |
795 } | 621 } |
796 | 622 |
797 } // namespace | 623 } // namespace |
798 | 624 |
799 // This class tries to run a queue of reporters and react to their exit codes. | 625 // This class tries to run a queue of reporters and react to their exit codes. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 void ScheduleNextInvocation() { | 670 void ScheduleNextInvocation() { |
845 DCHECK(!current_invocations_.empty()); | 671 DCHECK(!current_invocations_.empty()); |
846 auto next_invocation = current_invocations_.front(); | 672 auto next_invocation = current_invocations_.front(); |
847 current_invocations_.pop(); | 673 current_invocations_.pop(); |
848 | 674 |
849 AppendInvocationSpecificSwitches(&next_invocation); | 675 AppendInvocationSpecificSwitches(&next_invocation); |
850 | 676 |
851 base::TaskRunner* task_runner = | 677 base::TaskRunner* task_runner = |
852 g_testing_delegate_ ? g_testing_delegate_->BlockingTaskRunner() | 678 g_testing_delegate_ ? g_testing_delegate_->BlockingTaskRunner() |
853 : blocking_task_runner_.get(); | 679 : blocking_task_runner_.get(); |
854 auto sw_reporter_process = | |
855 make_scoped_refptr(new SwReporterProcess(next_invocation)); | |
856 auto launch_and_wait = | 680 auto launch_and_wait = |
857 base::Bind(&SwReporterProcess::LaunchAndWaitForExitOnBackgroundThread, | 681 base::Bind(&LaunchAndWaitForExitOnBackgroundThread, next_invocation); |
858 sw_reporter_process); | |
859 auto reporter_done = | 682 auto reporter_done = |
860 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), Now(), | 683 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), Now(), |
861 version_, std::move(sw_reporter_process)); | 684 version_, next_invocation); |
862 base::PostTaskAndReplyWithResult(task_runner, FROM_HERE, | 685 base::PostTaskAndReplyWithResult(task_runner, FROM_HERE, |
863 std::move(launch_and_wait), | 686 std::move(launch_and_wait), |
864 std::move(reporter_done)); | 687 std::move(reporter_done)); |
865 } | 688 } |
866 | 689 |
867 // This method is called on the UI thread when an invocation of the reporter | 690 // This method is called on the UI thread when an invocation of the reporter |
868 // has completed. This is run as a task posted from an interruptible worker | 691 // has completed. This is run as a task posted from an interruptible worker |
869 // thread so should be resilient to unexpected shutdown. | 692 // thread so should be resilient to unexpected shutdown. |
870 void ReporterDone(const base::Time& reporter_start_time, | 693 void ReporterDone(const base::Time& reporter_start_time, |
871 const base::Version& version, | 694 const base::Version& version, |
872 scoped_refptr<SwReporterProcess> sw_reporter_process, | 695 const SwReporterInvocation& finished_invocation, |
873 int exit_code) { | 696 int exit_code) { |
874 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 697 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
875 | 698 |
876 sw_reporter_process->OnReporterDone(); | |
877 | |
878 base::Time now = Now(); | 699 base::Time now = Now(); |
879 base::TimeDelta reporter_running_time = now - reporter_start_time; | 700 base::TimeDelta reporter_running_time = now - reporter_start_time; |
880 | 701 |
881 // Don't continue the current queue of reporters if one failed to launch. | 702 // Don't continue the current queue of reporters if one failed to launch. |
882 if (exit_code == kReporterNotLaunchedExitCode) | 703 if (exit_code == kReporterNotLaunchedExitCode) |
883 current_invocations_ = SwReporterQueue(); | 704 current_invocations_ = SwReporterQueue(); |
884 | 705 |
885 // As soon as we're not running this queue, schedule the next overall queue | 706 // As soon as we're not running this queue, schedule the next overall queue |
886 // run after the regular delay. (If there was a failure it's not worth | 707 // run after the regular delay. (If there was a failure it's not worth |
887 // retrying earlier, risking running too often if it always fails, since | 708 // retrying earlier, risking running too often if it always fails, since |
888 // not many users fail here.) | 709 // not many users fail here.) |
889 if (current_invocations_.empty()) { | 710 if (current_invocations_.empty()) { |
890 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 711 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
891 FROM_HERE, | 712 FROM_HERE, |
892 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 713 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
893 base::TimeDelta::FromDays(days_between_reporter_runs_)); | 714 base::TimeDelta::FromDays(days_between_reporter_runs_)); |
894 } else { | 715 } else { |
895 ScheduleNextInvocation(); | 716 ScheduleNextInvocation(); |
896 } | 717 } |
897 | 718 |
898 // If the reporter failed to launch, do not process the results. (The exit | 719 // If the reporter failed to launch, do not process the results. (The exit |
899 // code itself doesn't need to be logged in this case because | 720 // code itself doesn't need to be logged in this case because |
900 // SW_REPORTER_FAILED_TO_START is logged in | 721 // SW_REPORTER_FAILED_TO_START is logged in |
901 // |LaunchAndWaitForExitOnBackgroundThread|.) | 722 // |LaunchAndWaitForExitOnBackgroundThread|.) |
902 if (exit_code == kReporterNotLaunchedExitCode) | 723 if (exit_code == kReporterNotLaunchedExitCode) |
903 return; | 724 return; |
904 | 725 |
905 const auto& finished_invocation = sw_reporter_process->invocation(); | |
906 UMAHistogramReporter uma(finished_invocation.suffix); | 726 UMAHistogramReporter uma(finished_invocation.suffix); |
907 uma.ReportVersion(version); | 727 uma.ReportVersion(version); |
908 uma.ReportExitCode(exit_code); | 728 uma.ReportExitCode(exit_code); |
909 uma.ReportEngineErrorCode(); | 729 uma.ReportEngineErrorCode(); |
910 uma.ReportFoundUwS(); | 730 uma.ReportFoundUwS(); |
911 | 731 |
912 PrefService* local_state = g_browser_process->local_state(); | 732 PrefService* local_state = g_browser_process->local_state(); |
913 if (local_state) { | 733 if (local_state) { |
914 if (finished_invocation.BehaviourIsSupported( | 734 if (finished_invocation.BehaviourIsSupported( |
915 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS)) { | 735 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS)) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 return srt_cleaner_key.Open(HKEY_CURRENT_USER, cleaner_key_path.c_str(), | 987 return srt_cleaner_key.Open(HKEY_CURRENT_USER, cleaner_key_path.c_str(), |
1168 KEY_QUERY_VALUE) == ERROR_SUCCESS && | 988 KEY_QUERY_VALUE) == ERROR_SUCCESS && |
1169 srt_cleaner_key.GetValueCount() > 0; | 989 srt_cleaner_key.GetValueCount() > 0; |
1170 } | 990 } |
1171 | 991 |
1172 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { | 992 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { |
1173 g_testing_delegate_ = delegate; | 993 g_testing_delegate_ = delegate; |
1174 } | 994 } |
1175 | 995 |
1176 } // namespace safe_browsing | 996 } // namespace safe_browsing |
OLD | NEW |