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" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/image/image.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/message_center/message_center_style.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/notification.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/message_center/notification_blocker.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/notification_types.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace message_center { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace { 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ShouldShowNotificationAsPopup( 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const Notification& notification, 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers) { 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < blockers.size(); ++i) { 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!blockers[i]->ShouldShowNotificationAsPopup(notification.notifier_id())) 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ComparePriorityTimestampSerial::operator()(Notification* n1, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notification* n2) { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->priority() > n2->priority()) // Higher pri go first. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->priority() < n2->priority()) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CompareTimestampSerial()(n1, n2); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CompareTimestampSerial::operator()(Notification* n1, Notification* n2) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->timestamp() > n2->timestamp()) // Newer come first. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->timestamp() < n2->timestamp()) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->serial_number() > n2->serial_number()) // Newer come first. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (n1->serial_number() < n2->serial_number()) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NotificationList::NotificationList() 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : message_center_visible_(false), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quiet_mode_(false) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationList::~NotificationList() { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPointers(notifications_.begin(), notifications_.end()); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NotificationList::SetMessageCenterVisible( 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool visible, 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string>* updated_ids) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_center_visible_ == visible) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_center_visible_ = visible; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!visible) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.end(); ++iter) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notification* notification = *iter; 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool was_popup = notification->shown_as_popup(); 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool was_read = notification->IsRead(); 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (notification->priority() < SYSTEM_PRIORITY) 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) notification->set_shown_as_popup(true); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notification->set_is_read(true); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (updated_ids && !(was_popup && was_read)) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) updated_ids->insert(notification->id()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NotificationList::AddNotification(scoped_ptr<Notification> notification) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PushNotification(notification.Pass()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::UpdateNotificationMessage( 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& old_id, 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<Notification> new_notification) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notifications::iterator iter = GetNotification(old_id); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == notifications_.end()) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->CopyState(*iter); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Handles priority promotion. If the notification is already dismissed but 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the updated notification has higher priority, it should re-appear as a 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // toast. Notifications coming from websites through the Web Notification API 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // will always re-appear on update. 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((*iter)->priority() < new_notification->priority() || 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_notification->notifier_id().type == NotifierId::WEB_PAGE) { 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->set_is_read(false); 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_notification->set_shown_as_popup(false); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Do not use EraseNotification and PushNotification, since we don't want to 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // change unread counts nor to update is_read/shown_as_popup states. 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Notification* old = *iter; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notifications_.erase(iter); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete old; 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We really don't want duplicate IDs. 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(GetNotification(new_notification->id()) == notifications_.end()); 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) notifications_.insert(new_notification.release()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::RemoveNotification(const std::string& id) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EraseNotification(GetNotification(id)); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)NotificationList::Notifications NotificationList::GetNotificationsByNotifierId( 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const NotifierId& notifier_id) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notifications notifications; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != notifications_.end(); ++iter) { 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if ((*iter)->notifier_id() == notifier_id) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notifications.insert(*iter); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return notifications; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationIcon(const std::string& notification_id, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == notifications_.end()) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_icon(image); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationImage(const std::string& notification_id, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == notifications_.end()) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_image(image); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationButtonIcon( 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& notification_id, int button_index, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification_id); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == notifications_.end()) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (*iter)->SetButtonIcon(button_index, image); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool NotificationList::HasNotificationOfType(const std::string& id, 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const NotificationType type) { 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (iter == notifications_.end()) 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return (*iter)->type() == type; 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NotificationList::HasPopupNotifications( 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers) { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.end(); ++iter) { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() < DEFAULT_PRIORITY) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ShouldShowNotificationAsPopup(**iter, blockers)) 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) continue; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(*iter)->shown_as_popup()) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NotificationList::PopupNotifications NotificationList::GetPopupNotifications( 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers, 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::list<std::string>* blocked_ids) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PopupNotifications result; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t default_priority_popup_count = 0; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Collect notifications that should be shown as popups. Start from oldest. 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Notifications::const_reverse_iterator iter = notifications_.rbegin(); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != notifications_.rend(); iter++) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->shown_as_popup()) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No popups for LOW/MIN priority. 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() < DEFAULT_PRIORITY) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ShouldShowNotificationAsPopup(**iter, blockers)) { 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (blocked_ids) 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blocked_ids->push_back((*iter)->id()); 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) continue; 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Checking limits. No limits for HIGH/MAX priority. DEFAULT priority 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will return at most kMaxVisiblePopupNotifications entries. If the 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // popup entries are more, older entries are used. see crbug.com/165768 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->priority() == DEFAULT_PRIORITY && 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_priority_popup_count++ >= kMaxVisiblePopupNotifications) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result.insert(*iter); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkSinglePopupAsShown( 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, bool mark_notification_as_read) { 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != notifications_.end()); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->shown_as_popup()) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // System notification is marked as shown only when marked as read. 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if ((*iter)->priority() != SYSTEM_PRIORITY || mark_notification_as_read) 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (*iter)->set_shown_as_popup(true); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The popup notification is already marked as read when it's displayed. 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the is_read() back to false if necessary. 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mark_notification_as_read) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (*iter)->set_is_read(false); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NotificationList::MarkSinglePopupAsDisplayed(const std::string& id) { 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter == notifications_.end()) 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*iter)->shown_as_popup()) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!(*iter)->IsRead()) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->set_is_read(true); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NotificationDelegate* NotificationList::GetNotificationDelegate( 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& id) { 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Notifications::iterator iter = GetNotification(id); 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (iter == notifications_.end()) 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return (*iter)->delegate(); 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::SetQuietMode(bool quiet_mode) { 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) quiet_mode_ = quiet_mode; 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (quiet_mode_) { 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) iter != notifications_.end(); 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ++iter) { 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*iter)->set_shown_as_popup(true); 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)Notification* NotificationList::GetNotificationById(const std::string& id) { 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Notifications::iterator iter = GetNotification(id); 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (iter != notifications_.end()) 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *iter; 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return NULL; 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NotificationList::Notifications NotificationList::GetVisibleNotifications( 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers) const { 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Notifications result; 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (Notifications::const_iterator iter = notifications_.begin(); 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) iter != notifications_.end(); ++iter) { 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool should_show = true; 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < blockers.size(); ++i) { 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!blockers[i]->ShouldShowNotification((*iter)->notifier_id())) { 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) should_show = false; 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (should_show) 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) result.insert(*iter); 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return result; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)size_t NotificationList::NotificationCount( 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers) const { 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return GetVisibleNotifications(blockers).size(); 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)size_t NotificationList::UnreadCount( 304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const NotificationBlockers& blockers) const { 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Notifications notifications = GetVisibleNotifications(blockers); 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t unread_count = 0; 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (Notifications::const_iterator iter = notifications.begin(); 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) iter != notifications.end(); ++iter) { 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!(*iter)->IsRead()) 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ++unread_count; 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return unread_count; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)NotificationList::Notifications::iterator NotificationList::GetNotification( 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& id) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Notifications::iterator iter = notifications_.begin(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != notifications_.end(); ++iter) { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->id() == id) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notifications_.end(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationList::EraseNotification(Notifications::iterator iter) { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete *iter; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifications_.erase(iter); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::PushNotification(scoped_ptr<Notification> notification) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that notification.id is unique by erasing any existing 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification with the same id (shouldn't normally happen). 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Notifications::iterator iter = GetNotification(notification->id()); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool state_inherited = false; 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter != notifications_.end()) { 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) notification->CopyState(*iter); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_inherited = true; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EraseNotification(iter); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the notification to the the list and mark it unread and unshown. 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!state_inherited) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mukai): needs to distinguish if a notification is dismissed by 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the quiet mode or user operation. 344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) notification->set_is_read(false); 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) notification->set_shown_as_popup(message_center_visible_ 3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) || quiet_mode_ 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) || notification->shown_as_popup()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Take ownership. The notification can only be removed from the list 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in EraseNotification(), which will delete it. 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) notifications_.insert(notification.release()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace message_center 355