notification_list.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/message_center/notification_blocker.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/notification_types.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace message_center {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ShouldShowNotificationAsPopup(
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NotifierId& notifier_id,
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<NotificationBlocker*>& blockers) {
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < blockers.size(); ++i) {
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!blockers[i]->ShouldShowNotificationAsPopup(notifier_id))
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return false;
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ComparePriorityTimestampSerial::operator()(Notification* n1,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                Notification* n2) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->priority() > n2->priority())  // Higher pri go first.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->priority() < n2->priority())
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CompareTimestampSerial()(n1, n2);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CompareTimestampSerial::operator()(Notification* n1, Notification* n2) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->timestamp() > n2->timestamp())  // Newer come first.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->timestamp() < n2->timestamp())
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->serial_number() > n2->serial_number())  // Newer come first.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (n1->serial_number() < n2->serial_number())
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NotificationList::NotificationList()
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : message_center_visible_(false),
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unread_count_(0),
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)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unread_count_ = 0;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (Notifications::iterator iter = notifications_.begin();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != notifications_.end(); ++iter) {
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Notification* notification = *iter;
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);
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (updated_ids &&
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        !(notification->shown_as_popup() && notification->is_read())) {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      updated_ids->insert(notification->id());
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NotificationList::AddNotification(scoped_ptr<Notification> notification) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PushNotification(notification.Pass());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::UpdateNotificationMessage(
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& old_id,
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_ptr<Notification> new_notification) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Notifications::iterator iter = GetNotification(old_id);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == notifications_.end())
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  new_notification->CopyState(*iter);
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Handles priority promotion. If the notification is already dismissed but
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the updated notification has higher priority, it should re-appear as a
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // toast.
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if ((*iter)->priority() < new_notification->priority()) {
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;
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notifications_.insert(new_notification.release());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::RemoveNotification(const std::string& id) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EraseNotification(GetNotification(id));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationList::RemoveAllNotifications() {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (Notifications::iterator loopiter = notifications_.begin();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       loopiter != notifications_.end(); ) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Notifications::iterator curiter = loopiter++;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EraseNotification(curiter);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unread_count_ = 0;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)NotificationList::Notifications NotificationList::GetNotificationsByNotifierId(
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        const NotifierId& notifier_id) {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Notifications notifications;
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (Notifications::iterator iter = notifications_.begin();
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       iter != notifications_.end(); ++iter) {
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if ((*iter)->notifier_id() == notifier_id)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      notifications.insert(*iter);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return notifications;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationIcon(const std::string& notification_id,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const gfx::Image& image) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(notification_id);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == notifications_.end())
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  (*iter)->set_icon(image);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationImage(const std::string& notification_id,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const gfx::Image& image) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(notification_id);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == notifications_.end())
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  (*iter)->set_image(image);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NotificationList::SetNotificationButtonIcon(
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& notification_id, int button_index,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Image& image) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(notification_id);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == notifications_.end())
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  (*iter)->SetButtonIcon(button_index, image);
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationList::HasNotification(const std::string& id) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetNotification(id) != notifications_.end();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NotificationList::HasPopupNotifications(
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<NotificationBlocker*>& blockers) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (Notifications::iterator iter = notifications_.begin();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != notifications_.end(); ++iter) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->priority() < DEFAULT_PRIORITY)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!ShouldShowNotificationAsPopup((*iter)->notifier_id(), blockers))
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!(*iter)->shown_as_popup())
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NotificationList::PopupNotifications NotificationList::GetPopupNotifications(
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<NotificationBlocker*>& blockers,
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::list<std::string>* blocked_ids) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PopupNotifications result;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t default_priority_popup_count = 0;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Collect notifications that should be shown as popups. Start from oldest.
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (Notifications::const_reverse_iterator iter = notifications_.rbegin();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != notifications_.rend(); iter++) {
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->shown_as_popup())
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No popups for LOW/MIN priority.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->priority() < DEFAULT_PRIORITY)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!ShouldShowNotificationAsPopup((*iter)->notifier_id(), blockers)) {
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (blocked_ids)
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        blocked_ids->push_back((*iter)->id());
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Checking limits. No limits for HIGH/MAX priority. DEFAULT priority
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // will return at most kMaxVisiblePopupNotifications entries. If the
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // popup entries are more, older entries are used. see crbug.com/165768
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->priority() == DEFAULT_PRIORITY &&
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        default_priority_popup_count++ >= kMaxVisiblePopupNotifications) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result.insert(*iter);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkSinglePopupAsShown(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& id, bool mark_notification_as_read) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(id);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(iter != notifications_.end());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if ((*iter)->shown_as_popup())
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // System notification is marked as shown only when marked as read.
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if ((*iter)->priority() != SYSTEM_PRIORITY || mark_notification_as_read)
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    (*iter)->set_shown_as_popup(true);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The popup notification is already marked as read when it's displayed.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the is_read() back to false if necessary.
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!mark_notification_as_read) {
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (*iter)->set_is_read(false);
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++unread_count_;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NotificationList::MarkSinglePopupAsDisplayed(const std::string& id) {
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Notifications::iterator iter = GetNotification(id);
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter == notifications_.end())
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if ((*iter)->shown_as_popup())
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!(*iter)->is_read()) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_is_read(true);
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    --unread_count_;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::MarkNotificationAsExpanded(const std::string& id) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(id);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != notifications_.end())
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_is_expanded(true);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NotificationDelegate* NotificationList::GetNotificationDelegate(
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& id) {
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Notifications::iterator iter = GetNotification(id);
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (iter == notifications_.end())
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return (*iter)->delegate();
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::SetQuietMode(bool quiet_mode) {
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  quiet_mode_ = quiet_mode;
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (quiet_mode_) {
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    for (Notifications::iterator iter = notifications_.begin();
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)         iter != notifications_.end();
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)         ++iter) {
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      (*iter)->set_shown_as_popup(true);
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const NotificationList::Notifications& NotificationList::GetNotifications() {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return notifications_;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t NotificationList::NotificationCount() const {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return notifications_.size();
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)NotificationList::Notifications::iterator NotificationList::GetNotification(
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& id) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (Notifications::iterator iter = notifications_.begin();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != notifications_.end(); ++iter) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->id() == id)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return iter;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notifications_.end();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationList::EraseNotification(Notifications::iterator iter) {
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!(*iter)->is_read() && (*iter)->priority() > MIN_PRIORITY)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --unread_count_;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete *iter;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications_.erase(iter);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationList::PushNotification(scoped_ptr<Notification> notification) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that notification.id is unique by erasing any existing
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification with the same id (shouldn't normally happen).
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Notifications::iterator iter = GetNotification(notification->id());
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool state_inherited = false;
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter != notifications_.end()) {
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    notification->CopyState(*iter);
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state_inherited = true;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EraseNotification(iter);
3173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // if |iter| is unread, EraseNotification decrements |unread_count_| but
3183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // actually the count is unchanged since |notification| will be added.
3193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (!notification->is_read())
3203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      ++unread_count_;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add the notification to the the list and mark it unread and unshown.
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!state_inherited) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(mukai): needs to distinguish if a notification is dismissed by
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the quiet mode or user operation.
326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    notification->set_is_read(false);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    notification->set_shown_as_popup(message_center_visible_ || quiet_mode_);
328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (notification->priority() > MIN_PRIORITY)
329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ++unread_count_;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Take ownership. The notification can only be removed from the list
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in EraseNotification(), which will delete it.
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  notifications_.insert(notification.release());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace message_center
337