session_limit_notification_controller.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright 2014 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/system/session/session_limit_notification_controller.h"
  5. #include "ash/constants/notifier_catalogs.h"
  6. #include "ash/public/cpp/notification_utils.h"
  7. #include "ash/resources/vector_icons/vector_icons.h"
  8. #include "ash/session/session_controller_impl.h"
  9. #include "ash/shell.h"
  10. #include "ash/strings/grit/ash_strings.h"
  11. #include "ash/system/model/session_length_limit_model.h"
  12. #include "ash/system/model/system_tray_model.h"
  13. #include "ui/base/l10n/l10n_util.h"
  14. #include "ui/base/l10n/time_format.h"
  15. #include "ui/message_center/message_center.h"
  16. #include "ui/message_center/public/cpp/notification.h"
  17. namespace ash {
  18. namespace {
  19. const char kNotifierSessionLengthTimeout[] = "ash.session-length-timeout";
  20. // A notification is shown to the user only if the remaining session time falls
  21. // under this threshold. e.g. If the user has several days left in their
  22. // session, there is no use displaying a notification right now.
  23. constexpr base::TimeDelta kNotificationThreshold = base::Minutes(60);
  24. } // namespace
  25. // static
  26. const char SessionLimitNotificationController::kNotificationId[] =
  27. "chrome://session/timeout";
  28. SessionLimitNotificationController::SessionLimitNotificationController()
  29. : model_(Shell::Get()->system_tray_model()->session_length_limit()) {
  30. model_->AddObserver(this);
  31. OnSessionLengthLimitUpdated();
  32. }
  33. SessionLimitNotificationController::~SessionLimitNotificationController() {
  34. model_->RemoveObserver(this);
  35. }
  36. void SessionLimitNotificationController::OnSessionLengthLimitUpdated() {
  37. // Don't show notification until the user is logged in.
  38. if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted())
  39. return;
  40. UpdateNotification();
  41. last_limit_state_ = model_->limit_state();
  42. }
  43. void SessionLimitNotificationController::UpdateNotification() {
  44. message_center::MessageCenter* message_center =
  45. message_center::MessageCenter::Get();
  46. // If state hasn't changed and the notification has already been acknowledged,
  47. // we won't re-create it. We consider a notification to be acknowledged if it
  48. // was shown before, but is no longer visible.
  49. if (model_->limit_state() == last_limit_state_ &&
  50. has_notification_been_shown_ &&
  51. !message_center->FindVisibleNotificationById(kNotificationId)) {
  52. return;
  53. }
  54. // After state change, any possibly existing notification is removed to make
  55. // sure it is re-shown even if it had been acknowledged by the user before
  56. // (and in the rare case of state change towards LIMIT_NONE to make the
  57. // notification disappear).
  58. if (model_->limit_state() != last_limit_state_ &&
  59. message_center->FindVisibleNotificationById(kNotificationId)) {
  60. message_center::MessageCenter::Get()->RemoveNotification(
  61. kNotificationId, false /* by_user */);
  62. }
  63. // If the session is unlimited or if the remaining time is too far off into
  64. // the future, there is nothing more to do.
  65. if (model_->limit_state() == SessionLengthLimitModel::LIMIT_NONE ||
  66. model_->remaining_session_time() > kNotificationThreshold) {
  67. return;
  68. }
  69. message_center::RichNotificationData data;
  70. data.should_make_spoken_feedback_for_popup_updates =
  71. (model_->limit_state() != last_limit_state_);
  72. std::unique_ptr<message_center::Notification> notification =
  73. CreateSystemNotification(
  74. message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId,
  75. ComposeNotificationTitle(),
  76. l10n_util::GetStringUTF16(
  77. IDS_ASH_STATUS_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT_MESSAGE),
  78. std::u16string() /* display_source */, GURL(),
  79. message_center::NotifierId(
  80. message_center::NotifierType::SYSTEM_COMPONENT,
  81. kNotifierSessionLengthTimeout,
  82. NotificationCatalogName::kSessionLengthTimeout),
  83. data, nullptr /* delegate */, kNotificationTimerIcon,
  84. message_center::SystemNotificationWarningLevel::WARNING);
  85. notification->set_pinned(true);
  86. if (message_center->FindVisibleNotificationById(kNotificationId)) {
  87. message_center->UpdateNotification(kNotificationId,
  88. std::move(notification));
  89. } else {
  90. message_center->AddNotification(std::move(notification));
  91. }
  92. has_notification_been_shown_ = true;
  93. }
  94. std::u16string SessionLimitNotificationController::ComposeNotificationTitle()
  95. const {
  96. return l10n_util::GetStringFUTF16(
  97. IDS_ASH_STATUS_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT_TITLE,
  98. ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
  99. ui::TimeFormat::LENGTH_SHORT,
  100. model_->remaining_session_time()));
  101. }
  102. } // namespace ash