1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/message_center/message_center_impl.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/observer_list.h"
11 #include "ui/message_center/message_center_style.h"
12 #include "ui/message_center/message_center_types.h"
13 #include "ui/message_center/notification.h"
14 #include "ui/message_center/notification_blocker.h"
15 #include "ui/message_center/notification_list.h"
16 #include "ui/message_center/notification_types.h"
20 base::TimeDelta
GetTimeoutForPriority(int priority
) {
21 if (priority
> message_center::DEFAULT_PRIORITY
) {
22 return base::TimeDelta::FromSeconds(
23 message_center::kAutocloseHighPriorityDelaySeconds
);
25 return base::TimeDelta::FromSeconds(
26 message_center::kAutocloseDefaultDelaySeconds
);
31 namespace message_center
{
34 // ChangeQueue keeps track of all the changes that we need to make to the
35 // notification list once the visibility is set to VISIBILITY_TRANSIENT.
44 // Change represents an operation made on a notification. Since it contains
45 // the final state of the notification, we only keep the last change for a
46 // particular notification that is in the notification list around. There are
47 // two ids; |id_| is the newest notification id that has been assigned by an
48 // update, and |notification_list_id_| is the id of the notification it should
49 // be updating as it exists in the notification list.
52 Change(ChangeType type
,
53 const std::string
& id
,
54 scoped_ptr
<Notification
> notification
);
57 // Used to transfer ownership of the contained notification.
58 scoped_ptr
<Notification
> PassNotification();
60 Notification
* notification() const { return notification_
.get(); }
61 const std::string
& id() const { return id_
; }
62 ChangeType
type() const { return type_
; }
63 bool by_user() const { return by_user_
; }
64 void set_by_user(bool by_user
) { by_user_
= by_user
; }
65 const std::string
& notification_list_id() const {
66 return notification_list_id_
;
68 void set_notification_list_id(const std::string
& id
) {
69 notification_list_id_
= id
;
73 const ChangeType type_
;
74 const std::string id_
;
75 std::string notification_list_id_
;
77 scoped_ptr
<Notification
> notification_
;
79 DISALLOW_COPY_AND_ASSIGN(Change
);
85 // Called when the message center has appropriate visibility. Modifies
86 // |message_center| but does not retain it. This also causes the queue to
88 void ApplyChanges(MessageCenter
* message_center
);
90 // Causes a TYPE_ADD change to be added to the queue.
91 void AddNotification(scoped_ptr
<Notification
> notification
);
93 // Causes a TYPE_UPDATE change to be added to the queue.
94 void UpdateNotification(const std::string
& old_id
,
95 scoped_ptr
<Notification
> notification
);
97 // Causes a TYPE_DELETE change to be added to the queue.
98 void EraseNotification(const std::string
& id
, bool by_user
);
100 // Returns whether the queue matches an id. The id given will be matched
101 // against the ID of all changes post-update, not the id of the notification
102 // as it stands in the notification list.
103 bool Has(const std::string
& id
) const;
105 // Returns a Change that can be modified by the caller. ChangeQueue retains
106 // ownership of the Change; pointers should not be retained.
107 Notification
* GetLatestNotification(const std::string
& id
) const;
110 void Replace(const std::string
& id
, scoped_ptr
<Change
> change
);
112 ScopedVector
<Change
> changes_
;
115 ////////////////////////////////////////////////////////////////////////////////
118 struct ChangeFinder
{
119 explicit ChangeFinder(const std::string
& id
) : id(id
) {}
120 bool operator()(ChangeQueue::Change
* change
) { return change
->id() == id
; }
125 ////////////////////////////////////////////////////////////////////////////////
126 // ChangeQueue::Change
128 ChangeQueue::Change::Change(ChangeType type
,
129 const std::string
& id
,
130 scoped_ptr
<Notification
> notification
)
133 notification_list_id_(id
),
135 notification_(notification
.Pass()) {
136 DCHECK(!id
.empty() &&
137 (type
!= CHANGE_TYPE_DELETE
|| notification_
.get() == NULL
));
140 ChangeQueue::Change::~Change() {}
142 scoped_ptr
<Notification
> ChangeQueue::Change::PassNotification() {
143 return notification_
.Pass();
146 ////////////////////////////////////////////////////////////////////////////////
149 ChangeQueue::ChangeQueue() {}
151 ChangeQueue::~ChangeQueue() {}
153 void ChangeQueue::ApplyChanges(MessageCenter
* message_center
) {
154 // This method is re-entrant.
155 while (!changes_
.empty()) {
156 ScopedVector
<Change
>::iterator iter
= changes_
.begin();
157 scoped_ptr
<Change
> change(*iter
);
158 // TODO(dewittj): Replace changes_ with a deque.
159 changes_
.weak_erase(iter
);
160 // |message_center| is taking ownership of each element here.
161 switch (change
->type()) {
162 case CHANGE_TYPE_ADD
:
163 message_center
->AddNotification(change
->PassNotification());
165 case CHANGE_TYPE_UPDATE
:
166 message_center
->UpdateNotification(change
->notification_list_id(),
167 change
->PassNotification());
169 case CHANGE_TYPE_DELETE
:
170 message_center
->RemoveNotification(change
->notification_list_id(),
179 void ChangeQueue::AddNotification(scoped_ptr
<Notification
> notification
) {
180 std::string id
= notification
->id();
182 scoped_ptr
<Change
> change(
183 new Change(CHANGE_TYPE_ADD
, id
, notification
.Pass()));
184 Replace(id
, change
.Pass());
187 void ChangeQueue::UpdateNotification(const std::string
& old_id
,
188 scoped_ptr
<Notification
> notification
) {
189 std::string new_id
= notification
->id();
190 scoped_ptr
<Change
> change(
191 new Change(CHANGE_TYPE_UPDATE
, new_id
, notification
.Pass()));
192 Replace(old_id
, change
.Pass());
195 void ChangeQueue::EraseNotification(const std::string
& id
, bool by_user
) {
196 scoped_ptr
<Change
> change(
197 new Change(CHANGE_TYPE_DELETE
, id
, scoped_ptr
<Notification
>()));
198 change
->set_by_user(by_user
);
199 Replace(id
, change
.Pass());
202 bool ChangeQueue::Has(const std::string
& id
) const {
203 ScopedVector
<Change
>::const_iterator iter
=
204 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(id
));
205 return iter
!= changes_
.end();
208 Notification
* ChangeQueue::GetLatestNotification(const std::string
& id
) const {
209 ScopedVector
<Change
>::const_iterator iter
=
210 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(id
));
211 if (iter
== changes_
.end())
214 return (*iter
)->notification();
217 void ChangeQueue::Replace(const std::string
& changed_id
,
218 scoped_ptr
<Change
> new_change
) {
219 ScopedVector
<Change
>::iterator iter
=
220 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(changed_id
));
221 if (iter
!= changes_
.end()) {
222 Change
* old_change
= *iter
;
223 new_change
->set_notification_list_id(old_change
->notification_list_id());
224 changes_
.erase(iter
);
226 new_change
->set_notification_list_id(changed_id
);
229 changes_
.push_back(new_change
.release());
232 ////////////////////////////////////////////////////////////////////////////////
235 PopupTimer::PopupTimer(const std::string
& id
,
236 base::TimeDelta timeout
,
237 base::WeakPtr
<PopupTimersController
> controller
)
240 timer_controller_(controller
),
241 timer_(new base::OneShotTimer
<PopupTimersController
>) {}
243 PopupTimer::~PopupTimer() {
247 if (timer_
->IsRunning())
251 void PopupTimer::Start() {
252 if (timer_
->IsRunning())
254 base::TimeDelta timeout_to_close
=
255 timeout_
<= passed_
? base::TimeDelta() : timeout_
- passed_
;
256 start_time_
= base::Time::Now();
261 &PopupTimersController::TimerFinished
, timer_controller_
, id_
));
264 void PopupTimer::Pause() {
265 if (!timer_
.get() || !timer_
->IsRunning())
269 passed_
+= base::Time::Now() - start_time_
;
272 void PopupTimer::Reset() {
275 passed_
= base::TimeDelta();
278 ////////////////////////////////////////////////////////////////////////////////
279 // PopupTimersController
281 PopupTimersController::PopupTimersController(MessageCenter
* message_center
)
282 : message_center_(message_center
), popup_deleter_(&popup_timers_
) {
283 message_center_
->AddObserver(this);
286 PopupTimersController::~PopupTimersController() {
287 message_center_
->RemoveObserver(this);
290 void PopupTimersController::StartTimer(const std::string
& id
,
291 const base::TimeDelta
& timeout
) {
292 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
293 if (iter
!= popup_timers_
.end()) {
294 DCHECK(iter
->second
);
295 iter
->second
->Start();
299 PopupTimer
* timer
= new PopupTimer(id
, timeout
, AsWeakPtr());
302 popup_timers_
[id
] = timer
;
305 void PopupTimersController::StartAll() {
306 std::map
<std::string
, PopupTimer
*>::iterator iter
;
307 for (iter
= popup_timers_
.begin(); iter
!= popup_timers_
.end(); iter
++) {
308 iter
->second
->Start();
312 void PopupTimersController::ResetTimer(const std::string
& id
,
313 const base::TimeDelta
& timeout
) {
315 StartTimer(id
, timeout
);
318 void PopupTimersController::PauseTimer(const std::string
& id
) {
319 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
320 if (iter
== popup_timers_
.end())
322 iter
->second
->Pause();
325 void PopupTimersController::PauseAll() {
326 std::map
<std::string
, PopupTimer
*>::iterator iter
;
327 for (iter
= popup_timers_
.begin(); iter
!= popup_timers_
.end(); iter
++) {
328 iter
->second
->Pause();
332 void PopupTimersController::CancelTimer(const std::string
& id
) {
333 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
334 if (iter
== popup_timers_
.end())
337 PopupTimer
* timer
= iter
->second
;
340 popup_timers_
.erase(iter
);
343 void PopupTimersController::CancelAll() {
344 STLDeleteValues(&popup_timers_
);
345 popup_timers_
.clear();
348 void PopupTimersController::TimerFinished(const std::string
& id
) {
349 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
350 if (iter
== popup_timers_
.end())
354 message_center_
->MarkSinglePopupAsShown(id
, false);
357 void PopupTimersController::OnNotificationDisplayed(
358 const std::string
& id
,
359 const DisplaySource source
) {
360 OnNotificationUpdated(id
);
363 void PopupTimersController::OnNotificationUpdated(const std::string
& id
) {
364 NotificationList::PopupNotifications popup_notifications
=
365 message_center_
->GetPopupNotifications();
367 if (!popup_notifications
.size()) {
372 NotificationList::PopupNotifications::const_iterator iter
=
373 popup_notifications
.begin();
374 for (; iter
!= popup_notifications
.end(); iter
++) {
375 if ((*iter
)->id() == id
)
379 if (iter
== popup_notifications
.end() || (*iter
)->never_timeout()) {
384 // Start the timer if not yet.
385 if (popup_timers_
.find(id
) == popup_timers_
.end())
386 StartTimer(id
, GetTimeoutForPriority((*iter
)->priority()));
389 void PopupTimersController::OnNotificationRemoved(const std::string
& id
,
394 } // namespace internal
396 ////////////////////////////////////////////////////////////////////////////////
397 // MessageCenterImpl::NotificationCache
399 MessageCenterImpl::NotificationCache::NotificationCache()
402 MessageCenterImpl::NotificationCache::~NotificationCache() {}
404 void MessageCenterImpl::NotificationCache::Rebuild(
405 const NotificationList::Notifications
& notifications
) {
406 visible_notifications
= notifications
;
410 void MessageCenterImpl::NotificationCache::RecountUnread() {
412 for (NotificationList::Notifications::const_iterator iter
=
413 visible_notifications
.begin();
414 iter
!= visible_notifications
.end(); ++iter
) {
415 if (!(*iter
)->IsRead())
420 ////////////////////////////////////////////////////////////////////////////////
423 MessageCenterImpl::MessageCenterImpl()
425 popup_timers_controller_(new internal::PopupTimersController(this)),
426 settings_provider_(NULL
) {
427 notification_list_
.reset(new NotificationList());
428 notification_queue_
.reset(new internal::ChangeQueue());
431 MessageCenterImpl::~MessageCenterImpl() {
432 SetNotifierSettingsProvider(NULL
);
435 void MessageCenterImpl::AddObserver(MessageCenterObserver
* observer
) {
436 observer_list_
.AddObserver(observer
);
439 void MessageCenterImpl::RemoveObserver(MessageCenterObserver
* observer
) {
440 observer_list_
.RemoveObserver(observer
);
443 void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker
* blocker
) {
444 if (std::find(blockers_
.begin(), blockers_
.end(), blocker
) !=
448 blocker
->AddObserver(this);
449 blockers_
.push_back(blocker
);
452 void MessageCenterImpl::RemoveNotificationBlocker(
453 NotificationBlocker
* blocker
) {
454 std::vector
<NotificationBlocker
*>::iterator iter
=
455 std::find(blockers_
.begin(), blockers_
.end(), blocker
);
456 if (iter
== blockers_
.end())
458 blocker
->RemoveObserver(this);
459 blockers_
.erase(iter
);
462 void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker
* blocker
) {
463 std::list
<std::string
> blocked_ids
;
464 NotificationList::PopupNotifications popups
=
465 notification_list_
->GetPopupNotifications(blockers_
, &blocked_ids
);
467 for (std::list
<std::string
>::const_iterator iter
= blocked_ids
.begin();
468 iter
!= blocked_ids
.end(); ++iter
) {
469 // Do not call MessageCenterImpl::MarkSinglePopupAsShown() directly here
470 // just for performance reason. MessageCenterImpl::MarkSinglePopupAsShown()
471 // calls NotificationList::MarkSinglePopupAsShown() and then updates the
472 // unread count, but the whole cache will be recreated below.
473 notification_list_
->MarkSinglePopupAsShown((*iter
), true);
474 FOR_EACH_OBSERVER(MessageCenterObserver
,
476 OnNotificationUpdated(*iter
));
478 notification_cache_
.Rebuild(
479 notification_list_
->GetVisibleNotifications(blockers_
));
480 FOR_EACH_OBSERVER(MessageCenterObserver
,
482 OnBlockingStateChanged(blocker
));
485 void MessageCenterImpl::UpdateIconImage(
486 const NotifierId
& notifier_id
,const gfx::Image
& icon
) {}
488 void MessageCenterImpl::NotifierGroupChanged() {}
490 void MessageCenterImpl::NotifierEnabledChanged(
491 const NotifierId
& notifier_id
, bool enabled
) {
493 RemoveNotificationsForNotifierId(notifier_id
);
497 void MessageCenterImpl::SetVisibility(Visibility visibility
) {
498 std::set
<std::string
> updated_ids
;
499 notification_list_
->SetMessageCenterVisible(
500 (visibility
== VISIBILITY_MESSAGE_CENTER
), &updated_ids
);
501 notification_cache_
.RecountUnread();
503 for (std::set
<std::string
>::const_iterator iter
= updated_ids
.begin();
504 iter
!= updated_ids
.end();
507 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(*iter
));
510 if (visibility
== VISIBILITY_TRANSIENT
)
511 notification_queue_
->ApplyChanges(this);
513 FOR_EACH_OBSERVER(MessageCenterObserver
,
515 OnCenterVisibilityChanged(visibility
));
518 bool MessageCenterImpl::IsMessageCenterVisible() const {
519 return notification_list_
->is_message_center_visible();
522 size_t MessageCenterImpl::NotificationCount() const {
523 return notification_cache_
.visible_notifications
.size();
526 size_t MessageCenterImpl::UnreadNotificationCount() const {
527 return notification_cache_
.unread_count
;
530 bool MessageCenterImpl::HasPopupNotifications() const {
531 return !IsMessageCenterVisible() &&
532 notification_list_
->HasPopupNotifications(blockers_
);
535 bool MessageCenterImpl::IsQuietMode() const {
536 return notification_list_
->quiet_mode();
539 bool MessageCenterImpl::HasClickedListener(const std::string
& id
) {
540 scoped_refptr
<NotificationDelegate
> delegate
=
541 notification_list_
->GetNotificationDelegate(id
);
542 return delegate
.get() && delegate
->HasClickedListener();
545 message_center::Notification
* MessageCenterImpl::FindVisibleNotificationById(
546 const std::string
& id
) {
547 return notification_list_
->GetNotificationById(id
);
550 const NotificationList::Notifications
&
551 MessageCenterImpl::GetVisibleNotifications() {
552 return notification_cache_
.visible_notifications
;
555 NotificationList::PopupNotifications
556 MessageCenterImpl::GetPopupNotifications() {
557 return notification_list_
->GetPopupNotifications(blockers_
, NULL
);
560 //------------------------------------------------------------------------------
561 // Client code interface.
562 void MessageCenterImpl::AddNotification(scoped_ptr
<Notification
> notification
) {
563 DCHECK(notification
.get());
564 const std::string id
= notification
->id();
565 for (size_t i
= 0; i
< blockers_
.size(); ++i
)
566 blockers_
[i
]->CheckState();
568 if (notification_list_
->is_message_center_visible()) {
569 notification_queue_
->AddNotification(notification
.Pass());
573 // Sometimes the notification can be added with the same id and the
574 // |notification_list| will replace the notification instead of adding new.
575 // This is essentially an update rather than addition.
576 bool already_exists
= (notification_list_
->GetNotificationById(id
) != NULL
);
577 notification_list_
->AddNotification(notification
.Pass());
578 notification_cache_
.Rebuild(
579 notification_list_
->GetVisibleNotifications(blockers_
));
581 if (already_exists
) {
583 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(id
));
586 MessageCenterObserver
, observer_list_
, OnNotificationAdded(id
));
590 void MessageCenterImpl::UpdateNotification(
591 const std::string
& old_id
,
592 scoped_ptr
<Notification
> new_notification
) {
593 for (size_t i
= 0; i
< blockers_
.size(); ++i
)
594 blockers_
[i
]->CheckState();
596 if (notification_list_
->is_message_center_visible()) {
597 // We will allow notifications that are progress types (and stay progress
598 // types) to be updated even if the message center is open. There are 3
599 // requirements here:
600 // * Notification of type PROGRESS exists with same ID in the center
601 // * There are no queued updates for this notification (they imply a change
602 // that violates the PROGRESS invariant
603 // * The new notification is type PROGRESS.
604 // TODO(dewittj): Ensure this works when the ID is changed by the caller.
605 // This shouldn't be an issue in practice since only W3C notifications
606 // change the ID on update, and they don't have progress type notifications.
607 bool update_keeps_progress_type
=
608 new_notification
->type() == NOTIFICATION_TYPE_PROGRESS
&&
609 !notification_queue_
->Has(old_id
) &&
610 notification_list_
->HasNotificationOfType(old_id
,
611 NOTIFICATION_TYPE_PROGRESS
);
612 if (!update_keeps_progress_type
) {
613 // Updates are allowed only for progress notifications.
614 notification_queue_
->UpdateNotification(old_id
, new_notification
.Pass());
619 std::string new_id
= new_notification
->id();
620 notification_list_
->UpdateNotificationMessage(old_id
,
621 new_notification
.Pass());
622 notification_cache_
.Rebuild(
623 notification_list_
->GetVisibleNotifications(blockers_
));
624 if (old_id
== new_id
) {
626 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(new_id
));
628 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
629 OnNotificationRemoved(old_id
, false));
630 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
631 OnNotificationAdded(new_id
));
635 void MessageCenterImpl::RemoveNotification(const std::string
& id
,
637 if (!by_user
&& notification_list_
->is_message_center_visible()) {
638 notification_queue_
->EraseNotification(id
, by_user
);
642 if (FindVisibleNotificationById(id
) == NULL
)
645 // In many cases |id| is a reference to an existing notification instance
646 // but the instance can be destructed in RemoveNotification(). Hence
647 // copies the id explicitly here.
648 std::string
copied_id(id
);
650 scoped_refptr
<NotificationDelegate
> delegate
=
651 notification_list_
->GetNotificationDelegate(copied_id
);
653 delegate
->Close(by_user
);
655 notification_list_
->RemoveNotification(copied_id
);
656 notification_cache_
.Rebuild(
657 notification_list_
->GetVisibleNotifications(blockers_
));
658 FOR_EACH_OBSERVER(MessageCenterObserver
,
660 OnNotificationRemoved(copied_id
, by_user
));
663 void MessageCenterImpl::RemoveNotificationsForNotifierId(
664 const NotifierId
& notifier_id
) {
665 NotificationList::Notifications notifications
=
666 notification_list_
->GetNotificationsByNotifierId(notifier_id
);
667 for (NotificationList::Notifications::const_iterator iter
=
668 notifications
.begin(); iter
!= notifications
.end(); ++iter
) {
669 RemoveNotification((*iter
)->id(), false);
671 if (!notifications
.empty()) {
672 notification_cache_
.Rebuild(
673 notification_list_
->GetVisibleNotifications(blockers_
));
677 void MessageCenterImpl::RemoveAllNotifications(bool by_user
) {
678 // Using not |blockers_| but an empty list since it wants to remove literally
679 // all notifications.
680 RemoveNotifications(by_user
, NotificationBlockers());
683 void MessageCenterImpl::RemoveAllVisibleNotifications(bool by_user
) {
684 RemoveNotifications(by_user
, blockers_
);
687 void MessageCenterImpl::RemoveNotifications(
689 const NotificationBlockers
& blockers
) {
690 const NotificationList::Notifications notifications
=
691 notification_list_
->GetVisibleNotifications(blockers
);
692 std::set
<std::string
> ids
;
693 for (NotificationList::Notifications::const_iterator iter
=
694 notifications
.begin(); iter
!= notifications
.end(); ++iter
) {
695 ids
.insert((*iter
)->id());
696 scoped_refptr
<NotificationDelegate
> delegate
= (*iter
)->delegate();
698 delegate
->Close(by_user
);
699 notification_list_
->RemoveNotification((*iter
)->id());
703 notification_cache_
.Rebuild(
704 notification_list_
->GetVisibleNotifications(blockers_
));
706 for (std::set
<std::string
>::const_iterator iter
= ids
.begin();
707 iter
!= ids
.end(); ++iter
) {
708 FOR_EACH_OBSERVER(MessageCenterObserver
,
710 OnNotificationRemoved(*iter
, by_user
));
714 void MessageCenterImpl::SetNotificationIcon(const std::string
& notification_id
,
715 const gfx::Image
& image
) {
716 bool updated
= false;
717 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
720 if (queue_notification
) {
721 queue_notification
->set_icon(image
);
724 updated
= notification_list_
->SetNotificationIcon(notification_id
, image
);
728 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
729 OnNotificationUpdated(notification_id
));
733 void MessageCenterImpl::SetNotificationImage(const std::string
& notification_id
,
734 const gfx::Image
& image
) {
735 bool updated
= false;
736 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
739 if (queue_notification
) {
740 queue_notification
->set_image(image
);
743 updated
= notification_list_
->SetNotificationImage(notification_id
, image
);
747 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
748 OnNotificationUpdated(notification_id
));
752 void MessageCenterImpl::SetNotificationButtonIcon(
753 const std::string
& notification_id
, int button_index
,
754 const gfx::Image
& image
) {
755 bool updated
= false;
756 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
759 if (queue_notification
) {
760 queue_notification
->SetButtonIcon(button_index
, image
);
763 updated
= notification_list_
->SetNotificationButtonIcon(
764 notification_id
, button_index
, image
);
768 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
769 OnNotificationUpdated(notification_id
));
773 void MessageCenterImpl::DisableNotificationsByNotifier(
774 const NotifierId
& notifier_id
) {
775 if (settings_provider_
) {
776 // TODO(mukai): SetNotifierEnabled can just accept notifier_id?
777 Notifier
notifier(notifier_id
, base::string16(), true);
778 settings_provider_
->SetNotifierEnabled(notifier
, false);
779 // The settings provider will call back to remove the notifications
780 // belonging to the notifier id.
782 RemoveNotificationsForNotifierId(notifier_id
);
786 void MessageCenterImpl::ClickOnNotification(const std::string
& id
) {
787 if (FindVisibleNotificationById(id
) == NULL
)
789 if (HasPopupNotifications())
790 MarkSinglePopupAsShown(id
, true);
791 scoped_refptr
<NotificationDelegate
> delegate
=
792 notification_list_
->GetNotificationDelegate(id
);
796 MessageCenterObserver
, observer_list_
, OnNotificationClicked(id
));
799 void MessageCenterImpl::ClickOnNotificationButton(const std::string
& id
,
801 if (FindVisibleNotificationById(id
) == NULL
)
803 if (HasPopupNotifications())
804 MarkSinglePopupAsShown(id
, true);
805 scoped_refptr
<NotificationDelegate
> delegate
=
806 notification_list_
->GetNotificationDelegate(id
);
808 delegate
->ButtonClick(button_index
);
810 MessageCenterObserver
, observer_list_
, OnNotificationButtonClicked(
814 void MessageCenterImpl::MarkSinglePopupAsShown(const std::string
& id
,
815 bool mark_notification_as_read
) {
816 if (FindVisibleNotificationById(id
) == NULL
)
818 notification_list_
->MarkSinglePopupAsShown(id
, mark_notification_as_read
);
819 notification_cache_
.RecountUnread();
821 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(id
));
824 void MessageCenterImpl::DisplayedNotification(
825 const std::string
& id
,
826 const DisplaySource source
) {
827 if (FindVisibleNotificationById(id
) == NULL
)
830 if (HasPopupNotifications())
831 notification_list_
->MarkSinglePopupAsDisplayed(id
);
832 notification_cache_
.RecountUnread();
833 scoped_refptr
<NotificationDelegate
> delegate
=
834 notification_list_
->GetNotificationDelegate(id
);
838 MessageCenterObserver
,
840 OnNotificationDisplayed(id
, source
));
843 void MessageCenterImpl::SetNotifierSettingsProvider(
844 NotifierSettingsProvider
* provider
) {
845 if (settings_provider_
) {
846 settings_provider_
->RemoveObserver(this);
847 settings_provider_
= NULL
;
849 settings_provider_
= provider
;
850 if (settings_provider_
)
851 settings_provider_
->AddObserver(this);
854 NotifierSettingsProvider
* MessageCenterImpl::GetNotifierSettingsProvider() {
855 return settings_provider_
;
858 void MessageCenterImpl::SetQuietMode(bool in_quiet_mode
) {
859 if (in_quiet_mode
!= notification_list_
->quiet_mode()) {
860 notification_list_
->SetQuietMode(in_quiet_mode
);
861 FOR_EACH_OBSERVER(MessageCenterObserver
,
863 OnQuietModeChanged(in_quiet_mode
));
865 quiet_mode_timer_
.reset();
868 void MessageCenterImpl::EnterQuietModeWithExpire(
869 const base::TimeDelta
& expires_in
) {
870 if (quiet_mode_timer_
.get()) {
871 // Note that the capital Reset() is the method to restart the timer, not
872 // scoped_ptr::reset().
873 quiet_mode_timer_
->Reset();
875 notification_list_
->SetQuietMode(true);
877 MessageCenterObserver
, observer_list_
, OnQuietModeChanged(true));
879 quiet_mode_timer_
.reset(new base::OneShotTimer
<MessageCenterImpl
>);
880 quiet_mode_timer_
->Start(
884 &MessageCenterImpl::SetQuietMode
, base::Unretained(this), false));
888 void MessageCenterImpl::RestartPopupTimers() {
889 if (popup_timers_controller_
.get())
890 popup_timers_controller_
->StartAll();
893 void MessageCenterImpl::PausePopupTimers() {
894 if (popup_timers_controller_
.get())
895 popup_timers_controller_
->PauseAll();
898 void MessageCenterImpl::DisableTimersForTest() {
899 popup_timers_controller_
.reset();
902 } // namespace message_center