ash_message_center_lock_screen_controller.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Copyright 2018 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/message_center/ash_message_center_lock_screen_controller.h"
  5. #include "ash/constants/ash_features.h"
  6. #include "ash/constants/ash_pref_names.h"
  7. #include "ash/constants/notifier_catalogs.h"
  8. #include "ash/login/ui/lock_screen.h"
  9. #include "ash/public/cpp/system/toast_data.h"
  10. #include "ash/session/session_controller_impl.h"
  11. #include "ash/shelf/shelf.h"
  12. #include "ash/shell.h"
  13. #include "ash/strings/grit/ash_strings.h"
  14. #include "ash/system/status_area_widget.h"
  15. #include "ash/system/toast/toast_manager_impl.h"
  16. #include "ash/system/unified/unified_system_tray.h"
  17. #include "base/strings/utf_string_conversions.h"
  18. #include "components/prefs/pref_service.h"
  19. #include "ui/base/l10n/l10n_util.h"
  20. #include "ui/views/widget/widget.h"
  21. namespace ash {
  22. // static private
  23. absl::optional<AshMessageCenterLockScreenController::Mode>
  24. AshMessageCenterLockScreenController::overridden_mode_for_testing_;
  25. // static
  26. bool AshMessageCenterLockScreenController::IsEnabled() {
  27. auto mode = GetMode();
  28. bool is_showing = (mode == Mode::SHOW || mode == Mode::HIDE_SENSITIVE);
  29. // If |isAllowed()| is false, must return false;
  30. DCHECK(!is_showing || IsAllowed());
  31. return is_showing;
  32. }
  33. // static
  34. bool AshMessageCenterLockScreenController::IsAllowed() {
  35. return GetMode() != Mode::PROHIBITED;
  36. }
  37. // static, private
  38. AshMessageCenterLockScreenController::Mode
  39. AshMessageCenterLockScreenController::GetMode() {
  40. if (overridden_mode_for_testing_.has_value())
  41. return *overridden_mode_for_testing_;
  42. if (!features::IsLockScreenNotificationsEnabled())
  43. return Mode::PROHIBITED;
  44. // User prefs may be null in some tests.
  45. PrefService* user_prefs =
  46. Shell::Get()->session_controller()->GetLastActiveUserPrefService();
  47. if (!user_prefs)
  48. return Mode::PROHIBITED;
  49. const std::string& mode =
  50. user_prefs->GetString(prefs::kMessageCenterLockScreenMode);
  51. if (mode == prefs::kMessageCenterLockScreenModeShow)
  52. return Mode::SHOW;
  53. if (mode == prefs::kMessageCenterLockScreenModeHideSensitive &&
  54. features::IsLockScreenHideSensitiveNotificationsSupported())
  55. return Mode::HIDE_SENSITIVE;
  56. return Mode::HIDE;
  57. }
  58. // static, only for testing
  59. void AshMessageCenterLockScreenController::OverrideModeForTest(
  60. absl::optional<AshMessageCenterLockScreenController::Mode> new_mode) {
  61. overridden_mode_for_testing_ = new_mode;
  62. }
  63. namespace {
  64. const char kToastId[] = "ash-lock-screen-manager";
  65. } // anonymous namespace
  66. AshMessageCenterLockScreenController::AshMessageCenterLockScreenController()
  67. : locked_(Shell::Get()->session_controller()->IsScreenLocked()) {}
  68. AshMessageCenterLockScreenController::~AshMessageCenterLockScreenController() {
  69. // Invokes the cancel task if any.
  70. if (cancel_task_)
  71. std::move(cancel_task_).Run();
  72. }
  73. void AshMessageCenterLockScreenController::DismissLockScreenThenExecute(
  74. base::OnceClosure pending_callback,
  75. base::OnceClosure cancel_callback,
  76. int message_id) {
  77. if (locked_) {
  78. // Invokes the previous cancel task if any.
  79. if (cancel_task_)
  80. std::move(cancel_task_).Run();
  81. // Stores the new pending/cancel tasks.
  82. pending_task_ = std::move(pending_callback);
  83. cancel_task_ = std::move(cancel_callback);
  84. EncourageUserToUnlock(message_id);
  85. } else {
  86. DCHECK(pending_task_.is_null());
  87. DCHECK(cancel_task_.is_null());
  88. if (pending_callback)
  89. std::move(pending_callback).Run();
  90. }
  91. }
  92. bool AshMessageCenterLockScreenController::IsScreenLocked() const {
  93. return locked_;
  94. }
  95. void AshMessageCenterLockScreenController::EncourageUserToUnlock(
  96. int message_id) {
  97. DCHECK(locked_);
  98. DCHECK(LockScreen::Get());
  99. DCHECK(LockScreen::Get()->widget());
  100. auto* unified_system_tray =
  101. Shelf::ForWindow(LockScreen::Get()->widget()->GetNativeWindow())
  102. ->GetStatusAreaWidget()
  103. ->unified_system_tray();
  104. if (unified_system_tray) {
  105. // Lockscreen notification works only with the unified system tray.
  106. unified_system_tray->CloseBubble();
  107. }
  108. std::u16string message;
  109. if (message_id != -1) {
  110. message = l10n_util::GetStringUTF16(message_id);
  111. } else {
  112. message =
  113. (Shell::Get()->session_controller()->NumberOfLoggedInUsers() == 1 ||
  114. active_account_id_.empty())
  115. ? l10n_util::GetStringUTF16(
  116. IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION)
  117. : l10n_util::GetStringFUTF16(
  118. IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION_WITH_USER_ID,
  119. base::UTF8ToUTF16(active_account_id_.GetUserEmail()));
  120. }
  121. // TODO(yoshiki): Update UI after the UX finalizes.
  122. Shell::Get()->toast_manager()->Show(
  123. ToastData(kToastId, ToastCatalogName::kEncourageUnlock, message,
  124. ToastData::kInfiniteDuration,
  125. /*visible_on_lock_screen=*/true));
  126. }
  127. void AshMessageCenterLockScreenController::OnLockStateChanged(bool locked) {
  128. if (locked_ == locked)
  129. return;
  130. locked_ = locked;
  131. if (!locked) {
  132. Shell::Get()->toast_manager()->Cancel(kToastId);
  133. // Invokes the pending task and resets the cancel task.
  134. if (pending_task_)
  135. std::move(pending_task_).Run();
  136. std::move(cancel_task_).Reset();
  137. } else {
  138. DCHECK(pending_task_.is_null());
  139. DCHECK(cancel_task_.is_null());
  140. }
  141. }
  142. void AshMessageCenterLockScreenController::OnActiveUserSessionChanged(
  143. const AccountId& account_id) {
  144. if (active_account_id_ == account_id)
  145. return;
  146. active_account_id_ = account_id;
  147. if (locked_) {
  148. // Cancels the current callbacks, if the user switches the active account
  149. // on the lock screen.
  150. DCHECK(Shell::Get());
  151. DCHECK(Shell::Get()->toast_manager());
  152. Shell::Get()->toast_manager()->Cancel(kToastId);
  153. std::move(pending_task_).Reset();
  154. if (cancel_task_)
  155. std::move(cancel_task_).Run();
  156. }
  157. }
  158. } // namespace ash