| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/message_center/message_center_impl.h" | 5 #include "ui/message_center/message_center_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <utility> |
| 9 | 10 |
| 10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 11 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
| 12 #include "base/observer_list.h" | 13 #include "base/observer_list.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "ui/message_center/message_center_style.h" | 15 #include "ui/message_center/message_center_style.h" |
| 15 #include "ui/message_center/message_center_switches.h" | 16 #include "ui/message_center/message_center_switches.h" |
| 16 #include "ui/message_center/message_center_types.h" | 17 #include "ui/message_center/message_center_types.h" |
| 17 #include "ui/message_center/notification.h" | 18 #include "ui/message_center/notification.h" |
| 18 #include "ui/message_center/notification_blocker.h" | 19 #include "ui/message_center/notification_blocker.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 132 |
| 132 //////////////////////////////////////////////////////////////////////////////// | 133 //////////////////////////////////////////////////////////////////////////////// |
| 133 // ChangeQueue::Change | 134 // ChangeQueue::Change |
| 134 | 135 |
| 135 ChangeQueue::Change::Change(ChangeType type, | 136 ChangeQueue::Change::Change(ChangeType type, |
| 136 const std::string& id, | 137 const std::string& id, |
| 137 scoped_ptr<Notification> notification) | 138 scoped_ptr<Notification> notification) |
| 138 : type_(type), | 139 : type_(type), |
| 139 notification_list_id_(id), | 140 notification_list_id_(id), |
| 140 by_user_(false), | 141 by_user_(false), |
| 141 notification_(notification.Pass()) { | 142 notification_(std::move(notification)) { |
| 142 DCHECK(!id.empty()); | 143 DCHECK(!id.empty()); |
| 143 DCHECK(type != CHANGE_TYPE_DELETE || notification_.get() == NULL); | 144 DCHECK(type != CHANGE_TYPE_DELETE || notification_.get() == NULL); |
| 144 | 145 |
| 145 id_ = notification_ ? notification_->id() : notification_list_id_; | 146 id_ = notification_ ? notification_->id() : notification_list_id_; |
| 146 } | 147 } |
| 147 | 148 |
| 148 ChangeQueue::Change::~Change() {} | 149 ChangeQueue::Change::~Change() {} |
| 149 | 150 |
| 150 scoped_ptr<Notification> ChangeQueue::Change::PassNotification() { | 151 scoped_ptr<Notification> ChangeQueue::Change::PassNotification() { |
| 151 return notification_.Pass(); | 152 return std::move(notification_); |
| 152 } | 153 } |
| 153 | 154 |
| 154 void ChangeQueue::Change::ReplaceNotification( | 155 void ChangeQueue::Change::ReplaceNotification( |
| 155 scoped_ptr<Notification> new_notification) { | 156 scoped_ptr<Notification> new_notification) { |
| 156 id_ = new_notification ? new_notification->id() : notification_list_id_; | 157 id_ = new_notification ? new_notification->id() : notification_list_id_; |
| 157 notification_.swap(new_notification); | 158 notification_.swap(new_notification); |
| 158 } | 159 } |
| 159 | 160 |
| 160 //////////////////////////////////////////////////////////////////////////////// | 161 //////////////////////////////////////////////////////////////////////////////// |
| 161 // ChangeQueue | 162 // ChangeQueue |
| 162 | 163 |
| 163 ChangeQueue::ChangeQueue() {} | 164 ChangeQueue::ChangeQueue() {} |
| 164 | 165 |
| 165 ChangeQueue::~ChangeQueue() {} | 166 ChangeQueue::~ChangeQueue() {} |
| 166 | 167 |
| 167 void ChangeQueue::ApplyChanges(MessageCenterImpl* message_center) { | 168 void ChangeQueue::ApplyChanges(MessageCenterImpl* message_center) { |
| 168 // This method is re-entrant. | 169 // This method is re-entrant. |
| 169 while (!changes_.empty()) { | 170 while (!changes_.empty()) { |
| 170 ScopedVector<Change>::iterator iter = changes_.begin(); | 171 ScopedVector<Change>::iterator iter = changes_.begin(); |
| 171 scoped_ptr<Change> change(*iter); | 172 scoped_ptr<Change> change(*iter); |
| 172 // TODO(dewittj): Replace changes_ with a deque. | 173 // TODO(dewittj): Replace changes_ with a deque. |
| 173 changes_.weak_erase(iter); | 174 changes_.weak_erase(iter); |
| 174 ApplyChangeInternal(message_center, change.Pass()); | 175 ApplyChangeInternal(message_center, std::move(change)); |
| 175 } | 176 } |
| 176 } | 177 } |
| 177 | 178 |
| 178 void ChangeQueue::ApplyChangesForId(MessageCenterImpl* message_center, | 179 void ChangeQueue::ApplyChangesForId(MessageCenterImpl* message_center, |
| 179 const std::string& id) { | 180 const std::string& id) { |
| 180 std::deque<Change*> changes_for_id; | 181 std::deque<Change*> changes_for_id; |
| 181 std::string interesting_id = id; | 182 std::string interesting_id = id; |
| 182 | 183 |
| 183 // Traverses the queue in reverse so shat we can track changes which change | 184 // Traverses the queue in reverse so shat we can track changes which change |
| 184 // the notification's ID. | 185 // the notification's ID. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 197 | 198 |
| 198 while (!changes_for_id.empty()) { | 199 while (!changes_for_id.empty()) { |
| 199 ApplyChangeInternal( | 200 ApplyChangeInternal( |
| 200 message_center, scoped_ptr<Change>(changes_for_id.back())); | 201 message_center, scoped_ptr<Change>(changes_for_id.back())); |
| 201 changes_for_id.pop_back(); | 202 changes_for_id.pop_back(); |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 | 205 |
| 205 void ChangeQueue::AddNotification(scoped_ptr<Notification> notification) { | 206 void ChangeQueue::AddNotification(scoped_ptr<Notification> notification) { |
| 206 std::string id = notification->id(); | 207 std::string id = notification->id(); |
| 207 changes_.push_back( | 208 changes_.push_back(new Change(CHANGE_TYPE_ADD, id, std::move(notification))); |
| 208 new Change(CHANGE_TYPE_ADD, id, notification.Pass())); | |
| 209 } | 209 } |
| 210 | 210 |
| 211 void ChangeQueue::UpdateNotification(const std::string& old_id, | 211 void ChangeQueue::UpdateNotification(const std::string& old_id, |
| 212 scoped_ptr<Notification> notification) { | 212 scoped_ptr<Notification> notification) { |
| 213 ScopedVector<Change>::reverse_iterator iter = | 213 ScopedVector<Change>::reverse_iterator iter = |
| 214 std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(old_id)); | 214 std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(old_id)); |
| 215 if (iter == changes_.rend()) { | 215 if (iter == changes_.rend()) { |
| 216 changes_.push_back( | 216 changes_.push_back( |
| 217 new Change(CHANGE_TYPE_UPDATE, old_id, notification.Pass())); | 217 new Change(CHANGE_TYPE_UPDATE, old_id, std::move(notification))); |
| 218 return; | 218 return; |
| 219 } | 219 } |
| 220 | 220 |
| 221 Change* change = *iter; | 221 Change* change = *iter; |
| 222 switch (change->type()) { | 222 switch (change->type()) { |
| 223 case CHANGE_TYPE_ADD: { | 223 case CHANGE_TYPE_ADD: { |
| 224 std::string id = notification->id(); | 224 std::string id = notification->id(); |
| 225 // Needs to add the change at the last, because if this change updates | 225 // Needs to add the change at the last, because if this change updates |
| 226 // its ID, some previous changes may affect new ID. | 226 // its ID, some previous changes may affect new ID. |
| 227 // (eg. Add A, Update B->C, and This update A->B). | 227 // (eg. Add A, Update B->C, and This update A->B). |
| 228 changes_.erase(--(iter.base())); | 228 changes_.erase(--(iter.base())); |
| 229 changes_.push_back( | 229 changes_.push_back( |
| 230 new Change(CHANGE_TYPE_ADD, id, notification.Pass())); | 230 new Change(CHANGE_TYPE_ADD, id, std::move(notification))); |
| 231 break; | 231 break; |
| 232 } | 232 } |
| 233 case CHANGE_TYPE_UPDATE: | 233 case CHANGE_TYPE_UPDATE: |
| 234 if (notification->id() == old_id) { | 234 if (notification->id() == old_id) { |
| 235 // Safe to place the change at the previous place. | 235 // Safe to place the change at the previous place. |
| 236 change->ReplaceNotification(notification.Pass()); | 236 change->ReplaceNotification(std::move(notification)); |
| 237 } else if (change->id() == change->notification_list_id()) { | 237 } else if (change->id() == change->notification_list_id()) { |
| 238 std::string id = notification->id(); | 238 std::string id = notification->id(); |
| 239 // Safe to place the change at the last. | 239 // Safe to place the change at the last. |
| 240 changes_.erase(--(iter.base())); | 240 changes_.erase(--(iter.base())); |
| 241 changes_.push_back(new Change( | 241 changes_.push_back( |
| 242 CHANGE_TYPE_ADD, id, notification.Pass())); | 242 new Change(CHANGE_TYPE_ADD, id, std::move(notification))); |
| 243 } else { | 243 } else { |
| 244 // Complex case: gives up to optimize. | 244 // Complex case: gives up to optimize. |
| 245 changes_.push_back( | 245 changes_.push_back( |
| 246 new Change(CHANGE_TYPE_UPDATE, old_id, notification.Pass())); | 246 new Change(CHANGE_TYPE_UPDATE, old_id, std::move(notification))); |
| 247 } | 247 } |
| 248 break; | 248 break; |
| 249 case CHANGE_TYPE_DELETE: | 249 case CHANGE_TYPE_DELETE: |
| 250 // DELETE -> UPDATE. Something is wrong. Treats the UPDATE as ADD. | 250 // DELETE -> UPDATE. Something is wrong. Treats the UPDATE as ADD. |
| 251 changes_.push_back( | 251 changes_.push_back( |
| 252 new Change(CHANGE_TYPE_ADD, old_id, notification.Pass())); | 252 new Change(CHANGE_TYPE_ADD, old_id, std::move(notification))); |
| 253 break; | 253 break; |
| 254 default: | 254 default: |
| 255 NOTREACHED(); | 255 NOTREACHED(); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 void ChangeQueue::EraseNotification(const std::string& id, bool by_user) { | 259 void ChangeQueue::EraseNotification(const std::string& id, bool by_user) { |
| 260 ScopedVector<Change>::reverse_iterator iter = | 260 ScopedVector<Change>::reverse_iterator iter = |
| 261 std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(id)); | 261 std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(id)); |
| 262 if (iter == changes_.rend()) { | 262 if (iter == changes_.rend()) { |
| 263 scoped_ptr<Change> change(new Change(CHANGE_TYPE_DELETE, id, nullptr)); | 263 scoped_ptr<Change> change(new Change(CHANGE_TYPE_DELETE, id, nullptr)); |
| 264 change->set_by_user(by_user); | 264 change->set_by_user(by_user); |
| 265 changes_.push_back(change.Pass()); | 265 changes_.push_back(std::move(change)); |
| 266 return; | 266 return; |
| 267 } | 267 } |
| 268 | 268 |
| 269 Change* change = *iter; | 269 Change* change = *iter; |
| 270 switch (change->type()) { | 270 switch (change->type()) { |
| 271 case CHANGE_TYPE_ADD: | 271 case CHANGE_TYPE_ADD: |
| 272 // ADD -> DELETE. Just removes both. | 272 // ADD -> DELETE. Just removes both. |
| 273 changes_.erase(--(iter.base())); | 273 changes_.erase(--(iter.base())); |
| 274 break; | 274 break; |
| 275 case CHANGE_TYPE_UPDATE: | 275 case CHANGE_TYPE_UPDATE: |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 //------------------------------------------------------------------------------ | 507 //------------------------------------------------------------------------------ |
| 508 // Client code interface. | 508 // Client code interface. |
| 509 void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) { | 509 void MessageCenterImpl::AddNotification(scoped_ptr<Notification> notification) { |
| 510 DCHECK(notification); | 510 DCHECK(notification); |
| 511 const std::string id = notification->id(); | 511 const std::string id = notification->id(); |
| 512 for (size_t i = 0; i < blockers_.size(); ++i) | 512 for (size_t i = 0; i < blockers_.size(); ++i) |
| 513 blockers_[i]->CheckState(); | 513 blockers_[i]->CheckState(); |
| 514 | 514 |
| 515 if (notification_queue_ && | 515 if (notification_queue_ && |
| 516 notification_list_->is_message_center_visible()) { | 516 notification_list_->is_message_center_visible()) { |
| 517 notification_queue_->AddNotification(notification.Pass()); | 517 notification_queue_->AddNotification(std::move(notification)); |
| 518 return; | 518 return; |
| 519 } | 519 } |
| 520 | 520 |
| 521 AddNotificationImmediately(notification.Pass()); | 521 AddNotificationImmediately(std::move(notification)); |
| 522 } | 522 } |
| 523 | 523 |
| 524 void MessageCenterImpl::AddNotificationImmediately( | 524 void MessageCenterImpl::AddNotificationImmediately( |
| 525 scoped_ptr<Notification> notification) { | 525 scoped_ptr<Notification> notification) { |
| 526 const std::string id = notification->id(); | 526 const std::string id = notification->id(); |
| 527 | 527 |
| 528 // Sometimes the notification can be added with the same id and the | 528 // Sometimes the notification can be added with the same id and the |
| 529 // |notification_list| will replace the notification instead of adding new. | 529 // |notification_list| will replace the notification instead of adding new. |
| 530 // This is essentially an update rather than addition. | 530 // This is essentially an update rather than addition. |
| 531 bool already_exists = (notification_list_->GetNotificationById(id) != NULL); | 531 bool already_exists = (notification_list_->GetNotificationById(id) != NULL); |
| 532 notification_list_->AddNotification(notification.Pass()); | 532 notification_list_->AddNotification(std::move(notification)); |
| 533 notification_cache_.Rebuild( | 533 notification_cache_.Rebuild( |
| 534 notification_list_->GetVisibleNotifications(blockers_)); | 534 notification_list_->GetVisibleNotifications(blockers_)); |
| 535 | 535 |
| 536 if (already_exists) { | 536 if (already_exists) { |
| 537 FOR_EACH_OBSERVER( | 537 FOR_EACH_OBSERVER( |
| 538 MessageCenterObserver, observer_list_, OnNotificationUpdated(id)); | 538 MessageCenterObserver, observer_list_, OnNotificationUpdated(id)); |
| 539 } else { | 539 } else { |
| 540 FOR_EACH_OBSERVER( | 540 FOR_EACH_OBSERVER( |
| 541 MessageCenterObserver, observer_list_, OnNotificationAdded(id)); | 541 MessageCenterObserver, observer_list_, OnNotificationAdded(id)); |
| 542 } | 542 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 560 // TODO(dewittj): Ensure this works when the ID is changed by the caller. | 560 // TODO(dewittj): Ensure this works when the ID is changed by the caller. |
| 561 // This shouldn't be an issue in practice since only W3C notifications | 561 // This shouldn't be an issue in practice since only W3C notifications |
| 562 // change the ID on update, and they don't have progress type notifications. | 562 // change the ID on update, and they don't have progress type notifications. |
| 563 bool update_keeps_progress_type = | 563 bool update_keeps_progress_type = |
| 564 new_notification->type() == NOTIFICATION_TYPE_PROGRESS && | 564 new_notification->type() == NOTIFICATION_TYPE_PROGRESS && |
| 565 !notification_queue_->Has(old_id) && | 565 !notification_queue_->Has(old_id) && |
| 566 notification_list_->HasNotificationOfType(old_id, | 566 notification_list_->HasNotificationOfType(old_id, |
| 567 NOTIFICATION_TYPE_PROGRESS); | 567 NOTIFICATION_TYPE_PROGRESS); |
| 568 if (!update_keeps_progress_type) { | 568 if (!update_keeps_progress_type) { |
| 569 // Updates are allowed only for progress notifications. | 569 // Updates are allowed only for progress notifications. |
| 570 notification_queue_->UpdateNotification(old_id, new_notification.Pass()); | 570 notification_queue_->UpdateNotification(old_id, |
| 571 std::move(new_notification)); |
| 571 return; | 572 return; |
| 572 } | 573 } |
| 573 } | 574 } |
| 574 | 575 |
| 575 UpdateNotificationImmediately(old_id, new_notification.Pass()); | 576 UpdateNotificationImmediately(old_id, std::move(new_notification)); |
| 576 } | 577 } |
| 577 | 578 |
| 578 void MessageCenterImpl::UpdateNotificationImmediately( | 579 void MessageCenterImpl::UpdateNotificationImmediately( |
| 579 const std::string& old_id, | 580 const std::string& old_id, |
| 580 scoped_ptr<Notification> new_notification) { | 581 scoped_ptr<Notification> new_notification) { |
| 581 std::string new_id = new_notification->id(); | 582 std::string new_id = new_notification->id(); |
| 582 notification_list_->UpdateNotificationMessage(old_id, | 583 notification_list_->UpdateNotificationMessage(old_id, |
| 583 new_notification.Pass()); | 584 std::move(new_notification)); |
| 584 notification_cache_.Rebuild( | 585 notification_cache_.Rebuild( |
| 585 notification_list_->GetVisibleNotifications(blockers_)); | 586 notification_list_->GetVisibleNotifications(blockers_)); |
| 586 if (old_id == new_id) { | 587 if (old_id == new_id) { |
| 587 FOR_EACH_OBSERVER( | 588 FOR_EACH_OBSERVER( |
| 588 MessageCenterObserver, observer_list_, OnNotificationUpdated(new_id)); | 589 MessageCenterObserver, observer_list_, OnNotificationUpdated(new_id)); |
| 589 } else { | 590 } else { |
| 590 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_, | 591 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_, |
| 591 OnNotificationRemoved(old_id, false)); | 592 OnNotificationRemoved(old_id, false)); |
| 592 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_, | 593 FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_, |
| 593 OnNotificationAdded(new_id)); | 594 OnNotificationAdded(new_id)); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 } | 888 } |
| 888 | 889 |
| 889 void MessageCenterImpl::EnableChangeQueueForTest(bool enable) { | 890 void MessageCenterImpl::EnableChangeQueueForTest(bool enable) { |
| 890 if (enable) | 891 if (enable) |
| 891 notification_queue_.reset(new internal::ChangeQueue()); | 892 notification_queue_.reset(new internal::ChangeQueue()); |
| 892 else | 893 else |
| 893 notification_queue_.reset(); | 894 notification_queue_.reset(); |
| 894 } | 895 } |
| 895 | 896 |
| 896 } // namespace message_center | 897 } // namespace message_center |
| OLD | NEW |