Get foreground tab on Android
[chromium-blink-merge.git] / ui / message_center / message_center_impl.cc
blobc707a2c8ce2282435b0f8476fdf4f19ec7a86545
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"
7 #include <algorithm>
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"
18 namespace {
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);
29 } // namespace
31 namespace message_center {
32 namespace internal {
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.
36 class ChangeQueue {
37 public:
38 enum ChangeType {
39 CHANGE_TYPE_ADD = 0,
40 CHANGE_TYPE_UPDATE,
41 CHANGE_TYPE_DELETE
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.
50 class Change {
51 public:
52 Change(ChangeType type,
53 const std::string& id,
54 scoped_ptr<Notification> notification);
55 ~Change();
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;
72 private:
73 const ChangeType type_;
74 const std::string id_;
75 std::string notification_list_id_;
76 bool by_user_;
77 scoped_ptr<Notification> notification_;
79 DISALLOW_COPY_AND_ASSIGN(Change);
82 ChangeQueue();
83 ~ChangeQueue();
85 // Called when the message center has appropriate visibility. Modifies
86 // |message_center| but does not retain it. This also causes the queue to
87 // empty itself.
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;
109 private:
110 void Replace(const std::string& id, scoped_ptr<Change> change);
112 ScopedVector<Change> changes_;
115 ////////////////////////////////////////////////////////////////////////////////
116 // ChangeFinder
118 struct ChangeFinder {
119 explicit ChangeFinder(const std::string& id) : id(id) {}
120 bool operator()(ChangeQueue::Change* change) { return change->id() == id; }
122 std::string id;
125 ////////////////////////////////////////////////////////////////////////////////
126 // ChangeQueue::Change
128 ChangeQueue::Change::Change(ChangeType type,
129 const std::string& id,
130 scoped_ptr<Notification> notification)
131 : type_(type),
132 id_(id),
133 notification_list_id_(id),
134 by_user_(false),
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 ////////////////////////////////////////////////////////////////////////////////
147 // ChangeQueue
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());
164 break;
165 case CHANGE_TYPE_UPDATE:
166 message_center->UpdateNotification(change->notification_list_id(),
167 change->PassNotification());
168 break;
169 case CHANGE_TYPE_DELETE:
170 message_center->RemoveNotification(change->notification_list_id(),
171 change->by_user());
172 break;
173 default:
174 NOTREACHED();
179 void ChangeQueue::AddNotification(scoped_ptr<Notification> notification) {
180 std::string id = notification->id();
181 scoped_ptr<Change> change(
182 new Change(CHANGE_TYPE_ADD, id, notification.Pass()));
183 Replace(id, change.Pass());
186 void ChangeQueue::UpdateNotification(const std::string& old_id,
187 scoped_ptr<Notification> notification) {
188 std::string new_id = notification->id();
189 scoped_ptr<Change> change(
190 new Change(CHANGE_TYPE_UPDATE, new_id, notification.Pass()));
191 Replace(old_id, change.Pass());
194 void ChangeQueue::EraseNotification(const std::string& id, bool by_user) {
195 scoped_ptr<Change> change(
196 new Change(CHANGE_TYPE_DELETE, id, scoped_ptr<Notification>()));
197 change->set_by_user(by_user);
198 Replace(id, change.Pass());
201 bool ChangeQueue::Has(const std::string& id) const {
202 ScopedVector<Change>::const_iterator iter =
203 std::find_if(changes_.begin(), changes_.end(), ChangeFinder(id));
204 return iter != changes_.end();
207 Notification* ChangeQueue::GetLatestNotification(const std::string& id) const {
208 ScopedVector<Change>::const_iterator iter =
209 std::find_if(changes_.begin(), changes_.end(), ChangeFinder(id));
210 if (iter == changes_.end())
211 return NULL;
213 return (*iter)->notification();
216 void ChangeQueue::Replace(const std::string& changed_id,
217 scoped_ptr<Change> new_change) {
218 ScopedVector<Change>::iterator iter =
219 std::find_if(changes_.begin(), changes_.end(), ChangeFinder(changed_id));
220 if (iter != changes_.end()) {
221 Change* old_change = *iter;
222 new_change->set_notification_list_id(old_change->notification_list_id());
223 changes_.erase(iter);
224 } else {
225 new_change->set_notification_list_id(changed_id);
228 changes_.push_back(new_change.release());
231 ////////////////////////////////////////////////////////////////////////////////
232 // PopupTimer
234 PopupTimer::PopupTimer(const std::string& id,
235 base::TimeDelta timeout,
236 base::WeakPtr<PopupTimersController> controller)
237 : id_(id),
238 timeout_(timeout),
239 timer_controller_(controller),
240 timer_(new base::OneShotTimer<PopupTimersController>) {}
242 PopupTimer::~PopupTimer() {
243 if (!timer_)
244 return;
246 if (timer_->IsRunning())
247 timer_->Stop();
250 void PopupTimer::Start() {
251 if (timer_->IsRunning())
252 return;
253 base::TimeDelta timeout_to_close =
254 timeout_ <= passed_ ? base::TimeDelta() : timeout_ - passed_;
255 start_time_ = base::Time::Now();
256 timer_->Start(
257 FROM_HERE,
258 timeout_to_close,
259 base::Bind(
260 &PopupTimersController::TimerFinished, timer_controller_, id_));
263 void PopupTimer::Pause() {
264 if (!timer_.get() || !timer_->IsRunning())
265 return;
267 timer_->Stop();
268 passed_ += base::Time::Now() - start_time_;
271 void PopupTimer::Reset() {
272 if (timer_)
273 timer_->Stop();
274 passed_ = base::TimeDelta();
277 ////////////////////////////////////////////////////////////////////////////////
278 // PopupTimersController
280 PopupTimersController::PopupTimersController(MessageCenter* message_center)
281 : message_center_(message_center), popup_deleter_(&popup_timers_) {
282 message_center_->AddObserver(this);
285 PopupTimersController::~PopupTimersController() {
286 message_center_->RemoveObserver(this);
289 void PopupTimersController::StartTimer(const std::string& id,
290 const base::TimeDelta& timeout) {
291 PopupTimerCollection::iterator iter = popup_timers_.find(id);
292 if (iter != popup_timers_.end()) {
293 DCHECK(iter->second);
294 iter->second->Start();
295 return;
298 PopupTimer* timer = new PopupTimer(id, timeout, AsWeakPtr());
300 timer->Start();
301 popup_timers_[id] = timer;
304 void PopupTimersController::StartAll() {
305 std::map<std::string, PopupTimer*>::iterator iter;
306 for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
307 iter->second->Start();
311 void PopupTimersController::ResetTimer(const std::string& id,
312 const base::TimeDelta& timeout) {
313 CancelTimer(id);
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())
320 return;
321 iter->second->Pause();
324 void PopupTimersController::PauseAll() {
325 std::map<std::string, PopupTimer*>::iterator iter;
326 for (iter = popup_timers_.begin(); iter != popup_timers_.end(); iter++) {
327 iter->second->Pause();
331 void PopupTimersController::CancelTimer(const std::string& id) {
332 PopupTimerCollection::iterator iter = popup_timers_.find(id);
333 if (iter == popup_timers_.end())
334 return;
336 PopupTimer* timer = iter->second;
337 delete timer;
339 popup_timers_.erase(iter);
342 void PopupTimersController::CancelAll() {
343 STLDeleteValues(&popup_timers_);
344 popup_timers_.clear();
347 void PopupTimersController::TimerFinished(const std::string& id) {
348 PopupTimerCollection::iterator iter = popup_timers_.find(id);
349 if (iter == popup_timers_.end())
350 return;
352 CancelTimer(id);
353 message_center_->MarkSinglePopupAsShown(id, false);
356 void PopupTimersController::OnNotificationDisplayed(const std::string& id) {
357 OnNotificationUpdated(id);
360 void PopupTimersController::OnNotificationUpdated(const std::string& id) {
361 NotificationList::PopupNotifications popup_notifications =
362 message_center_->GetPopupNotifications();
364 if (!popup_notifications.size()) {
365 CancelAll();
366 return;
369 NotificationList::PopupNotifications::const_iterator iter =
370 popup_notifications.begin();
371 for (; iter != popup_notifications.end(); iter++) {
372 if ((*iter)->id() == id)
373 break;
376 if (iter == popup_notifications.end() || (*iter)->never_timeout()) {
377 CancelTimer(id);
378 return;
381 // Start the timer if not yet.
382 if (popup_timers_.find(id) == popup_timers_.end())
383 StartTimer(id, GetTimeoutForPriority((*iter)->priority()));
386 void PopupTimersController::OnNotificationRemoved(const std::string& id,
387 bool by_user) {
388 CancelTimer(id);
391 } // namespace internal
393 ////////////////////////////////////////////////////////////////////////////////
394 // MessageCenterImpl
396 MessageCenterImpl::MessageCenterImpl()
397 : MessageCenter(),
398 popup_timers_controller_(new internal::PopupTimersController(this)),
399 settings_provider_(NULL) {
400 notification_list_.reset(new NotificationList());
401 notification_queue_.reset(new internal::ChangeQueue());
404 MessageCenterImpl::~MessageCenterImpl() {}
406 void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) {
407 observer_list_.AddObserver(observer);
410 void MessageCenterImpl::RemoveObserver(MessageCenterObserver* observer) {
411 observer_list_.RemoveObserver(observer);
414 void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker* blocker) {
415 if (std::find(blockers_.begin(), blockers_.end(), blocker) !=
416 blockers_.end()) {
417 return;
419 blocker->AddObserver(this);
420 blockers_.push_back(blocker);
423 void MessageCenterImpl::RemoveNotificationBlocker(
424 NotificationBlocker* blocker) {
425 std::vector<NotificationBlocker*>::iterator iter =
426 std::find(blockers_.begin(), blockers_.end(), blocker);
427 if (iter == blockers_.end())
428 return;
429 blocker->RemoveObserver(this);
430 blockers_.erase(iter);
433 void MessageCenterImpl::OnBlockingStateChanged() {
434 std::list<std::string> blocked_ids;
435 NotificationList::PopupNotifications popups =
436 notification_list_->GetPopupNotifications(blockers_, &blocked_ids);
438 for (std::list<std::string>::const_iterator iter = blocked_ids.begin();
439 iter != blocked_ids.end(); ++iter) {
440 MarkSinglePopupAsShown((*iter), true);
444 void MessageCenterImpl::SetVisibility(Visibility visibility) {
445 std::set<std::string> updated_ids;
446 notification_list_->SetMessageCenterVisible(
447 (visibility == VISIBILITY_MESSAGE_CENTER), &updated_ids);
449 for (std::set<std::string>::const_iterator iter = updated_ids.begin();
450 iter != updated_ids.end();
451 ++iter) {
452 FOR_EACH_OBSERVER(
453 MessageCenterObserver, observer_list_, OnNotificationUpdated(*iter));
456 if (visibility == VISIBILITY_TRANSIENT)
457 notification_queue_->ApplyChanges(this);
459 FOR_EACH_OBSERVER(MessageCenterObserver,
460 observer_list_,
461 OnCenterVisibilityChanged(visibility));
464 bool MessageCenterImpl::IsMessageCenterVisible() {
465 return notification_list_->is_message_center_visible();
468 size_t MessageCenterImpl::NotificationCount() const {
469 return notification_list_->NotificationCount();
472 size_t MessageCenterImpl::UnreadNotificationCount() const {
473 return notification_list_->unread_count();
476 bool MessageCenterImpl::HasPopupNotifications() const {
477 return notification_list_->HasPopupNotifications(blockers_);
480 bool MessageCenterImpl::HasNotification(const std::string& id) {
481 return notification_list_->HasNotification(id);
484 bool MessageCenterImpl::IsQuietMode() const {
485 return notification_list_->quiet_mode();
488 bool MessageCenterImpl::HasClickedListener(const std::string& id) {
489 NotificationDelegate* delegate =
490 notification_list_->GetNotificationDelegate(id);
491 return delegate && delegate->HasClickedListener();
494 const NotificationList::Notifications&
495 MessageCenterImpl::GetVisibleNotifications() {
496 return notification_list_->GetNotifications();
499 NotificationList::PopupNotifications
500 MessageCenterImpl::GetPopupNotifications() {
501 return notification_list_->GetPopupNotifications(blockers_, NULL);
504 //------------------------------------------------------------------------------
505 // Client code interface.
506 void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) {
507 DCHECK(notification.get());
509 for (size_t i = 0; i < blockers_.size(); ++i)
510 blockers_[i]->CheckState();
512 if (notification_list_->is_message_center_visible()) {
513 notification_queue_->AddNotification(notification.Pass());
514 return;
517 // Sometimes the notification can be added with the same id and the
518 // |notification_list| will replace the notification instead of adding new.
519 // This is essentially an update rather than addition.
520 const std::string& id = notification->id();
521 bool already_exists = notification_list_->HasNotification(id);
522 notification_list_->AddNotification(notification.Pass());
524 if (already_exists) {
525 FOR_EACH_OBSERVER(
526 MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
527 } else {
528 FOR_EACH_OBSERVER(
529 MessageCenterObserver, observer_list_, OnNotificationAdded(id));
533 void MessageCenterImpl::UpdateNotification(
534 const std::string& old_id,
535 scoped_ptr<Notification> new_notification) {
536 for (size_t i = 0; i < blockers_.size(); ++i)
537 blockers_[i]->CheckState();
539 if (notification_list_->is_message_center_visible()) {
540 // We will allow notifications that are progress types (and stay progress
541 // types) to be updated even if the message center is open. There are 3
542 // requirements here:
543 // * Notification of type PROGRESS exists with same ID in the center
544 // * There are no queued updates for this notification (they imply a change
545 // that violates the PROGRESS invariant
546 // * The new notification is type PROGRESS.
547 // TODO(dewittj): Ensure this works when the ID is changed by the caller.
548 // This shouldn't be an issue in practice since only W3C notifications
549 // change the ID on update, and they don't have progress type notifications.
550 bool update_keeps_progress_type =
551 new_notification->type() == NOTIFICATION_TYPE_PROGRESS &&
552 !notification_queue_->Has(old_id) &&
553 notification_list_->HasNotificationOfType(old_id,
554 NOTIFICATION_TYPE_PROGRESS);
555 if (!update_keeps_progress_type) {
556 // Updates are allowed only for progress notifications.
557 notification_queue_->UpdateNotification(old_id, new_notification.Pass());
558 return;
562 std::string new_id = new_notification->id();
563 notification_list_->UpdateNotificationMessage(old_id,
564 new_notification.Pass());
565 if (old_id == new_id) {
566 FOR_EACH_OBSERVER(
567 MessageCenterObserver, observer_list_, OnNotificationUpdated(new_id));
568 } else {
569 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
570 OnNotificationRemoved(old_id, false));
571 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
572 OnNotificationAdded(new_id));
576 void MessageCenterImpl::RemoveNotification(const std::string& id,
577 bool by_user) {
578 if (!by_user && notification_list_->is_message_center_visible()) {
579 notification_queue_->EraseNotification(id, by_user);
580 return;
583 if (!HasNotification(id))
584 return;
586 NotificationDelegate* delegate =
587 notification_list_->GetNotificationDelegate(id);
588 if (delegate)
589 delegate->Close(by_user);
591 // In many cases |id| is a reference to an existing notification instance
592 // but the instance can be destructed in RemoveNotification(). Hence
593 // copies the id explicitly here.
594 std::string copied_id(id);
595 notification_list_->RemoveNotification(copied_id);
596 FOR_EACH_OBSERVER(MessageCenterObserver,
597 observer_list_,
598 OnNotificationRemoved(copied_id, by_user));
601 void MessageCenterImpl::RemoveAllNotifications(bool by_user) {
602 const NotificationList::Notifications& notifications =
603 notification_list_->GetNotifications();
604 std::set<std::string> ids;
605 for (NotificationList::Notifications::const_iterator iter =
606 notifications.begin(); iter != notifications.end(); ++iter) {
607 ids.insert((*iter)->id());
608 NotificationDelegate* delegate = (*iter)->delegate();
609 if (delegate)
610 delegate->Close(by_user);
612 notification_list_->RemoveAllNotifications();
614 for (std::set<std::string>::const_iterator iter = ids.begin();
615 iter != ids.end(); ++iter) {
616 FOR_EACH_OBSERVER(MessageCenterObserver,
617 observer_list_,
618 OnNotificationRemoved(*iter, by_user));
622 void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
623 const gfx::Image& image) {
624 bool updated = false;
625 Notification* queue_notification = notification_queue_->GetLatestNotification(
626 notification_id);
628 if (queue_notification) {
629 queue_notification->set_icon(image);
630 updated = true;
631 } else {
632 updated = notification_list_->SetNotificationIcon(notification_id, image);
635 if (updated) {
636 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
637 OnNotificationUpdated(notification_id));
641 void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
642 const gfx::Image& image) {
643 bool updated = false;
644 Notification* queue_notification = notification_queue_->GetLatestNotification(
645 notification_id);
647 if (queue_notification) {
648 queue_notification->set_image(image);
649 updated = true;
650 } else {
651 updated = notification_list_->SetNotificationImage(notification_id, image);
654 if (updated) {
655 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
656 OnNotificationUpdated(notification_id));
660 void MessageCenterImpl::SetNotificationButtonIcon(
661 const std::string& notification_id, int button_index,
662 const gfx::Image& image) {
663 bool updated = false;
664 Notification* queue_notification = notification_queue_->GetLatestNotification(
665 notification_id);
667 if (queue_notification) {
668 queue_notification->SetButtonIcon(button_index, image);
669 updated = true;
670 } else {
671 updated = notification_list_->SetNotificationButtonIcon(
672 notification_id, button_index, image);
675 if (updated) {
676 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
677 OnNotificationUpdated(notification_id));
681 void MessageCenterImpl::DisableNotificationsByNotifier(
682 const NotifierId& notifier_id) {
683 if (settings_provider_) {
684 // TODO(mukai): SetNotifierEnabled can just accept notifier_id?
685 Notifier notifier(notifier_id, base::string16(), true);
686 settings_provider_->SetNotifierEnabled(notifier, false);
689 NotificationList::Notifications notifications =
690 notification_list_->GetNotificationsByNotifierId(notifier_id);
691 for (NotificationList::Notifications::const_iterator iter =
692 notifications.begin(); iter != notifications.end();) {
693 std::string id = (*iter)->id();
694 iter++;
695 RemoveNotification(id, false);
699 void MessageCenterImpl::ExpandNotification(const std::string& id) {
700 if (!HasNotification(id))
701 return;
702 notification_list_->MarkNotificationAsExpanded(id);
703 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
704 OnNotificationUpdated(id));
707 void MessageCenterImpl::ClickOnNotification(const std::string& id) {
708 if (!HasNotification(id))
709 return;
710 if (HasPopupNotifications())
711 MarkSinglePopupAsShown(id, true);
712 NotificationDelegate* delegate =
713 notification_list_->GetNotificationDelegate(id);
714 if (delegate)
715 delegate->Click();
716 FOR_EACH_OBSERVER(
717 MessageCenterObserver, observer_list_, OnNotificationClicked(id));
720 void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
721 int button_index) {
722 if (!HasNotification(id))
723 return;
724 if (HasPopupNotifications())
725 MarkSinglePopupAsShown(id, true);
726 NotificationDelegate* delegate =
727 notification_list_->GetNotificationDelegate(id);
728 if (delegate)
729 delegate->ButtonClick(button_index);
730 FOR_EACH_OBSERVER(
731 MessageCenterObserver, observer_list_, OnNotificationButtonClicked(
732 id, button_index));
735 void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
736 bool mark_notification_as_read) {
737 if (!HasNotification(id))
738 return;
739 notification_list_->MarkSinglePopupAsShown(id, mark_notification_as_read);
740 FOR_EACH_OBSERVER(
741 MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
744 void MessageCenterImpl::DisplayedNotification(const std::string& id) {
745 if (!HasNotification(id))
746 return;
748 if (HasPopupNotifications())
749 notification_list_->MarkSinglePopupAsDisplayed(id);
750 NotificationDelegate* delegate =
751 notification_list_->GetNotificationDelegate(id);
752 if (delegate)
753 delegate->Display();
754 FOR_EACH_OBSERVER(
755 MessageCenterObserver, observer_list_, OnNotificationDisplayed(id));
758 void MessageCenterImpl::SetNotifierSettingsProvider(
759 NotifierSettingsProvider* provider) {
760 settings_provider_ = provider;
763 NotifierSettingsProvider* MessageCenterImpl::GetNotifierSettingsProvider() {
764 return settings_provider_;
767 void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
768 if (in_quiet_mode != notification_list_->quiet_mode()) {
769 notification_list_->SetQuietMode(in_quiet_mode);
770 FOR_EACH_OBSERVER(MessageCenterObserver,
771 observer_list_,
772 OnQuietModeChanged(in_quiet_mode));
774 quiet_mode_timer_.reset();
777 void MessageCenterImpl::EnterQuietModeWithExpire(
778 const base::TimeDelta& expires_in) {
779 if (quiet_mode_timer_.get()) {
780 // Note that the capital Reset() is the method to restart the timer, not
781 // scoped_ptr::reset().
782 quiet_mode_timer_->Reset();
783 } else {
784 notification_list_->SetQuietMode(true);
785 FOR_EACH_OBSERVER(
786 MessageCenterObserver, observer_list_, OnQuietModeChanged(true));
788 quiet_mode_timer_.reset(new base::OneShotTimer<MessageCenterImpl>);
789 quiet_mode_timer_->Start(
790 FROM_HERE,
791 expires_in,
792 base::Bind(
793 &MessageCenterImpl::SetQuietMode, base::Unretained(this), false));
797 void MessageCenterImpl::RestartPopupTimers() {
798 if (popup_timers_controller_.get())
799 popup_timers_controller_->StartAll();
802 void MessageCenterImpl::PausePopupTimers() {
803 if (popup_timers_controller_.get())
804 popup_timers_controller_->PauseAll();
807 void MessageCenterImpl::DisableTimersForTest() {
808 popup_timers_controller_.reset();
811 } // namespace message_center