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_
;
114 DISALLOW_COPY_AND_ASSIGN(ChangeQueue
);
117 ////////////////////////////////////////////////////////////////////////////////
120 struct ChangeFinder
{
121 explicit ChangeFinder(const std::string
& id
) : id(id
) {}
122 bool operator()(ChangeQueue::Change
* change
) { return change
->id() == id
; }
127 ////////////////////////////////////////////////////////////////////////////////
128 // ChangeQueue::Change
130 ChangeQueue::Change::Change(ChangeType type
,
131 const std::string
& id
,
132 scoped_ptr
<Notification
> notification
)
135 notification_list_id_(id
),
137 notification_(notification
.Pass()) {
139 DCHECK(type
!= CHANGE_TYPE_DELETE
|| notification_
.get() == NULL
);
142 ChangeQueue::Change::~Change() {}
144 scoped_ptr
<Notification
> ChangeQueue::Change::PassNotification() {
145 return notification_
.Pass();
148 ////////////////////////////////////////////////////////////////////////////////
151 ChangeQueue::ChangeQueue() {}
153 ChangeQueue::~ChangeQueue() {}
155 void ChangeQueue::ApplyChanges(MessageCenter
* message_center
) {
156 // This method is re-entrant.
157 while (!changes_
.empty()) {
158 ScopedVector
<Change
>::iterator iter
= changes_
.begin();
159 scoped_ptr
<Change
> change(*iter
);
160 // TODO(dewittj): Replace changes_ with a deque.
161 changes_
.weak_erase(iter
);
162 // |message_center| is taking ownership of each element here.
163 switch (change
->type()) {
164 case CHANGE_TYPE_ADD
:
165 message_center
->AddNotification(change
->PassNotification());
167 case CHANGE_TYPE_UPDATE
:
168 message_center
->UpdateNotification(change
->notification_list_id(),
169 change
->PassNotification());
171 case CHANGE_TYPE_DELETE
:
172 message_center
->RemoveNotification(change
->notification_list_id(),
181 void ChangeQueue::AddNotification(scoped_ptr
<Notification
> notification
) {
182 std::string id
= notification
->id();
184 scoped_ptr
<Change
> change(
185 new Change(CHANGE_TYPE_ADD
, id
, notification
.Pass()));
186 Replace(id
, change
.Pass());
189 void ChangeQueue::UpdateNotification(const std::string
& old_id
,
190 scoped_ptr
<Notification
> notification
) {
191 std::string new_id
= notification
->id();
192 scoped_ptr
<Change
> change(
193 new Change(CHANGE_TYPE_UPDATE
, new_id
, notification
.Pass()));
194 Replace(old_id
, change
.Pass());
197 void ChangeQueue::EraseNotification(const std::string
& id
, bool by_user
) {
198 scoped_ptr
<Change
> change(new Change(CHANGE_TYPE_DELETE
, id
, nullptr));
199 change
->set_by_user(by_user
);
200 Replace(id
, change
.Pass());
203 bool ChangeQueue::Has(const std::string
& id
) const {
204 ScopedVector
<Change
>::const_iterator iter
=
205 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(id
));
206 return iter
!= changes_
.end();
209 Notification
* ChangeQueue::GetLatestNotification(const std::string
& id
) const {
210 ScopedVector
<Change
>::const_iterator iter
=
211 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(id
));
212 if (iter
== changes_
.end())
215 return (*iter
)->notification();
218 void ChangeQueue::Replace(const std::string
& changed_id
,
219 scoped_ptr
<Change
> new_change
) {
220 ScopedVector
<Change
>::iterator iter
=
221 std::find_if(changes_
.begin(), changes_
.end(), ChangeFinder(changed_id
));
222 if (iter
!= changes_
.end()) {
223 Change
* old_change
= *iter
;
224 new_change
->set_notification_list_id(old_change
->notification_list_id());
225 changes_
.erase(iter
);
227 new_change
->set_notification_list_id(changed_id
);
230 changes_
.push_back(new_change
.release());
233 ////////////////////////////////////////////////////////////////////////////////
236 PopupTimer::PopupTimer(const std::string
& id
,
237 base::TimeDelta timeout
,
238 base::WeakPtr
<PopupTimersController
> controller
)
241 timer_controller_(controller
),
242 timer_(new base::OneShotTimer
<PopupTimersController
>) {}
244 PopupTimer::~PopupTimer() {
248 if (timer_
->IsRunning())
252 void PopupTimer::Start() {
253 if (timer_
->IsRunning())
255 base::TimeDelta timeout_to_close
=
256 timeout_
<= passed_
? base::TimeDelta() : timeout_
- passed_
;
257 start_time_
= base::Time::Now();
262 &PopupTimersController::TimerFinished
, timer_controller_
, id_
));
265 void PopupTimer::Pause() {
266 if (!timer_
|| !timer_
->IsRunning())
270 passed_
+= base::Time::Now() - start_time_
;
273 void PopupTimer::Reset() {
276 passed_
= base::TimeDelta();
279 ////////////////////////////////////////////////////////////////////////////////
280 // PopupTimersController
282 PopupTimersController::PopupTimersController(MessageCenter
* message_center
)
283 : message_center_(message_center
), popup_deleter_(&popup_timers_
) {
284 message_center_
->AddObserver(this);
287 PopupTimersController::~PopupTimersController() {
288 message_center_
->RemoveObserver(this);
291 void PopupTimersController::StartTimer(const std::string
& id
,
292 const base::TimeDelta
& timeout
) {
293 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
294 if (iter
!= popup_timers_
.end()) {
295 DCHECK(iter
->second
);
296 iter
->second
->Start();
300 PopupTimer
* timer
= new PopupTimer(id
, timeout
, AsWeakPtr());
303 popup_timers_
[id
] = timer
;
306 void PopupTimersController::StartAll() {
307 for (auto& iter
: popup_timers_
)
308 iter
.second
->Start();
311 void PopupTimersController::ResetTimer(const std::string
& id
,
312 const base::TimeDelta
& timeout
) {
314 StartTimer(id
, timeout
);
317 void PopupTimersController::PauseTimer(const std::string
& id
) {
318 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
319 if (iter
== popup_timers_
.end())
321 iter
->second
->Pause();
324 void PopupTimersController::PauseAll() {
325 for (auto& iter
: popup_timers_
)
326 iter
.second
->Pause();
329 void PopupTimersController::CancelTimer(const std::string
& id
) {
330 PopupTimerCollection::iterator iter
= popup_timers_
.find(id
);
331 if (iter
== popup_timers_
.end())
335 popup_timers_
.erase(iter
);
338 void PopupTimersController::CancelAll() {
339 STLDeleteValues(&popup_timers_
);
342 void PopupTimersController::TimerFinished(const std::string
& id
) {
343 if (!ContainsKey(popup_timers_
, id
))
347 message_center_
->MarkSinglePopupAsShown(id
, false);
350 void PopupTimersController::OnNotificationDisplayed(
351 const std::string
& id
,
352 const DisplaySource source
) {
353 OnNotificationUpdated(id
);
356 void PopupTimersController::OnNotificationUpdated(const std::string
& id
) {
357 NotificationList::PopupNotifications popup_notifications
=
358 message_center_
->GetPopupNotifications();
360 if (!popup_notifications
.size()) {
365 NotificationList::PopupNotifications::const_iterator iter
=
366 popup_notifications
.begin();
367 for (; iter
!= popup_notifications
.end(); ++iter
) {
368 if ((*iter
)->id() == id
)
372 if (iter
== popup_notifications
.end() || (*iter
)->never_timeout()) {
377 // Start the timer if not yet.
378 if (popup_timers_
.find(id
) == popup_timers_
.end())
379 StartTimer(id
, GetTimeoutForPriority((*iter
)->priority()));
382 void PopupTimersController::OnNotificationRemoved(const std::string
& id
,
387 } // namespace internal
389 ////////////////////////////////////////////////////////////////////////////////
390 // MessageCenterImpl::NotificationCache
392 MessageCenterImpl::NotificationCache::NotificationCache()
395 MessageCenterImpl::NotificationCache::~NotificationCache() {}
397 void MessageCenterImpl::NotificationCache::Rebuild(
398 const NotificationList::Notifications
& notifications
) {
399 visible_notifications
= notifications
;
403 void MessageCenterImpl::NotificationCache::RecountUnread() {
405 for (const auto& notification
: visible_notifications
) {
406 if (!notification
->IsRead())
411 ////////////////////////////////////////////////////////////////////////////////
414 MessageCenterImpl::MessageCenterImpl()
416 popup_timers_controller_(new internal::PopupTimersController(this)),
417 settings_provider_(NULL
) {
418 notification_list_
.reset(new NotificationList());
419 notification_queue_
.reset(new internal::ChangeQueue());
422 MessageCenterImpl::~MessageCenterImpl() {
423 SetNotifierSettingsProvider(NULL
);
426 void MessageCenterImpl::AddObserver(MessageCenterObserver
* observer
) {
427 observer_list_
.AddObserver(observer
);
430 void MessageCenterImpl::RemoveObserver(MessageCenterObserver
* observer
) {
431 observer_list_
.RemoveObserver(observer
);
434 void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker
* blocker
) {
435 if (std::find(blockers_
.begin(), blockers_
.end(), blocker
) !=
439 blocker
->AddObserver(this);
440 blockers_
.push_back(blocker
);
443 void MessageCenterImpl::RemoveNotificationBlocker(
444 NotificationBlocker
* blocker
) {
445 std::vector
<NotificationBlocker
*>::iterator iter
=
446 std::find(blockers_
.begin(), blockers_
.end(), blocker
);
447 if (iter
== blockers_
.end())
449 blocker
->RemoveObserver(this);
450 blockers_
.erase(iter
);
453 void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker
* blocker
) {
454 std::list
<std::string
> blocked_ids
;
455 NotificationList::PopupNotifications popups
=
456 notification_list_
->GetPopupNotifications(blockers_
, &blocked_ids
);
458 for (const auto& id
: blocked_ids
) {
459 // Do not call MessageCenterImpl::MarkSinglePopupAsShown() directly here
460 // just for performance reason. MessageCenterImpl::MarkSinglePopupAsShown()
461 // calls NotificationList::MarkSinglePopupAsShown() and then updates the
462 // unread count, but the whole cache will be recreated below.
463 notification_list_
->MarkSinglePopupAsShown(id
, true);
464 FOR_EACH_OBSERVER(MessageCenterObserver
,
466 OnNotificationUpdated(id
));
468 notification_cache_
.Rebuild(
469 notification_list_
->GetVisibleNotifications(blockers_
));
470 FOR_EACH_OBSERVER(MessageCenterObserver
,
472 OnBlockingStateChanged(blocker
));
475 void MessageCenterImpl::UpdateIconImage(
476 const NotifierId
& notifier_id
, const gfx::Image
& icon
) {}
478 void MessageCenterImpl::NotifierGroupChanged() {}
480 void MessageCenterImpl::NotifierEnabledChanged(
481 const NotifierId
& notifier_id
, bool enabled
) {
483 RemoveNotificationsForNotifierId(notifier_id
);
487 void MessageCenterImpl::SetVisibility(Visibility visibility
) {
488 std::set
<std::string
> updated_ids
;
489 notification_list_
->SetMessageCenterVisible(
490 (visibility
== VISIBILITY_MESSAGE_CENTER
), &updated_ids
);
491 notification_cache_
.RecountUnread();
493 for (const auto& id
: updated_ids
) {
495 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(id
));
498 if (visibility
== VISIBILITY_TRANSIENT
)
499 notification_queue_
->ApplyChanges(this);
501 FOR_EACH_OBSERVER(MessageCenterObserver
,
503 OnCenterVisibilityChanged(visibility
));
506 bool MessageCenterImpl::IsMessageCenterVisible() const {
507 return notification_list_
->is_message_center_visible();
510 size_t MessageCenterImpl::NotificationCount() const {
511 return notification_cache_
.visible_notifications
.size();
514 size_t MessageCenterImpl::UnreadNotificationCount() const {
515 return notification_cache_
.unread_count
;
518 bool MessageCenterImpl::HasPopupNotifications() const {
519 return !IsMessageCenterVisible() &&
520 notification_list_
->HasPopupNotifications(blockers_
);
523 bool MessageCenterImpl::IsQuietMode() const {
524 return notification_list_
->quiet_mode();
527 bool MessageCenterImpl::HasClickedListener(const std::string
& id
) {
528 scoped_refptr
<NotificationDelegate
> delegate
=
529 notification_list_
->GetNotificationDelegate(id
);
530 return delegate
.get() && delegate
->HasClickedListener();
533 message_center::Notification
* MessageCenterImpl::FindVisibleNotificationById(
534 const std::string
& id
) {
535 return notification_list_
->GetNotificationById(id
);
538 const NotificationList::Notifications
&
539 MessageCenterImpl::GetVisibleNotifications() {
540 return notification_cache_
.visible_notifications
;
543 NotificationList::PopupNotifications
544 MessageCenterImpl::GetPopupNotifications() {
545 return notification_list_
->GetPopupNotifications(blockers_
, NULL
);
548 //------------------------------------------------------------------------------
549 // Client code interface.
550 void MessageCenterImpl::AddNotification(scoped_ptr
<Notification
> notification
) {
551 DCHECK(notification
);
552 const std::string id
= notification
->id();
553 for (size_t i
= 0; i
< blockers_
.size(); ++i
)
554 blockers_
[i
]->CheckState();
556 if (notification_list_
->is_message_center_visible()) {
557 notification_queue_
->AddNotification(notification
.Pass());
561 // Sometimes the notification can be added with the same id and the
562 // |notification_list| will replace the notification instead of adding new.
563 // This is essentially an update rather than addition.
564 bool already_exists
= (notification_list_
->GetNotificationById(id
) != NULL
);
565 notification_list_
->AddNotification(notification
.Pass());
566 notification_cache_
.Rebuild(
567 notification_list_
->GetVisibleNotifications(blockers_
));
569 if (already_exists
) {
571 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(id
));
574 MessageCenterObserver
, observer_list_
, OnNotificationAdded(id
));
578 void MessageCenterImpl::UpdateNotification(
579 const std::string
& old_id
,
580 scoped_ptr
<Notification
> new_notification
) {
581 for (size_t i
= 0; i
< blockers_
.size(); ++i
)
582 blockers_
[i
]->CheckState();
584 if (notification_list_
->is_message_center_visible()) {
585 // We will allow notifications that are progress types (and stay progress
586 // types) to be updated even if the message center is open. There are 3
587 // requirements here:
588 // * Notification of type PROGRESS exists with same ID in the center
589 // * There are no queued updates for this notification (they imply a change
590 // that violates the PROGRESS invariant
591 // * The new notification is type PROGRESS.
592 // TODO(dewittj): Ensure this works when the ID is changed by the caller.
593 // This shouldn't be an issue in practice since only W3C notifications
594 // change the ID on update, and they don't have progress type notifications.
595 bool update_keeps_progress_type
=
596 new_notification
->type() == NOTIFICATION_TYPE_PROGRESS
&&
597 !notification_queue_
->Has(old_id
) &&
598 notification_list_
->HasNotificationOfType(old_id
,
599 NOTIFICATION_TYPE_PROGRESS
);
600 if (!update_keeps_progress_type
) {
601 // Updates are allowed only for progress notifications.
602 notification_queue_
->UpdateNotification(old_id
, new_notification
.Pass());
607 std::string new_id
= new_notification
->id();
608 notification_list_
->UpdateNotificationMessage(old_id
,
609 new_notification
.Pass());
610 notification_cache_
.Rebuild(
611 notification_list_
->GetVisibleNotifications(blockers_
));
612 if (old_id
== new_id
) {
614 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(new_id
));
616 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
617 OnNotificationRemoved(old_id
, false));
618 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
619 OnNotificationAdded(new_id
));
623 void MessageCenterImpl::RemoveNotification(const std::string
& id
,
625 if (!by_user
&& notification_list_
->is_message_center_visible()) {
626 notification_queue_
->EraseNotification(id
, by_user
);
630 if (FindVisibleNotificationById(id
) == NULL
)
633 // In many cases |id| is a reference to an existing notification instance
634 // but the instance can be destructed in RemoveNotification(). Hence
635 // copies the id explicitly here.
636 std::string
copied_id(id
);
638 scoped_refptr
<NotificationDelegate
> delegate
=
639 notification_list_
->GetNotificationDelegate(copied_id
);
641 delegate
->Close(by_user
);
643 notification_list_
->RemoveNotification(copied_id
);
644 notification_cache_
.Rebuild(
645 notification_list_
->GetVisibleNotifications(blockers_
));
646 FOR_EACH_OBSERVER(MessageCenterObserver
,
648 OnNotificationRemoved(copied_id
, by_user
));
651 void MessageCenterImpl::RemoveNotificationsForNotifierId(
652 const NotifierId
& notifier_id
) {
653 NotificationList::Notifications notifications
=
654 notification_list_
->GetNotificationsByNotifierId(notifier_id
);
655 for (const auto& notification
: notifications
)
656 RemoveNotification(notification
->id(), false);
657 if (!notifications
.empty()) {
658 notification_cache_
.Rebuild(
659 notification_list_
->GetVisibleNotifications(blockers_
));
663 void MessageCenterImpl::RemoveAllNotifications(bool by_user
) {
664 // Using not |blockers_| but an empty list since it wants to remove literally
665 // all notifications.
666 RemoveNotifications(by_user
, NotificationBlockers());
669 void MessageCenterImpl::RemoveAllVisibleNotifications(bool by_user
) {
670 RemoveNotifications(by_user
, blockers_
);
673 void MessageCenterImpl::RemoveNotifications(
675 const NotificationBlockers
& blockers
) {
676 const NotificationList::Notifications notifications
=
677 notification_list_
->GetVisibleNotifications(blockers
);
678 std::set
<std::string
> ids
;
679 for (const auto& notification
: notifications
) {
680 ids
.insert(notification
->id());
681 scoped_refptr
<NotificationDelegate
> delegate
= notification
->delegate();
683 delegate
->Close(by_user
);
684 notification_list_
->RemoveNotification(notification
->id());
688 notification_cache_
.Rebuild(
689 notification_list_
->GetVisibleNotifications(blockers_
));
691 for (const auto& id
: ids
) {
692 FOR_EACH_OBSERVER(MessageCenterObserver
,
694 OnNotificationRemoved(id
, by_user
));
698 void MessageCenterImpl::SetNotificationIcon(const std::string
& notification_id
,
699 const gfx::Image
& image
) {
700 bool updated
= false;
701 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
704 if (queue_notification
) {
705 queue_notification
->set_icon(image
);
708 updated
= notification_list_
->SetNotificationIcon(notification_id
, image
);
712 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
713 OnNotificationUpdated(notification_id
));
717 void MessageCenterImpl::SetNotificationImage(const std::string
& notification_id
,
718 const gfx::Image
& image
) {
719 bool updated
= false;
720 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
723 if (queue_notification
) {
724 queue_notification
->set_image(image
);
727 updated
= notification_list_
->SetNotificationImage(notification_id
, image
);
731 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
732 OnNotificationUpdated(notification_id
));
736 void MessageCenterImpl::SetNotificationButtonIcon(
737 const std::string
& notification_id
, int button_index
,
738 const gfx::Image
& image
) {
739 bool updated
= false;
740 Notification
* queue_notification
= notification_queue_
->GetLatestNotification(
743 if (queue_notification
) {
744 queue_notification
->SetButtonIcon(button_index
, image
);
747 updated
= notification_list_
->SetNotificationButtonIcon(
748 notification_id
, button_index
, image
);
752 FOR_EACH_OBSERVER(MessageCenterObserver
, observer_list_
,
753 OnNotificationUpdated(notification_id
));
757 void MessageCenterImpl::DisableNotificationsByNotifier(
758 const NotifierId
& notifier_id
) {
759 if (settings_provider_
) {
760 // TODO(mukai): SetNotifierEnabled can just accept notifier_id?
761 Notifier
notifier(notifier_id
, base::string16(), true);
762 settings_provider_
->SetNotifierEnabled(notifier
, false);
763 // The settings provider will call back to remove the notifications
764 // belonging to the notifier id.
766 RemoveNotificationsForNotifierId(notifier_id
);
770 void MessageCenterImpl::ClickOnNotification(const std::string
& id
) {
771 if (FindVisibleNotificationById(id
) == NULL
)
773 if (HasPopupNotifications())
774 MarkSinglePopupAsShown(id
, true);
775 scoped_refptr
<NotificationDelegate
> delegate
=
776 notification_list_
->GetNotificationDelegate(id
);
780 MessageCenterObserver
, observer_list_
, OnNotificationClicked(id
));
783 void MessageCenterImpl::ClickOnNotificationButton(const std::string
& id
,
785 if (FindVisibleNotificationById(id
) == NULL
)
787 if (HasPopupNotifications())
788 MarkSinglePopupAsShown(id
, true);
789 scoped_refptr
<NotificationDelegate
> delegate
=
790 notification_list_
->GetNotificationDelegate(id
);
792 delegate
->ButtonClick(button_index
);
794 MessageCenterObserver
, observer_list_
, OnNotificationButtonClicked(
798 void MessageCenterImpl::MarkSinglePopupAsShown(const std::string
& id
,
799 bool mark_notification_as_read
) {
800 if (FindVisibleNotificationById(id
) == NULL
)
802 notification_list_
->MarkSinglePopupAsShown(id
, mark_notification_as_read
);
803 notification_cache_
.RecountUnread();
805 MessageCenterObserver
, observer_list_
, OnNotificationUpdated(id
));
808 void MessageCenterImpl::DisplayedNotification(
809 const std::string
& id
,
810 const DisplaySource source
) {
811 if (FindVisibleNotificationById(id
) == NULL
)
814 if (HasPopupNotifications())
815 notification_list_
->MarkSinglePopupAsDisplayed(id
);
816 notification_cache_
.RecountUnread();
817 scoped_refptr
<NotificationDelegate
> delegate
=
818 notification_list_
->GetNotificationDelegate(id
);
822 MessageCenterObserver
,
824 OnNotificationDisplayed(id
, source
));
827 void MessageCenterImpl::SetNotifierSettingsProvider(
828 NotifierSettingsProvider
* provider
) {
829 if (settings_provider_
) {
830 settings_provider_
->RemoveObserver(this);
831 settings_provider_
= NULL
;
833 settings_provider_
= provider
;
834 if (settings_provider_
)
835 settings_provider_
->AddObserver(this);
838 NotifierSettingsProvider
* MessageCenterImpl::GetNotifierSettingsProvider() {
839 return settings_provider_
;
842 void MessageCenterImpl::SetQuietMode(bool in_quiet_mode
) {
843 if (in_quiet_mode
!= notification_list_
->quiet_mode()) {
844 notification_list_
->SetQuietMode(in_quiet_mode
);
845 FOR_EACH_OBSERVER(MessageCenterObserver
,
847 OnQuietModeChanged(in_quiet_mode
));
849 quiet_mode_timer_
.reset();
852 void MessageCenterImpl::EnterQuietModeWithExpire(
853 const base::TimeDelta
& expires_in
) {
854 if (quiet_mode_timer_
) {
855 // Note that the capital Reset() is the method to restart the timer, not
856 // scoped_ptr::reset().
857 quiet_mode_timer_
->Reset();
859 notification_list_
->SetQuietMode(true);
861 MessageCenterObserver
, observer_list_
, OnQuietModeChanged(true));
863 quiet_mode_timer_
.reset(new base::OneShotTimer
<MessageCenterImpl
>);
864 quiet_mode_timer_
->Start(
868 &MessageCenterImpl::SetQuietMode
, base::Unretained(this), false));
872 void MessageCenterImpl::RestartPopupTimers() {
873 if (popup_timers_controller_
)
874 popup_timers_controller_
->StartAll();
877 void MessageCenterImpl::PausePopupTimers() {
878 if (popup_timers_controller_
)
879 popup_timers_controller_
->PauseAll();
882 void MessageCenterImpl::DisableTimersForTest() {
883 popup_timers_controller_
.reset();
886 } // namespace message_center