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

Side by Side Diff: chrome/browser/download/notification/download_notification_item.cc

Issue 1105953002: Pop up the notification when the download is interrupted or completed (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dn-xxxx-close-bug
Patch Set: Adressed comment and pop up the notification after completion Created 5 years, 7 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
« no previous file with comments | « chrome/browser/download/notification/download_notification_item.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/download/notification/download_notification_item.h" 5 #include "chrome/browser/download/notification/download_notification_item.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/download/download_crx_util.h" 9 #include "chrome/browser/download/download_crx_util.h"
10 #include "chrome/browser/download/download_item_model.h" 10 #include "chrome/browser/download/download_item_model.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 } 65 }
66 66
67 std::string DownloadNotificationItem::NotificationWatcher::id() const { 67 std::string DownloadNotificationItem::NotificationWatcher::id() const {
68 return base::UintToString(item_->item_->GetId()); 68 return base::UintToString(item_->item_->GetId());
69 } 69 }
70 70
71 DownloadNotificationItem::DownloadNotificationItem(content::DownloadItem* item, 71 DownloadNotificationItem::DownloadNotificationItem(content::DownloadItem* item,
72 Profile* profile, 72 Profile* profile,
73 Delegate* delegate) 73 Delegate* delegate)
74 : openable_(false), 74 : openable_(false),
75 downloading_(false),
76 image_resource_id_(0), 75 image_resource_id_(0),
77 profile_(profile), 76 profile_(profile),
78 watcher_(new NotificationWatcher(this)), 77 watcher_(new NotificationWatcher(this)),
79 item_(item), 78 item_(item),
80 delegate_(delegate) { 79 delegate_(delegate) {
81 item->AddObserver(this); 80 item->AddObserver(this);
82 81
83 // Notify that the instance is just created. 82 // Notify that the instance is just created.
84 delegate_->OnCreated(this); 83 delegate_->OnCreated(this);
85 84
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 DownloadCommands(item_).ExecuteCommand(command); 139 DownloadCommands(item_).ExecuteCommand(command);
141 } 140 }
142 141
143 // DownloadItem::Observer methods 142 // DownloadItem::Observer methods
144 void DownloadNotificationItem::OnDownloadUpdated(content::DownloadItem* item) { 143 void DownloadNotificationItem::OnDownloadUpdated(content::DownloadItem* item) {
145 DCHECK_EQ(item, item_); 144 DCHECK_EQ(item, item_);
146 145
147 UpdateNotificationData(UPDATE_EXISTING); 146 UpdateNotificationData(UPDATE_EXISTING);
148 } 147 }
149 148
149 void DownloadNotificationItem::CloseNotificationByNonUser() {
150 const std::string& notification_id = watcher_->id();
151 const ProfileID profile_id = NotificationUIManager::GetProfileID(profile_);
152 const std::string notification_id_in_message_center =
153 ProfileNotification::GetProfileNotificationId(notification_id,
154 profile_id);
155
156 notification_ui_manager()->CancelById(notification_id, profile_id);
157 }
158
150 void DownloadNotificationItem::CloseNotificationByUser() { 159 void DownloadNotificationItem::CloseNotificationByUser() {
151 const std::string& notification_id = watcher_->id(); 160 const std::string& notification_id = watcher_->id();
152 const ProfileID profile_id = NotificationUIManager::GetProfileID(profile_); 161 const ProfileID profile_id = NotificationUIManager::GetProfileID(profile_);
153 const std::string notification_id_in_message_center = 162 const std::string notification_id_in_message_center =
154 ProfileNotification::GetProfileNotificationId(notification_id, 163 ProfileNotification::GetProfileNotificationId(notification_id,
155 profile_id); 164 profile_id);
156 165
157 notification_ui_manager()->CancelById(notification_id, profile_id); 166 notification_ui_manager()->CancelById(notification_id, profile_id);
158 167
159 // When the message center is visible, |NotificationUIManager::CancelByID()| 168 // When the message center is visible, |NotificationUIManager::CancelByID()|
160 // delays the close hence the notification is not closed at this time. But 169 // delays the close hence the notification is not closed at this time. But
161 // from the viewpoint of UX of MessageCenter, we should close it immediately 170 // from the viewpoint of UX of MessageCenter, we should close it immediately
162 // because it's by user action. So, we request closing of it directlly to 171 // because it's by user action. So, we request closing of it directlly to
163 // MessageCenter instance. 172 // MessageCenter instance.
164 // Note that: this calling has no side-effect even when the message center 173 // Note that: this calling has no side-effect even when the message center
165 // is not opened. 174 // is not opened.
166 g_browser_process->message_center()->RemoveNotification( 175 g_browser_process->message_center()->RemoveNotification(
167 notification_id_in_message_center, true /* by_user */); 176 notification_id_in_message_center, true /* by_user */);
168 } 177 }
169 178
170 void DownloadNotificationItem::UpdateNotificationData( 179 void DownloadNotificationItem::UpdateNotificationData(
171 NotificationUpdateType type) { 180 NotificationUpdateType type) {
172 DownloadItemModel model(item_); 181 DownloadItemModel model(item_);
173 DownloadCommands command(item_); 182 DownloadCommands command(item_);
174 183
175 if (!downloading_) { 184 if (previous_download_state_ != content::DownloadItem::IN_PROGRESS) {
yoshiki 2015/05/12 14:49:33 The semantics is same as the previous. Just rewrit
176 if (item_->GetState() == content::DownloadItem::IN_PROGRESS) { 185 if (item_->GetState() == content::DownloadItem::IN_PROGRESS)
177 delegate_->OnDownloadStarted(this); 186 delegate_->OnDownloadStarted(this);
178 downloading_ = true;
179 }
180 } else { 187 } else {
181 if (item_->GetState() != content::DownloadItem::IN_PROGRESS) { 188 if (item_->GetState() != content::DownloadItem::IN_PROGRESS)
182 delegate_->OnDownloadStopped(this); 189 delegate_->OnDownloadStopped(this);
183 downloading_ = false;
184 }
185 } 190 }
186 191
187 if (item_->IsDangerous()) { 192 if (item_->IsDangerous()) {
188 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE); 193 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE);
189 notification_->set_title(GetTitle()); 194 notification_->set_title(GetTitle());
190 notification_->set_message(GetWarningText()); 195 notification_->set_message(GetWarningText());
191 196
192 // Show icon. 197 // Show icon.
193 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_MALICIOUS); 198 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_MALICIOUS);
194 } else { 199 } else {
195 notification_->set_title(GetTitle()); 200 notification_->set_title(GetTitle());
196 notification_->set_message(model.GetStatusText()); 201 notification_->set_message(model.GetStatusText());
197 202
198 bool is_off_the_record = item_->GetBrowserContext() && 203 bool is_off_the_record = item_->GetBrowserContext() &&
199 item_->GetBrowserContext()->IsOffTheRecord(); 204 item_->GetBrowserContext()->IsOffTheRecord();
200 205
201 switch (item_->GetState()) { 206 switch (item_->GetState()) {
202 case content::DownloadItem::IN_PROGRESS: 207 case content::DownloadItem::IN_PROGRESS:
203 notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS); 208 notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
204 notification_->set_progress(item_->PercentComplete()); 209 notification_->set_progress(item_->PercentComplete());
205 if (is_off_the_record) { 210 if (is_off_the_record) {
206 // TODO(yoshiki): Replace the tentative image. 211 // TODO(yoshiki): Replace the tentative image.
207 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_INCOGNITO); 212 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_INCOGNITO);
208 } else { 213 } else {
209 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_DOWNLOADING); 214 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_DOWNLOADING);
210 } 215 }
211 break; 216 break;
212 case content::DownloadItem::COMPLETE: 217 case content::DownloadItem::COMPLETE:
213 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE); 218 DCHECK_EQ(100, item_->PercentComplete());
219 DCHECK(item_->IsDone());
220
221 // Shows a notifiation as progress type once so the visible content will
222 // be updated.
223 // Note: only progress-type notification's content will be updated
224 // immediately when the message center is visible.
225 notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
226 notification_->set_progress(100);
227
214 if (is_off_the_record) { 228 if (is_off_the_record) {
215 // TODO(yoshiki): Replace the tentative image. 229 // TODO(yoshiki): Replace the tentative image.
216 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_INCOGNITO); 230 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_INCOGNITO);
217 } else { 231 } else {
218 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_DOWNLOADING); 232 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_DOWNLOADING);
219 } 233 }
220
221 // TODO(yoshiki): Popup a notification again.
222 break; 234 break;
223 case content::DownloadItem::CANCELLED: 235 case content::DownloadItem::CANCELLED:
224 // Confgirms that a download is cancelled by user action. 236 // Confgirms that a download is cancelled by user action.
225 DCHECK(item_->GetLastReason() == 237 DCHECK(item_->GetLastReason() ==
226 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || 238 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED ||
227 item_->GetLastReason() == 239 item_->GetLastReason() ==
228 content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); 240 content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);
229 241
230 CloseNotificationByUser(); 242 CloseNotificationByUser();
243
244 previous_download_state_ = item_->GetState();
231 return; // Skips the remaining since the notification has closed. 245 return; // Skips the remaining since the notification has closed.
232 case content::DownloadItem::INTERRUPTED: 246 case content::DownloadItem::INTERRUPTED:
233 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE); 247 // Shows a notifiation as progress type once so the visible content will
248 // be updated. (same as the case of type = COMPLETE)
249 notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
250 notification_->set_progress(0);
234 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_WARNING); 251 SetNotificationImage(IDR_DOWNLOAD_NOTIFICATION_WARNING);
235
236 // TODO(yoshiki): Popup a notification again.
237 break; 252 break;
238 case content::DownloadItem::MAX_DOWNLOAD_STATE: // sentinel 253 case content::DownloadItem::MAX_DOWNLOAD_STATE: // sentinel
239 NOTREACHED(); 254 NOTREACHED();
240 } 255 }
241 } 256 }
242 257
243 std::vector<message_center::ButtonInfo> notification_actions; 258 std::vector<message_center::ButtonInfo> notification_actions;
244 scoped_ptr<std::vector<DownloadCommands::Command>> actions( 259 scoped_ptr<std::vector<DownloadCommands::Command>> actions(
245 GetPossibleActions().Pass()); 260 GetPossibleActions().Pass());
246 261
247 openable_ = false; 262 openable_ = false;
248 button_actions_.reset(new std::vector<DownloadCommands::Command>); 263 button_actions_.reset(new std::vector<DownloadCommands::Command>);
249 for (auto it = actions->begin(); it != actions->end(); it++) { 264 for (auto it = actions->begin(); it != actions->end(); it++) {
250 if (*it == DownloadCommands::OPEN_WHEN_COMPLETE) { 265 if (*it == DownloadCommands::OPEN_WHEN_COMPLETE) {
251 openable_ = true; 266 openable_ = true;
252 } else { 267 } else {
253 button_actions_->push_back(*it); 268 button_actions_->push_back(*it);
254 message_center::ButtonInfo button_info = 269 message_center::ButtonInfo button_info =
255 message_center::ButtonInfo(GetCommandLabel(*it)); 270 message_center::ButtonInfo(GetCommandLabel(*it));
256 button_info.icon = command.GetCommandIcon(*it); 271 button_info.icon = command.GetCommandIcon(*it);
257 notification_actions.push_back(button_info); 272 notification_actions.push_back(button_info);
258 } 273 }
259 } 274 }
260 notification_->set_buttons(notification_actions); 275 notification_->set_buttons(notification_actions);
261 276
262 if (item_->IsDone()) { 277 if (item_->IsDone()) {
263 // TODO(yoshiki): If the downloaded file is an image, show the thumbnail. 278 // TODO(yoshiki): If the downloaded file is an image, show the thumbnail.
264 } 279 }
265 280
266 if (type == ADD_NEW) 281 if (type == ADD_NEW) {
267 notification_ui_manager()->Add(*notification_, profile_); 282 notification_ui_manager()->Add(*notification_, profile_);
268 else if (type == UPDATE_EXISTING) 283 } else if (type == UPDATE_EXISTING) {
269 notification_ui_manager()->Update(*notification_, profile_); 284 notification_ui_manager()->Update(*notification_, profile_);
270 else 285
286 // When the download is just completed, close the notification once and
287 // re-show it immediately so it'll be poped up.
288 if (item_->GetState() == content::DownloadItem::COMPLETE &&
289 previous_download_state_ != content::DownloadItem::COMPLETE) {
290 CloseNotificationByNonUser();
291 // Changes the type from PROGRESS to SIMPLE.
292 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE);
293 notification_ui_manager()->Add(*notification_, profile_);
294 }
295
296 // When the download is just interruppted, close the notification once and
297 // re-show it immediately so it'll be poped up.
298 if (item_->GetState() == content::DownloadItem::INTERRUPTED &&
299 previous_download_state_ != content::DownloadItem::INTERRUPTED) {
300 CloseNotificationByNonUser();
301 notification_ui_manager()->Add(*notification_, profile_);
302 }
303 } else {
271 NOTREACHED(); 304 NOTREACHED();
305 }
306
307 previous_download_state_ = item_->GetState();
272 } 308 }
273 309
274 void DownloadNotificationItem::OnDownloadOpened(content::DownloadItem* item) { 310 void DownloadNotificationItem::OnDownloadOpened(content::DownloadItem* item) {
275 DCHECK_EQ(item, item_); 311 DCHECK_EQ(item, item_);
276 // Do nothing. 312 // Do nothing.
277 } 313 }
278 314
279 void DownloadNotificationItem::OnDownloadRemoved(content::DownloadItem* item) { 315 void DownloadNotificationItem::OnDownloadRemoved(content::DownloadItem* item) {
280 DCHECK_EQ(item, item_); 316 DCHECK_EQ(item, item_);
281 317
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 switch (item_->GetState()) { 385 switch (item_->GetState()) {
350 case content::DownloadItem::IN_PROGRESS: 386 case content::DownloadItem::IN_PROGRESS:
351 title_text = l10n_util::GetStringFUTF16( 387 title_text = l10n_util::GetStringFUTF16(
352 IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE, file_name); 388 IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE, file_name);
353 break; 389 break;
354 case content::DownloadItem::COMPLETE: 390 case content::DownloadItem::COMPLETE:
355 title_text = l10n_util::GetStringFUTF16( 391 title_text = l10n_util::GetStringFUTF16(
356 IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE, file_name); 392 IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE, file_name);
357 case content::DownloadItem::INTERRUPTED: 393 case content::DownloadItem::INTERRUPTED:
358 title_text = l10n_util::GetStringFUTF16( 394 title_text = l10n_util::GetStringFUTF16(
359 IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE, file_name); 395 IDS_DOWNLOAD_STATUS_DOWNLOAD_FAILED_TITLE, file_name);
yoshiki 2015/05/12 14:49:33 just fixing wrong ID for failure download.
360 break; 396 break;
361 case content::DownloadItem::CANCELLED: 397 case content::DownloadItem::CANCELLED:
362 title_text = l10n_util::GetStringFUTF16( 398 title_text = l10n_util::GetStringFUTF16(
363 IDS_DOWNLOAD_STATUS_DOWNLOAD_FAILED_TITLE, file_name); 399 IDS_DOWNLOAD_STATUS_DOWNLOAD_FAILED_TITLE, file_name);
364 break; 400 break;
365 case content::DownloadItem::MAX_DOWNLOAD_STATE: 401 case content::DownloadItem::MAX_DOWNLOAD_STATE:
366 NOTREACHED(); 402 NOTREACHED();
367 } 403 }
368 return title_text; 404 return title_text;
369 } 405 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: 484 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
449 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: 485 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
450 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: 486 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
451 case content::DOWNLOAD_DANGER_TYPE_MAX: { 487 case content::DOWNLOAD_DANGER_TYPE_MAX: {
452 break; 488 break;
453 } 489 }
454 } 490 }
455 NOTREACHED(); 491 NOTREACHED();
456 return base::string16(); 492 return base::string16();
457 } 493 }
OLDNEW
« no previous file with comments | « chrome/browser/download/notification/download_notification_item.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698