popup_timers_controller.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2016 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.
  4. #include "ui/message_center/popup_timers_controller.h"
  5. #include <algorithm>
  6. #include "base/containers/contains.h"
  7. #include "build/chromeos_buildflags.h"
  8. #include "ui/message_center/public/cpp/message_center_constants.h"
  9. namespace message_center {
  10. namespace {
  11. bool UseHighPriorityDelay(Notification* notification) {
  12. // Web Notifications are given a longer on-screen time on non-Chrome OS
  13. // platforms as there is no notification center to dismiss them to.
  14. #if BUILDFLAG(IS_CHROMEOS_ASH)
  15. const bool use_high_priority_delay =
  16. notification->priority() > DEFAULT_PRIORITY;
  17. #else
  18. const bool use_high_priority_delay =
  19. notification->priority() > DEFAULT_PRIORITY ||
  20. notification->notifier_id().type == NotifierType::WEB_PAGE;
  21. #endif
  22. return use_high_priority_delay;
  23. }
  24. } // namespace
  25. // Timeout values used to dismiss notifications automatically after they are
  26. // shown.
  27. int notification_timeout_default_seconds_ = kAutocloseDefaultDelaySeconds;
  28. int notification_timeout_high_priority_seconds_ =
  29. kAutocloseHighPriorityDelaySeconds;
  30. PopupTimersController::PopupTimersController(MessageCenter* message_center)
  31. : message_center_(message_center) {
  32. message_center_->AddObserver(this);
  33. }
  34. PopupTimersController::~PopupTimersController() {
  35. message_center_->RemoveObserver(this);
  36. }
  37. void PopupTimersController::StartTimer(const std::string& id,
  38. const base::TimeDelta& timeout) {
  39. PopupTimerCollection::const_iterator iter = popup_timers_.find(id);
  40. if (iter != popup_timers_.end()) {
  41. DCHECK(iter->second);
  42. iter->second->Start();
  43. return;
  44. }
  45. std::unique_ptr<PopupTimer> timer(new PopupTimer(id, timeout, AsWeakPtr()));
  46. timer->Start();
  47. popup_timers_.emplace(id, std::move(timer));
  48. }
  49. void PopupTimersController::StartAll() {
  50. for (const auto& iter : popup_timers_)
  51. iter.second->Start();
  52. }
  53. void PopupTimersController::PauseAll() {
  54. for (const auto& iter : popup_timers_)
  55. iter.second->Pause();
  56. }
  57. void PopupTimersController::CancelTimer(const std::string& id) {
  58. popup_timers_.erase(id);
  59. }
  60. void PopupTimersController::SetNotificationTimeouts(int default_timeout,
  61. int high_priority_timeout) {
  62. notification_timeout_default_seconds_ = default_timeout;
  63. notification_timeout_high_priority_seconds_ = high_priority_timeout;
  64. }
  65. void PopupTimersController::CancelAll() {
  66. popup_timers_.clear();
  67. }
  68. void PopupTimersController::TimerFinished(const std::string& id) {
  69. if (!base::Contains(popup_timers_, id))
  70. return;
  71. CancelTimer(id);
  72. message_center_->MarkSinglePopupAsShown(id, false);
  73. }
  74. base::TimeDelta PopupTimersController::GetTimeoutForNotification(
  75. Notification* notification) {
  76. return base::Seconds(UseHighPriorityDelay(notification)
  77. ? notification_timeout_high_priority_seconds_
  78. : notification_timeout_default_seconds_);
  79. }
  80. int PopupTimersController::GetNotificationTimeoutDefault() {
  81. return notification_timeout_default_seconds_;
  82. }
  83. void PopupTimersController::OnNotificationDisplayed(
  84. const std::string& id,
  85. const DisplaySource source) {
  86. OnNotificationUpdated(id);
  87. }
  88. void PopupTimersController::OnNotificationUpdated(const std::string& id) {
  89. NotificationList::PopupNotifications popup_notifications =
  90. message_center_->GetPopupNotifications();
  91. if (popup_notifications.empty()) {
  92. CancelAll();
  93. return;
  94. }
  95. auto iter = popup_notifications.begin();
  96. for (; iter != popup_notifications.end(); ++iter) {
  97. if ((*iter)->id() == id)
  98. break;
  99. }
  100. if (iter == popup_notifications.end() || (*iter)->never_timeout()) {
  101. CancelTimer(id);
  102. return;
  103. }
  104. auto timer = popup_timers_.find(id);
  105. // The timer must already have been started and not be running. Relies on
  106. // the invariant that |popup_timers_| only contains timers that have been
  107. // started.
  108. bool was_paused = timer != popup_timers_.end() && !timer->second->IsRunning();
  109. CancelTimer(id);
  110. StartTimer(id, GetTimeoutForNotification(*iter));
  111. // If a timer was paused before, pause it afterwards as well.
  112. // See crbug.com/710298
  113. if (was_paused) {
  114. popup_timers_.find(id)->second->Pause();
  115. }
  116. }
  117. void PopupTimersController::OnNotificationRemoved(const std::string& id,
  118. bool by_user) {
  119. CancelTimer(id);
  120. }
  121. } // namespace message_center