notification_list.cc revision 3240926e260ce088908e02ac07a6cf7b0c0cbf44
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/message_center/notification_list.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/message_center/message_center_style.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/notification.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/notification_types.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace message_center { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ComparePriorityTimestampSerial::operator()(Notification* n1, 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notification* n2) { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->priority() > n2->priority()) // Higher pri go first. 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->priority() < n2->priority()) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CompareTimestampSerial()(n1, n2); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CompareTimestampSerial::operator()(Notification* n1, Notification* n2) { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->timestamp() > n2->timestamp()) // Newer come first. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->timestamp() < n2->timestamp()) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->serial_number() > n2->serial_number()) // Newer come first. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->serial_number() < n2->serial_number()) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NotificationList::NotificationList() 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : message_center_visible_(false), 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unread_count_(0), 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_(false) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationList::~NotificationList() { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPointers(notifications_.begin(), notifications_.end()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NotificationList::SetMessageCenterVisible( 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool visible, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string>* updated_ids) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_center_visible_ == visible) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_center_visible_ = visible; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!visible) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unread_count_ = 0; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.end(); ++iter) { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notification* notification = *iter; 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (notification->priority() < SYSTEM_PRIORITY) 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) notification->set_shown_as_popup(true); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notification->set_is_read(true); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (updated_ids && 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !(notification->shown_as_popup() && notification->is_read())) { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) updated_ids->insert(notification->id()); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NotificationList::AddNotification(scoped_ptr<Notification> notification) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PushNotification(notification.Pass()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::UpdateNotificationMessage( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& old_id, 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<Notification> new_notification) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notifications::iterator iter = GetNotification(old_id); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == notifications_.end()) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->CopyState(*iter); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Handles priority promotion. If the notification is already dismissed but 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the updated notification has higher priority, it should re-appear as a 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // toast. 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((*iter)->priority() < new_notification->priority()) { 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->set_is_read(false); 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->set_shown_as_popup(false); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Do not use EraseNotification and PushNotification, since we don't want to 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // change unread counts nor to update is_read/shown_as_popup states. 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Notification* old = *iter; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notifications_.erase(iter); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete old; 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) notifications_.insert(new_notification.release()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::RemoveNotification(const std::string& id) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EraseNotification(GetNotification(id)); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationList::RemoveAllNotifications() { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator loopiter = notifications_.begin(); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loopiter != notifications_.end(); ) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator curiter = loopiter++; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EraseNotification(curiter); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unread_count_ = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NotificationList::Notifications NotificationList::GetNotificationsBySource( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id) { 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notifications notifications; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notifications::iterator source_iter = GetNotification(id); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source_iter == notifications_.end()) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return notifications; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string16 display_source = (*source_iter)->display_source(); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != notifications_.end(); ++iter) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*iter)->display_source() == display_source) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notifications.insert(*iter); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return notifications; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NotificationList::Notifications NotificationList::GetNotificationsByExtension( 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& id) { 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notifications notifications; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notifications::iterator source_iter = GetNotification(id); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source_iter == notifications_.end()) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return notifications; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string extension_id = (*source_iter)->extension_id(); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != notifications_.end(); ++iter) { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*iter)->extension_id() == extension_id) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notifications.insert(*iter); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return notifications; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationIcon(const std::string& notification_id, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == notifications_.end()) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_icon(image); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationImage(const std::string& notification_id, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == notifications_.end()) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_image(image); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationButtonIcon( 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& notification_id, int button_index, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == notifications_.end()) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (*iter)->SetButtonIcon(button_index, image); 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationList::HasNotification(const std::string& id) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNotification(id) != notifications_.end(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationList::HasPopupNotifications() { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.end(); ++iter) { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() < DEFAULT_PRIORITY) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(*iter)->shown_as_popup()) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NotificationList::PopupNotifications NotificationList::GetPopupNotifications() { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PopupNotifications result; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t default_priority_popup_count = 0; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Collect notifications that should be shown as popups. Start from oldest. 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::const_reverse_iterator iter = notifications_.rbegin(); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.rend(); iter++) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->shown_as_popup()) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No popups for LOW/MIN priority. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() < DEFAULT_PRIORITY) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Checking limits. No limits for HIGH/MAX priority. DEFAULT priority 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will return at most kMaxVisiblePopupNotifications entries. If the 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // popup entries are more, older entries are used. see crbug.com/165768 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() == DEFAULT_PRIORITY && 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_priority_popup_count++ >= kMaxVisiblePopupNotifications) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result.insert(*iter); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Notification* NotificationList::GetPopup(const std::string& id) { 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PopupNotifications popups = GetPopupNotifications(); 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (PopupNotifications::iterator iter = popups.begin(); iter != popups.end(); 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iter) { 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((*iter)->id() == id) 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return *iter; 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkPopupsAsShown(int priority) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PopupNotifications popups = GetPopupNotifications(); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (PopupNotifications::iterator iter = popups.begin(); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != popups.end(); ++iter) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() == priority) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_shown_as_popup(true); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkSinglePopupAsShown( 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, bool mark_notification_as_read) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != notifications_.end()); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->shown_as_popup()) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // System notification is marked as shown only when marked as read. 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if ((*iter)->priority() != SYSTEM_PRIORITY || mark_notification_as_read) 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*iter)->set_shown_as_popup(true); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The popup notification is already marked as read when it's displayed. 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the is_read() back to false if necessary. 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!mark_notification_as_read) { 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (*iter)->set_is_read(false); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++unread_count_; 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NotificationList::MarkSinglePopupAsDisplayed(const std::string& id) { 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter == notifications_.end()) 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*iter)->shown_as_popup()) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(*iter)->is_read()) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_is_read(true); 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) --unread_count_; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkNotificationAsExpanded(const std::string& id) { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != notifications_.end()) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_is_expanded(true); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NotificationDelegate* NotificationList::GetNotificationDelegate( 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& id) { 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (iter == notifications_.end()) 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return (*iter)->delegate(); 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::SetQuietMode(bool quiet_mode) { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetQuietModeInternal(quiet_mode); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_timer_.reset(); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::EnterQuietModeWithExpire( 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta& expires_in) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (quiet_mode_timer_.get()) { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that the capital Reset() is the method to restart the timer, not 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scoped_ptr::reset(). 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_timer_->Reset(); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetQuietModeInternal(true); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_timer_.reset(new base::OneShotTimer<NotificationList>); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_timer_->Start(FROM_HERE, expires_in, base::Bind( 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &NotificationList::SetQuietMode, base::Unretained(this), false)); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const NotificationList::Notifications& NotificationList::GetNotifications() { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return notifications_; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t NotificationList::NotificationCount() const { 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return notifications_.size(); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::SetQuietModeInternal(bool quiet_mode) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_ = quiet_mode; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (quiet_mode_) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != notifications_.end(); 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_shown_as_popup(true); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NotificationList::Notifications::iterator 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotificationList::GetNotification(const std::string& id) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != notifications_.end(); ++iter) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->id() == id) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notifications_.end(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationList::EraseNotification(Notifications::iterator iter) { 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(*iter)->is_read() && (*iter)->priority() > MIN_PRIORITY) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --unread_count_; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete *iter; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_.erase(iter); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::PushNotification(scoped_ptr<Notification> notification) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that notification.id is unique by erasing any existing 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification with the same id (shouldn't normally happen). 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification->id()); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool state_inherited = false; 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter != notifications_.end()) { 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notification->CopyState(*iter); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_inherited = true; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EraseNotification(iter); 3513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // if |iter| is unread, EraseNotification decrements |unread_count_| but 3523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // actually the count is unchanged since |notification| will be added. 3533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!notification->is_read()) 3543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ++unread_count_; 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the notification to the the list and mark it unread and unshown. 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!state_inherited) { 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mukai): needs to distinguish if a notification is dismissed by 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the quiet mode or user operation. 360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) notification->set_is_read(false); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notification->set_shown_as_popup(message_center_visible_ || quiet_mode_); 362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (notification->priority() > MIN_PRIORITY) 363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++unread_count_; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Take ownership. The notification can only be removed from the list 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in EraseNotification(), which will delete it. 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) notifications_.insert(notification.release()); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace message_center 371