Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / srt_global_error_win.cc
blob21c858026349ddbd0ff5a1a78ef6ddb4da4eba47
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
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/srt_global_error_win.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/command_line.h"
11 #include "base/files/file_util.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/process/launch.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/safe_browsing/srt_field_trial_win.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/global_error/global_error_service.h"
22 #include "components/component_updater/pref_names.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "grit/chromium_strings.h"
25 #include "grit/generated_resources.h"
26 #include "ui/base/l10n/l10n_util.h"
28 using base::SingleThreadTaskRunner;
29 using base::ThreadTaskRunnerHandle;
30 using content::BrowserThread;
32 namespace {
34 // Used as a backup plan in case the SRT executable was not successfully
35 // downloaded or run.
36 const char kSRTDownloadURL[] =
37 "https://www.google.com/chrome/srt/?chrome-prompt=1";
39 // The extension to use to replace the temporary one created when the SRT was
40 // downloaded.
41 const base::FilePath::CharType kExecutableExtension[] = L"exe";
43 // A switch to add to the command line when executing the SRT.
44 const char kChromePromptSwitch[] = "chrome-prompt";
46 void MaybeExecuteSRTFromBlockingPool(
47 const base::FilePath& downloaded_path,
48 const scoped_refptr<SingleThreadTaskRunner>& task_runner,
49 const base::Closure& success_callback,
50 const base::Closure& failure_callback) {
51 DCHECK(!downloaded_path.empty());
53 if (base::PathExists(downloaded_path)) {
54 base::FilePath executable_path(
55 downloaded_path.ReplaceExtension(kExecutableExtension));
56 if (base::ReplaceFile(downloaded_path, executable_path, NULL)) {
57 base::CommandLine srt_command_line(executable_path);
58 srt_command_line.AppendSwitch(kChromePromptSwitch);
59 base::Process srt_process(
60 base::LaunchProcess(srt_command_line, base::LaunchOptions()));
61 if (srt_process.IsValid()) {
62 task_runner->PostTask(FROM_HERE, success_callback);
63 return;
68 task_runner->PostTask(FROM_HERE, failure_callback);
71 void DeleteFilesFromBlockingPool(const base::FilePath& downloaded_path) {
72 base::DeleteFile(downloaded_path, false);
73 base::DeleteFile(downloaded_path.ReplaceExtension(kExecutableExtension),
74 false);
77 } // namespace
79 // SRTGlobalError ------------------------------------------------------------
81 SRTGlobalError::SRTGlobalError(GlobalErrorService* global_error_service,
82 const base::FilePath& downloaded_path)
83 : global_error_service_(global_error_service),
84 downloaded_path_(downloaded_path) {
85 DCHECK(global_error_service_);
88 SRTGlobalError::~SRTGlobalError() {
91 bool SRTGlobalError::HasMenuItem() {
92 return true;
95 int SRTGlobalError::MenuItemCommandID() {
96 return IDC_SHOW_SRT_BUBBLE;
99 base::string16 SRTGlobalError::MenuItemLabel() {
100 return l10n_util::GetStringUTF16(IDS_SRT_MENU_ITEM);
103 void SRTGlobalError::ExecuteMenuItem(Browser* browser) {
104 safe_browsing::RecordSRTPromptHistogram(
105 safe_browsing::SRT_PROMPT_SHOWN_FROM_MENU);
106 show_dismiss_button_ = true;
107 ShowBubbleView(browser);
110 void SRTGlobalError::ShowBubbleView(Browser* browser) {
111 safe_browsing::RecordSRTPromptHistogram(safe_browsing::SRT_PROMPT_SHOWN);
112 GlobalErrorWithStandardBubble::ShowBubbleView(browser);
115 bool SRTGlobalError::ShouldShowCloseButton() const {
116 return true;
119 base::string16 SRTGlobalError::GetBubbleViewTitle() {
120 return l10n_util::GetStringUTF16(IDS_SRT_BUBBLE_TITLE);
123 std::vector<base::string16> SRTGlobalError::GetBubbleViewMessages() {
124 std::vector<base::string16> messages;
125 messages.push_back(l10n_util::GetStringUTF16(IDS_SRT_BUBBLE_TEXT));
126 return messages;
129 base::string16 SRTGlobalError::GetBubbleViewAcceptButtonLabel() {
130 return downloaded_path_.empty()
131 ? l10n_util::GetStringUTF16(IDS_SRT_BUBBLE_DOWNLOAD_BUTTON_TEXT)
132 : l10n_util::GetStringUTF16(IDS_SRT_BUBBLE_RUN_BUTTON_TEXT);
135 bool SRTGlobalError::ShouldAddElevationIconToAcceptButton() {
136 return !downloaded_path_.empty() &&
137 safe_browsing::SRTPromptNeedsElevationIcon();
140 base::string16 SRTGlobalError::GetBubbleViewCancelButtonLabel() {
141 if (show_dismiss_button_)
142 return l10n_util::GetStringUTF16(IDS_SRT_BUBBLE_DISMISS);
143 return base::string16();
146 void SRTGlobalError::OnBubbleViewDidClose(Browser* browser) {
147 // This won't happen when user interacted with the bubble since DestroySelf is
148 // called in those cases and will prevent the base class from calling virtual
149 // methods. This DCHECK makes sure that behavior won't change.
150 DCHECK(!interacted_);
151 safe_browsing::RecordSRTPromptHistogram(safe_browsing::SRT_PROMPT_CLOSED);
152 g_browser_process->local_state()->SetBoolean(prefs::kSwReporterPendingPrompt,
153 true);
156 void SRTGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) {
157 safe_browsing::RecordSRTPromptHistogram(safe_browsing::SRT_PROMPT_ACCEPTED);
158 interacted_ = true;
159 global_error_service_->RemoveGlobalError(this);
160 MaybeExecuteSRT();
163 void SRTGlobalError::BubbleViewCancelButtonPressed(Browser* browser) {
164 safe_browsing::RecordSRTPromptHistogram(safe_browsing::SRT_PROMPT_DENIED);
165 interacted_ = true;
166 global_error_service_->RemoveGlobalError(this);
168 BrowserThread::PostBlockingPoolTask(
169 FROM_HERE, base::Bind(&DeleteFilesFromBlockingPool, downloaded_path_));
170 DestroySelf();
173 bool SRTGlobalError::ShouldCloseOnDeactivate() const {
174 return false;
177 void SRTGlobalError::MaybeExecuteSRT() {
178 if (downloaded_path_.empty()) {
179 FallbackToDownloadPage();
180 return;
182 // At this point, this object owns itself, since ownership has been taken back
183 // from the global_error_service_ in the call to RemoveGlobalError. This means
184 // that it is safe to use base::Unretained here.
185 BrowserThread::PostBlockingPoolTask(
186 FROM_HERE, base::Bind(&MaybeExecuteSRTFromBlockingPool, downloaded_path_,
187 base::ThreadTaskRunnerHandle::Get(),
188 base::Bind(&SRTGlobalError::DestroySelf,
189 base::Unretained(this)),
190 base::Bind(&SRTGlobalError::FallbackToDownloadPage,
191 base::Unretained(this))));
194 void SRTGlobalError::FallbackToDownloadPage() {
195 safe_browsing::RecordSRTPromptHistogram(safe_browsing::SRT_PROMPT_FALLBACK);
197 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
198 Browser* browser = chrome::FindLastActiveWithHostDesktopType(desktop_type);
199 if (browser) {
200 browser->OpenURL(content::OpenURLParams(
201 GURL(kSRTDownloadURL), content::Referrer(), NEW_FOREGROUND_TAB,
202 ui::PAGE_TRANSITION_LINK, false));
205 BrowserThread::PostBlockingPoolTask(
206 FROM_HERE, base::Bind(&DeleteFilesFromBlockingPool, downloaded_path_));
207 DestroySelf();
210 void SRTGlobalError::DestroySelf() {
211 // This should only happen when user interacted with the bubble.
212 DCHECK(interacted_);
213 g_browser_process->local_state()->SetBoolean(prefs::kSwReporterPendingPrompt,
214 false);
215 delete this;