assistant_notification_expiry_monitor.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2019 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 "ash/assistant/assistant_notification_expiry_monitor.h"
  5. #include <algorithm>
  6. #include "ash/assistant/assistant_notification_controller_impl.h"
  7. #include "ash/assistant/model/assistant_notification_model.h"
  8. #include "ash/assistant/model/assistant_notification_model_observer.h"
  9. #include "base/bind.h"
  10. #include "base/time/time.h"
  11. #include "chromeos/ash/services/assistant/public/cpp/assistant_service.h"
  12. namespace ash {
  13. namespace {
  14. bool HasExpired(const AssistantNotificationExpiryMonitor::AssistantNotification*
  15. notification) {
  16. return notification->expiry_time.has_value() &&
  17. (notification->expiry_time.value() <= base::Time::Now());
  18. }
  19. // Returns the minimum of the base::Time instances that actually have a value.
  20. absl::optional<base::Time> Min(absl::optional<base::Time> left,
  21. absl::optional<base::Time> right) {
  22. if (!left.has_value())
  23. return right;
  24. if (!right.has_value())
  25. return left;
  26. return std::min(left.value(), right.value());
  27. }
  28. } // namespace
  29. class AssistantNotificationExpiryMonitor::Observer
  30. : public AssistantNotificationModelObserver {
  31. public:
  32. explicit Observer(AssistantNotificationExpiryMonitor* monitor)
  33. : monitor_(monitor) {}
  34. Observer(const Observer&) = delete;
  35. Observer& operator=(const Observer&) = delete;
  36. ~Observer() override = default;
  37. void OnNotificationAdded(const AssistantNotification& notification) override {
  38. monitor_->UpdateTimer();
  39. }
  40. void OnNotificationUpdated(
  41. const AssistantNotification& notification) override {
  42. monitor_->UpdateTimer();
  43. }
  44. void OnNotificationRemoved(const AssistantNotification& notification,
  45. bool from_server) override {
  46. monitor_->UpdateTimer();
  47. }
  48. void OnAllNotificationsRemoved(bool from_server) override {
  49. monitor_->UpdateTimer();
  50. }
  51. private:
  52. AssistantNotificationExpiryMonitor* const monitor_;
  53. };
  54. AssistantNotificationExpiryMonitor::AssistantNotificationExpiryMonitor(
  55. AssistantNotificationControllerImpl* controller)
  56. : controller_(controller), observer_(std::make_unique<Observer>(this)) {
  57. DCHECK(controller_);
  58. controller_->model()->AddObserver(observer_.get());
  59. }
  60. AssistantNotificationExpiryMonitor::~AssistantNotificationExpiryMonitor() =
  61. default;
  62. void AssistantNotificationExpiryMonitor::UpdateTimer() {
  63. absl::optional<base::TimeDelta> timeout = GetTimerTimeout();
  64. if (timeout) {
  65. timer_.Start(
  66. FROM_HERE, timeout.value(),
  67. base::BindOnce(
  68. &AssistantNotificationExpiryMonitor::RemoveExpiredNotifications,
  69. base::Unretained(this)));
  70. } else {
  71. timer_.Stop();
  72. }
  73. }
  74. absl::optional<base::TimeDelta>
  75. AssistantNotificationExpiryMonitor::GetTimerTimeout() const {
  76. absl::optional<base::Time> endtime = GetTimerEndTime();
  77. if (endtime)
  78. return endtime.value() - base::Time::Now();
  79. return absl::nullopt;
  80. }
  81. absl::optional<base::Time> AssistantNotificationExpiryMonitor::GetTimerEndTime()
  82. const {
  83. absl::optional<base::Time> result = absl::nullopt;
  84. for (const AssistantNotification* notification : GetNotifications())
  85. result = Min(result, notification->expiry_time);
  86. return result;
  87. }
  88. void AssistantNotificationExpiryMonitor::RemoveExpiredNotifications() {
  89. for (const NotificationId& id : GetExpiredNotifications()) {
  90. VLOG(1) << "Removing expired notification '" << id << "'";
  91. controller_->RemoveNotificationById(id, /*from_server=*/false);
  92. }
  93. UpdateTimer();
  94. }
  95. std::vector<AssistantNotificationExpiryMonitor::NotificationId>
  96. AssistantNotificationExpiryMonitor::GetExpiredNotifications() const {
  97. std::vector<NotificationId> result;
  98. for (const AssistantNotification* notification : GetNotifications()) {
  99. if (HasExpired(notification))
  100. result.push_back(notification->client_id);
  101. }
  102. return result;
  103. }
  104. std::vector<const AssistantNotificationExpiryMonitor::AssistantNotification*>
  105. AssistantNotificationExpiryMonitor::GetNotifications() const {
  106. return controller_->model()->GetNotifications();
  107. }
  108. } // namespace ash