diff options
Diffstat (limited to 'chromium/ui/message_center/message_center_impl.cc')
-rw-r--r-- | chromium/ui/message_center/message_center_impl.cc | 232 |
1 files changed, 196 insertions, 36 deletions
diff --git a/chromium/ui/message_center/message_center_impl.cc b/chromium/ui/message_center/message_center_impl.cc index c1d0179dc00..2d8c9f22518 100644 --- a/chromium/ui/message_center/message_center_impl.cc +++ b/chromium/ui/message_center/message_center_impl.cc @@ -4,9 +4,13 @@ #include "ui/message_center/message_center_impl.h" +#include <algorithm> + #include "base/observer_list.h" #include "ui/message_center/message_center_style.h" +#include "ui/message_center/message_center_types.h" #include "ui/message_center/notification.h" +#include "ui/message_center/notification_blocker.h" #include "ui/message_center/notification_list.h" #include "ui/message_center/notification_types.h" @@ -27,6 +31,35 @@ namespace message_center { namespace internal { //////////////////////////////////////////////////////////////////////////////// +// NotificationQueueItem + +struct NotificationQueueItem { + public: + Notification* notification; + bool is_update; + std::string pre_update_id; +}; + +void DeleteQueueNotification(NotificationQueueItem item) { + if (item.notification) + delete item.notification; +} + + +//////////////////////////////////////////////////////////////////////////////// +// NotificationFinder + +struct NotificationFinder { + explicit NotificationFinder(const std::string& id) : id(id) {} + bool operator()(const NotificationQueueItem& item) { + DCHECK(item.notification); + return item.notification->id() == id; + } + + std::string id; +}; + +//////////////////////////////////////////////////////////////////////////////// // PopupTimer PopupTimer::PopupTimer(const std::string& id, @@ -194,13 +227,16 @@ void PopupTimersController::OnNotificationRemoved(const std::string& id, MessageCenterImpl::MessageCenterImpl() : MessageCenter(), popup_timers_controller_(new internal::PopupTimersController(this)), - delegate_(NULL), settings_provider_(NULL) { notification_list_.reset(new NotificationList()); } MessageCenterImpl::~MessageCenterImpl() { notification_list_.reset(); + for_each(notification_queue_.begin(), + notification_queue_.end(), + internal::DeleteQueueNotification); + notification_queue_.clear(); } void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) { @@ -211,13 +247,41 @@ void MessageCenterImpl::RemoveObserver(MessageCenterObserver* observer) { observer_list_.RemoveObserver(observer); } -void MessageCenterImpl::SetDelegate(Delegate* delegate) { - delegate_ = delegate; +void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker* blocker) { + if (std::find(blockers_.begin(), blockers_.end(), blocker) != + blockers_.end()) { + return; + } + blocker->AddObserver(this); + blockers_.push_back(blocker); +} + +void MessageCenterImpl::RemoveNotificationBlocker( + NotificationBlocker* blocker) { + std::vector<NotificationBlocker*>::iterator iter = + std::find(blockers_.begin(), blockers_.end(), blocker); + if (iter == blockers_.end()) + return; + blocker->RemoveObserver(this); + blockers_.erase(iter); } -void MessageCenterImpl::SetMessageCenterVisible(bool visible) { +void MessageCenterImpl::OnBlockingStateChanged() { + std::list<std::string> blocked_ids; + NotificationList::PopupNotifications popups = + notification_list_->GetPopupNotifications(blockers_, &blocked_ids); + + for (std::list<std::string>::const_iterator iter = blocked_ids.begin(); + iter != blocked_ids.end(); ++iter) { + MarkSinglePopupAsShown((*iter), true); + } +} + +void MessageCenterImpl::SetVisibility(Visibility visibility) { std::set<std::string> updated_ids; - notification_list_->SetMessageCenterVisible(visible, &updated_ids); + notification_list_->SetMessageCenterVisible( + (visibility == VISIBILITY_MESSAGE_CENTER), &updated_ids); + for (std::set<std::string>::const_iterator iter = updated_ids.begin(); iter != updated_ids.end(); ++iter) { @@ -225,10 +289,26 @@ void MessageCenterImpl::SetMessageCenterVisible(bool visible) { MessageCenterObserver, observer_list_, OnNotificationUpdated(*iter)); } - if (!visible) { - FOR_EACH_OBSERVER( - MessageCenterObserver, observer_list_, OnNotificationCenterClosed()); + if (visibility == VISIBILITY_TRANSIENT) { + for (std::list<internal::NotificationQueueItem>::const_iterator iter = + notification_queue_.begin(); + iter != notification_queue_.end(); + ++iter) { + // Warning: After this line, the queue will no longer own the + // notifications contained. + if ((*iter).is_update) + UpdateNotification((*iter).pre_update_id, + scoped_ptr<Notification>((*iter).notification)); + else + AddNotification(scoped_ptr<Notification>((*iter).notification)); + } + // This does not delete the internal notification pointers since they are + // now owned by the notification list. + notification_queue_.clear(); } + FOR_EACH_OBSERVER(MessageCenterObserver, + observer_list_, + OnCenterVisibilityChanged(visibility)); } bool MessageCenterImpl::IsMessageCenterVisible() { @@ -244,7 +324,7 @@ size_t MessageCenterImpl::UnreadNotificationCount() const { } bool MessageCenterImpl::HasPopupNotifications() const { - return notification_list_->HasPopupNotifications(); + return notification_list_->HasPopupNotifications(blockers_); } bool MessageCenterImpl::HasNotification(const std::string& id) { @@ -267,7 +347,7 @@ const NotificationList::Notifications& MessageCenterImpl::GetNotifications() { NotificationList::PopupNotifications MessageCenterImpl::GetPopupNotifications() { - return notification_list_->GetPopupNotifications(); + return notification_list_->GetPopupNotifications(blockers_, NULL); } //------------------------------------------------------------------------------ @@ -275,6 +355,27 @@ NotificationList::PopupNotifications void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) { DCHECK(notification.get()); + for (size_t i = 0; i < blockers_.size(); ++i) + blockers_[i]->CheckState(); + + if (notification_list_->is_message_center_visible()) { + std::list<internal::NotificationQueueItem>::iterator iter = std::find_if( + notification_queue_.begin(), + notification_queue_.end(), + internal::NotificationFinder(notification->id())); + if (iter != notification_queue_.end()) { + internal::DeleteQueueNotification(*iter); + notification_queue_.erase(iter); + } + internal::NotificationQueueItem item = { + notification.release(), + false, + std::string() + }; + notification_queue_.push_back(item); + return; + } + // Sometimes the notification can be added with the same id and the // |notification_list| will replace the notification instead of adding new. // This is essentially an update rather than addition. @@ -294,6 +395,38 @@ void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) { void MessageCenterImpl::UpdateNotification( const std::string& old_id, scoped_ptr<Notification> new_notification) { + for (size_t i = 0; i < blockers_.size(); ++i) + blockers_[i]->CheckState(); + + // We will allow notifications that are progress types (and stay progress + // types) to be updated even if the message center is open. + bool update_keeps_progress_type = + new_notification->type() == NOTIFICATION_TYPE_PROGRESS; + if (!notification_list_->HasNotificationOfType(old_id, + NOTIFICATION_TYPE_PROGRESS)) { + update_keeps_progress_type = false; + } + + // Updates are allowed only for progress notifications. + if (notification_list_->is_message_center_visible() && + !update_keeps_progress_type) { + std::list<internal::NotificationQueueItem>::iterator iter = std::find_if( + notification_queue_.begin(), + notification_queue_.end(), + internal::NotificationFinder(old_id)); + if (iter != notification_queue_.end()) { + internal::DeleteQueueNotification(*iter); + notification_queue_.erase(iter); + } + internal::NotificationQueueItem item = { + new_notification.release(), + true, + old_id + }; + notification_queue_.push_back(item); + return; + } + std::string new_id = new_notification->id(); notification_list_->UpdateNotificationMessage(old_id, new_notification.Pass()); @@ -310,6 +443,15 @@ void MessageCenterImpl::UpdateNotification( void MessageCenterImpl::RemoveNotification(const std::string& id, bool by_user) { + std::list<internal::NotificationQueueItem>::iterator iter = std::find_if( + notification_queue_.begin(), + notification_queue_.end(), + internal::NotificationFinder(id)); + if (iter != notification_queue_.end()) { + DeleteQueueNotification(*iter); + notification_queue_.erase(iter); + } + if (!HasNotification(id)) return; @@ -335,6 +477,9 @@ void MessageCenterImpl::RemoveAllNotifications(bool by_user) { for (NotificationList::Notifications::const_iterator iter = notifications.begin(); iter != notifications.end(); ++iter) { ids.insert((*iter)->id()); + NotificationDelegate* delegate = (*iter)->delegate(); + if (delegate) + delegate->Close(by_user); } notification_list_->RemoveAllNotifications(); @@ -348,7 +493,17 @@ void MessageCenterImpl::RemoveAllNotifications(bool by_user) { void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id, const gfx::Image& image) { - if (notification_list_->SetNotificationIcon(notification_id, image)) { + std::list<internal::NotificationQueueItem>::iterator iter = std::find_if( + notification_queue_.begin(), + notification_queue_.end(), + internal::NotificationFinder(notification_id)); + bool found = iter != notification_queue_.end(); + if (found) + iter->notification->set_icon(image); + else + found = notification_list_->SetNotificationIcon(notification_id, image); + + if (found) { FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_, OnNotificationUpdated(notification_id)); } @@ -374,27 +529,16 @@ void MessageCenterImpl::SetNotificationButtonIcon( } } -void MessageCenterImpl::DisableNotificationsByExtension( - const std::string& id) { - if (delegate_) - delegate_->DisableExtension(id); - - NotificationList::Notifications notifications = - notification_list_->GetNotificationsByExtension(id); - for (NotificationList::Notifications::const_iterator iter = - notifications.begin(); iter != notifications.end();) { - std::string id = (*iter)->id(); - iter++; - RemoveNotification(id, false); +void MessageCenterImpl::DisableNotificationsByNotifier( + const NotifierId& notifier_id) { + if (settings_provider_) { + // TODO(mukai): SetNotifierEnabled can just accept notifier_id? + Notifier notifier(notifier_id, base::string16(), true); + settings_provider_->SetNotifierEnabled(notifier, false); } -} - -void MessageCenterImpl::DisableNotificationsByUrl(const std::string& id) { - if (delegate_) - delegate_->DisableNotificationsFromSource(id); NotificationList::Notifications notifications = - notification_list_->GetNotificationsBySource(id); + notification_list_->GetNotificationsByNotifierId(notifier_id); for (NotificationList::Notifications::const_iterator iter = notifications.begin(); iter != notifications.end();) { std::string id = (*iter)->id(); @@ -403,11 +547,6 @@ void MessageCenterImpl::DisableNotificationsByUrl(const std::string& id) { } } -void MessageCenterImpl::ShowNotificationSettings(const std::string& id) { - if (delegate_) - delegate_->ShowSettings(id); -} - void MessageCenterImpl::ExpandNotification(const std::string& id) { if (!HasNotification(id)) return; @@ -477,12 +616,33 @@ NotifierSettingsProvider* MessageCenterImpl::GetNotifierSettingsProvider() { } void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) { - notification_list_->SetQuietMode(in_quiet_mode); + if (in_quiet_mode != notification_list_->quiet_mode()) { + notification_list_->SetQuietMode(in_quiet_mode); + FOR_EACH_OBSERVER(MessageCenterObserver, + observer_list_, + OnQuietModeChanged(in_quiet_mode)); + } + quiet_mode_timer_.reset(); } void MessageCenterImpl::EnterQuietModeWithExpire( const base::TimeDelta& expires_in) { - notification_list_->EnterQuietModeWithExpire(expires_in); + if (quiet_mode_timer_.get()) { + // Note that the capital Reset() is the method to restart the timer, not + // scoped_ptr::reset(). + quiet_mode_timer_->Reset(); + } else { + notification_list_->SetQuietMode(true); + FOR_EACH_OBSERVER( + MessageCenterObserver, observer_list_, OnQuietModeChanged(true)); + + quiet_mode_timer_.reset(new base::OneShotTimer<MessageCenterImpl>); + quiet_mode_timer_->Start( + FROM_HERE, + expires_in, + base::Bind( + &MessageCenterImpl::SetQuietMode, base::Unretained(this), false)); + } } void MessageCenterImpl::RestartPopupTimers() { |