Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / download / notification / download_group_notification.cc
blob020af24680cfd53038f265cccaabafe23f15948a
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
3 // found in the LICENSE file.
5 #include "chrome/browser/download/notification/download_group_notification.h"
7 #include <algorithm>
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/download/download_item_model.h"
13 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/chromium_strings.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "content/public/browser/download_item.h"
18 #include "grit/theme_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/l10n/time_format.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/text_elider.h"
23 #include "ui/views/controls/label.h"
25 namespace {
27 const char kDownloadNotificationNotifierId[] =
28 "chrome://downloads/notification/id-notifier";
30 const size_t kMaxFilenameWidth = 160; // in px
32 base::string16 TruncateFilename(const base::FilePath& filename) {
33 return gfx::ElideFilename(filename,
34 views::Label().font_list(),
35 kMaxFilenameWidth);
38 } // anonymous namespace
40 DownloadGroupNotification::DownloadGroupNotification(
41 Profile* profile, DownloadNotificationManagerForProfile* manager)
42 : profile_(profile) {
44 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
46 message_center::RichNotificationData data;
47 // Creates the notification instance. |title| and |body| will be overridden
48 // by UpdateNotificationData() below.
49 notification_.reset(new Notification(
50 message_center::NOTIFICATION_TYPE_MULTIPLE,
51 GURL(kDownloadNotificationOrigin), // origin_url
52 base::string16(), // title
53 base::string16(), // body
54 bundle.GetImageNamed(IDR_DOWNLOAD_NOTIFICATION_DOWNLOADING),
55 message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT,
56 kDownloadNotificationNotifierId),
57 base::string16(), // display_source
58 "GROUP", // tag
59 data, watcher()));
61 notification_->SetSystemPriority();
62 notification_->set_never_timeout(false);
64 std::vector<message_center::ButtonInfo> notification_actions;
65 message_center::ButtonInfo button_info =
66 message_center::ButtonInfo(l10n_util::GetStringUTF16(
67 IDS_DOWNLOAD_LINK_SHOW_ALL_DOWNLOADS));
68 notification_actions.push_back(button_info);
69 notification_->set_buttons(notification_actions);
72 DownloadGroupNotification::~DownloadGroupNotification() {}
74 bool DownloadGroupNotification::IsPopup() const {
75 const ProfileID profile_id =
76 NotificationUIManager::GetProfileID(profile_);
77 const std::string& notification_id = GetNotificationId();
78 const std::string& raw_notification_id = g_browser_process->
79 notification_ui_manager()->FindById(notification_id, profile_id)->id();
80 auto popup_notifications =
81 g_browser_process->message_center()->GetPopupNotifications();
82 for (auto notification : popup_notifications) {
83 if (notification->id() == raw_notification_id)
84 return true;
86 return false;
89 void DownloadGroupNotification::OnDownloadUpdated(
90 content::DownloadItem* download) {
91 if (items_.find(download) != items_.end()) {
92 Update();
96 void DownloadGroupNotification::OnDownloadAdded(
97 content::DownloadItem* download) {
98 if (items_.find(download) == items_.end()) {
99 items_.insert(download);
100 int inprogress_download_count = 0;
101 // If new download is started and there are more than 2 downloads in total,
102 // show the group notification.
103 for (auto it = items_.begin(); it != items_.end(); it++) {
104 if (!(*it)->IsDone() && ++inprogress_download_count >= 2) {
105 Show();
106 break;
112 void DownloadGroupNotification::OnDownloadRemoved(
113 content::DownloadItem* download) {
114 // The given |download| may be already free'd.
115 if (items_.find(download) != items_.end()) {
116 items_.erase(download);
117 if (items_.size() <= 1)
118 Hide();
122 void DownloadGroupNotification::OnNotificationClose() {
123 visible_ = false;
125 // When the notification is closed, removes the finished downloads.
126 auto it = items_.begin();
127 while (it != items_.end()) {
128 if ((*it)->GetState() != content::DownloadItem::IN_PROGRESS)
129 items_.erase(*(it++));
130 else
131 it++;
135 void DownloadGroupNotification::OnNotificationClick() {
136 OpenDownloads();
139 void DownloadGroupNotification::OnNotificationButtonClick(
140 int button_index) {
141 DCHECK_EQ(0, button_index);
142 OpenDownloads();
145 void DownloadGroupNotification::Hide() {
146 hide_next_ = true;
147 Update();
150 void DownloadGroupNotification::Show() {
151 show_next_ = true;
152 Update();
155 void DownloadGroupNotification::Update() {
156 if (visible_) {
157 if (hide_next_) {
158 const ProfileID profile_id =
159 NotificationUIManager::GetProfileID(profile_);
160 const std::string& notification_id = GetNotificationId();
161 g_browser_process->notification_ui_manager()->
162 CancelById(notification_id, profile_id);
163 visible_ = false;
164 } else {
165 UpdateNotificationData();
166 g_browser_process->notification_ui_manager()->
167 Update(*notification_, profile_);
169 } else {
170 if (show_next_) {
171 UpdateNotificationData();
172 g_browser_process->notification_ui_manager()->
173 Add(*notification_, profile_);
174 visible_ = true;
177 show_next_ = false;
178 hide_next_ = false;
181 void DownloadGroupNotification::UpdateNotificationData() {
182 bool all_finished = true;
183 std::vector<message_center::NotificationItem> subitems;
184 for (auto download : items_) {
185 DownloadItemModel model(download);
186 // TODO(yoshiki): Use emplace_back when C++11 becomes allowed.
187 subitems.push_back(message_center::NotificationItem(
188 TruncateFilename(download->GetFileNameToReportUser()),
189 model.GetStatusText()));
191 if (!download->IsDone())
192 all_finished = false;
194 notification_->set_items(subitems);
196 int title_id = all_finished ? IDS_DOWNLOAD_STATUS_GROUP_DONE_TITLE :
197 IDS_DOWNLOAD_STATUS_GROUP_IN_PROGRESS_TITLE;
198 notification_->set_title(l10n_util::GetPluralStringFUTF16(
199 title_id, items_.size()));
202 std::string DownloadGroupNotification::GetNotificationId() const {
203 return "GROUP";
206 void DownloadGroupNotification::OpenDownloads() {
207 chrome::ScopedTabbedBrowserDisplayer browser_displayer(
208 profile_, chrome::GetActiveDesktop());
209 Browser* browser = browser_displayer.browser();
210 DCHECK(browser);
212 browser->OpenURL(content::OpenURLParams(
213 GURL(chrome::kChromeUIDownloadsURL), content::Referrer(),
214 NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
215 false /* is_renderer_initiated */));