OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/download/download_danger_prompt.h" | 5 #include "chrome/browser/download/download_danger_prompt.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 8 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
9 #include "chrome/browser/ui/tab_modal_confirm_dialog.h" | 9 #include "chrome/browser/ui/tab_modal_confirm_dialog.h" |
10 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h" | 10 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h" |
| 11 #include "chrome/common/chrome_notification_types.h" |
11 #include "content/public/browser/download_danger_type.h" | 12 #include "content/public/browser/download_danger_type.h" |
12 #include "content/public/browser/download_item.h" | 13 #include "content/public/browser/download_item.h" |
13 #include "grit/generated_resources.h" | 14 #include "grit/generated_resources.h" |
14 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 // Implements DownloadDangerPrompt using a TabModalConfirmDialog. | 19 // Implements DownloadDangerPrompt using a TabModalConfirmDialog. |
19 class DownloadDangerPromptImpl | 20 class DownloadDangerPromptImpl |
20 : public DownloadDangerPrompt, | 21 : public DownloadDangerPrompt, |
21 public content::DownloadItem::Observer, | 22 public content::DownloadItem::Observer, |
22 public TabModalConfirmDialogDelegate { | 23 public TabModalConfirmDialogDelegate { |
23 public: | 24 public: |
24 DownloadDangerPromptImpl(content::DownloadItem* item, | 25 DownloadDangerPromptImpl(content::DownloadItem* item, |
25 content::WebContents* web_contents, | 26 content::WebContents* web_contents, |
26 bool show_context, | 27 bool show_context, |
27 const base::Closure& accepted, | 28 const base::Closure& accepted, |
28 const base::Closure& canceled); | 29 const base::Closure& canceled, |
| 30 const base::Closure& destroyed); |
29 virtual ~DownloadDangerPromptImpl(); | 31 virtual ~DownloadDangerPromptImpl(); |
30 | 32 |
31 // DownloadDangerPrompt | 33 // DownloadDangerPrompt |
32 virtual void InvokeActionForTesting(Action action) OVERRIDE; | 34 virtual void InvokeActionForTesting(Action action) OVERRIDE; |
33 | 35 |
34 private: | 36 private: |
35 // content::DownloadItem::Observer | 37 // content::DownloadItem::Observer |
36 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; | 38 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; |
37 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE; | 39 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE; |
38 | 40 |
39 // TabModalConfirmDialogDelegate | 41 // TabModalConfirmDialogDelegate |
40 virtual string16 GetTitle() OVERRIDE; | 42 virtual string16 GetTitle() OVERRIDE; |
41 virtual string16 GetMessage() OVERRIDE; | 43 virtual string16 GetMessage() OVERRIDE; |
42 virtual string16 GetAcceptButtonTitle() OVERRIDE; | 44 virtual string16 GetAcceptButtonTitle() OVERRIDE; |
43 virtual void OnAccepted() OVERRIDE; | 45 virtual void OnAccepted() OVERRIDE; |
44 virtual void OnCanceled() OVERRIDE; | 46 virtual void OnCanceled() OVERRIDE; |
45 | 47 |
| 48 // content::NotificationObserver implementation. |
| 49 virtual void Observe( |
| 50 int type, |
| 51 const content::NotificationSource& source, |
| 52 const content::NotificationDetails& details) OVERRIDE; |
| 53 |
46 // Runs |callback|. PrepareToClose() is called beforehand. Doing so prevents | 54 // Runs |callback|. PrepareToClose() is called beforehand. Doing so prevents |
47 // this object from responding to state changes in |download_| that might | 55 // this object from responding to state changes in |download_| that might |
48 // result from invoking the callback. |callback| must refer to either | 56 // result from invoking the callback. |callback| must refer to either |
49 // |accepted_| or |canceled_|. | 57 // |accepted_| or |canceled_|. |
50 void RunCallback(const base::Closure& callback); | 58 void RunCallback(const base::Closure& callback); |
51 | 59 |
52 // Resets |accepted_|, |canceled_| and removes the observer from |download_|, | 60 // Resets |accepted_|, |canceled_| and removes the observer from |download_|, |
53 // in preparation for closing the prompt. | 61 // in preparation for closing the prompt. |
54 void PrepareToClose(); | 62 void PrepareToClose(); |
55 | 63 |
56 content::DownloadItem* download_; | 64 content::DownloadItem* download_; |
57 bool show_context_; | 65 bool show_context_; |
58 base::Closure accepted_; | 66 base::Closure accepted_; |
59 base::Closure canceled_; | 67 base::Closure canceled_; |
| 68 base::Closure destroyed_; |
60 | 69 |
61 DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptImpl); | 70 DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptImpl); |
62 }; | 71 }; |
63 | 72 |
64 DownloadDangerPromptImpl::DownloadDangerPromptImpl( | 73 DownloadDangerPromptImpl::DownloadDangerPromptImpl( |
65 content::DownloadItem* download, | 74 content::DownloadItem* download, |
66 content::WebContents* web_contents, | 75 content::WebContents* web_contents, |
67 bool show_context, | 76 bool show_context, |
68 const base::Closure& accepted, | 77 const base::Closure& accepted, |
69 const base::Closure& canceled) | 78 const base::Closure& canceled, |
| 79 const base::Closure& destroyed) |
70 : TabModalConfirmDialogDelegate(web_contents), | 80 : TabModalConfirmDialogDelegate(web_contents), |
71 download_(download), | 81 download_(download), |
72 show_context_(show_context), | 82 show_context_(show_context), |
73 accepted_(accepted), | 83 accepted_(accepted), |
74 canceled_(canceled) { | 84 canceled_(canceled), |
| 85 destroyed_(destroyed) { |
75 DCHECK(!accepted_.is_null()); | 86 DCHECK(!accepted_.is_null()); |
76 // canceled_ is allowed to be null. | 87 // canceled_ is allowed to be null. |
77 DCHECK(download_); | 88 DCHECK(download_); |
78 download_->AddObserver(this); | 89 download_->AddObserver(this); |
79 } | 90 } |
80 | 91 |
81 DownloadDangerPromptImpl::~DownloadDangerPromptImpl() { | 92 DownloadDangerPromptImpl::~DownloadDangerPromptImpl() { |
82 // |this| might be deleted without invoking any callbacks. E.g. pressing Esc | 93 // |this| might be deleted without invoking any callbacks. E.g. pressing Esc |
83 // on GTK or if the user navigates away from the page showing the prompt. | 94 // on GTK or if the user navigates away from the page showing the prompt. |
| 95 base::Closure destroyed = destroyed_; |
| 96 destroyed_.Reset(); |
84 PrepareToClose(); | 97 PrepareToClose(); |
| 98 if (!destroyed.is_null()) |
| 99 destroyed.Run(); |
85 } | 100 } |
86 | 101 |
87 void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) { | 102 void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) { |
88 if (action == ACCEPT) | 103 if (action == ACCEPT) |
89 Accept(); | 104 Accept(); |
90 else | 105 else |
91 Cancel(); | 106 Cancel(); |
92 } | 107 } |
93 | 108 |
94 void DownloadDangerPromptImpl::OnDownloadUpdated( | 109 void DownloadDangerPromptImpl::OnDownloadUpdated( |
95 content::DownloadItem* download) { | 110 content::DownloadItem* download) { |
96 // If the download is nolonger dangerous (accepted externally) or the download | 111 // If the download is nolonger dangerous (accepted externally) or the download |
97 // is in a terminal state, then the download danger prompt is no longer | 112 // is in a terminal state, then the download danger prompt is no longer |
98 // necessary. | 113 // necessary. |
99 if (!download->IsDangerous() || download->IsDone()) | 114 if (!download->IsDangerous() || download->IsDone()) { |
| 115 accepted_.Reset(); |
| 116 canceled_.Reset(); |
100 Cancel(); | 117 Cancel(); |
| 118 } |
101 } | 119 } |
102 | 120 |
103 void DownloadDangerPromptImpl::OnDownloadOpened( | 121 void DownloadDangerPromptImpl::OnDownloadOpened( |
104 content::DownloadItem* download) { | 122 content::DownloadItem* download) { |
105 } | 123 } |
106 | 124 |
107 string16 DownloadDangerPromptImpl::GetTitle() { | 125 string16 DownloadDangerPromptImpl::GetTitle() { |
108 return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE); | 126 return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE); |
109 } | 127 } |
110 | 128 |
(...skipping 28 matching lines...) Expand all Loading... |
139 } | 157 } |
140 | 158 |
141 void DownloadDangerPromptImpl::OnAccepted() { | 159 void DownloadDangerPromptImpl::OnAccepted() { |
142 RunCallback(accepted_); | 160 RunCallback(accepted_); |
143 } | 161 } |
144 | 162 |
145 void DownloadDangerPromptImpl::OnCanceled() { | 163 void DownloadDangerPromptImpl::OnCanceled() { |
146 RunCallback(canceled_); | 164 RunCallback(canceled_); |
147 } | 165 } |
148 | 166 |
| 167 void DownloadDangerPromptImpl::Observe( |
| 168 int type, |
| 169 const content::NotificationSource& source, |
| 170 const content::NotificationDetails& details) { |
| 171 // Same logic as TabModalConfirmDialogDelegate::Observe, but don't run |
| 172 // canceled_. Just run destroyed_. |
| 173 if (type == content::NOTIFICATION_LOAD_START || |
| 174 type == chrome::NOTIFICATION_TAB_CLOSING) { |
| 175 PrepareToClose(); |
| 176 Cancel(); |
| 177 } else { |
| 178 NOTREACHED(); |
| 179 } |
| 180 } |
| 181 |
149 void DownloadDangerPromptImpl::RunCallback(const base::Closure& callback) { | 182 void DownloadDangerPromptImpl::RunCallback(const base::Closure& callback) { |
150 // Invoking the callback can cause the download item state to change or cause | 183 // Invoking the callback can cause the download item state to change or cause |
151 // the constrained window to close, and |callback| refers to a member | 184 // the constrained window to close, and |callback| refers to a member |
152 // variable. | 185 // variable. |
153 base::Closure callback_copy = callback; | 186 base::Closure callback_copy = callback; |
154 PrepareToClose(); | 187 PrepareToClose(); |
155 if (!callback_copy.is_null()) | 188 if (!callback_copy.is_null()) |
156 callback_copy.Run(); | 189 callback_copy.Run(); |
157 } | 190 } |
158 | 191 |
159 void DownloadDangerPromptImpl::PrepareToClose() { | 192 void DownloadDangerPromptImpl::PrepareToClose() { |
160 accepted_.Reset(); | 193 accepted_.Reset(); |
161 canceled_.Reset(); | 194 canceled_.Reset(); |
162 if (download_ != NULL) { | 195 if (download_ != NULL) { |
163 download_->RemoveObserver(this); | 196 download_->RemoveObserver(this); |
164 download_ = NULL; | 197 download_ = NULL; |
165 } | 198 } |
166 } | 199 } |
167 | 200 |
168 } // namespace | 201 } // namespace |
169 | 202 |
170 // static | 203 // static |
171 DownloadDangerPrompt* DownloadDangerPrompt::Create( | 204 DownloadDangerPrompt* DownloadDangerPrompt::Create( |
172 content::DownloadItem* item, | 205 content::DownloadItem* item, |
173 content::WebContents* web_contents, | 206 content::WebContents* web_contents, |
174 bool show_context, | 207 bool show_context, |
175 const base::Closure& accepted, | 208 const base::Closure& accepted, |
176 const base::Closure& canceled) { | 209 const base::Closure& canceled, |
| 210 const base::Closure& destroyed) { |
177 DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl( | 211 DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl( |
178 item, web_contents, show_context, accepted, canceled); | 212 item, web_contents, show_context, accepted, canceled, destroyed); |
179 // |prompt| will be deleted when the dialog is done. | 213 // |prompt| will be deleted when the dialog is done. |
180 TabModalConfirmDialog::Create(prompt, web_contents); | 214 TabModalConfirmDialog::Create(prompt, web_contents); |
181 return prompt; | 215 return prompt; |
182 } | 216 } |
OLD | NEW |