privacy_screen_toast_controller.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2020 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/privacy_screen/privacy_screen_toast_controller.h"
  5. #include "ash/accessibility/accessibility_controller_impl.h"
  6. #include "ash/bubble/bubble_constants.h"
  7. #include "ash/shelf/shelf.h"
  8. #include "ash/shell.h"
  9. #include "ash/system/status_area_widget.h"
  10. #include "ash/system/tray/tray_constants.h"
  11. #include "ash/system/tray/tray_utils.h"
  12. #include "ash/system/unified/unified_system_tray.h"
  13. #include "ash/system/unified/unified_system_tray_bubble.h"
  14. #include "ash/system/unified/unified_system_tray_view.h"
  15. #include "base/bind.h"
  16. #include "base/cxx17_backports.h"
  17. namespace ash {
  18. PrivacyScreenToastController::PrivacyScreenToastController(
  19. UnifiedSystemTray* tray)
  20. : tray_(tray) {
  21. Shell::Get()->privacy_screen_controller()->AddObserver(this);
  22. }
  23. PrivacyScreenToastController::~PrivacyScreenToastController() {
  24. close_timer_.Stop();
  25. if (bubble_widget_ && !bubble_widget_->IsClosed())
  26. bubble_widget_->CloseNow();
  27. Shell::Get()->privacy_screen_controller()->RemoveObserver(this);
  28. }
  29. void PrivacyScreenToastController::ShowToast() {
  30. // If the bubble already exists, update the content of the bubble and extend
  31. // the autoclose timer.
  32. if (bubble_widget_) {
  33. UpdateToastView();
  34. if (!mouse_hovered_)
  35. StartAutoCloseTimer();
  36. return;
  37. }
  38. tray_->CloseSecondaryBubbles();
  39. TrayBubbleView::InitParams init_params;
  40. init_params.shelf_alignment = tray_->shelf()->alignment();
  41. init_params.preferred_width = kPrivacyScreenToastMinWidth;
  42. init_params.delegate = GetWeakPtr();
  43. init_params.parent_window = tray_->GetBubbleWindowContainer();
  44. init_params.anchor_view = nullptr;
  45. init_params.anchor_mode = TrayBubbleView::AnchorMode::kRect;
  46. init_params.anchor_rect = tray_->shelf()->GetSystemTrayAnchorRect();
  47. // Decrease bottom and right insets to compensate for the adjustment of
  48. // the respective edges in Shelf::GetSystemTrayAnchorRect().
  49. init_params.insets = GetTrayBubbleInsets();
  50. init_params.translucent = true;
  51. bubble_view_ = new TrayBubbleView(init_params);
  52. toast_view_ = new PrivacyScreenToastView(
  53. this, base::BindRepeating(&PrivacyScreenToastController::ButtonPressed,
  54. base::Unretained(this)));
  55. bubble_view_->AddChildView(toast_view_);
  56. bubble_widget_ = views::BubbleDialogDelegateView::CreateBubble(bubble_view_);
  57. TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
  58. bubble_view_->InitializeAndShowBubble();
  59. StartAutoCloseTimer();
  60. UpdateToastView();
  61. tray_->SetTrayBubbleHeight(
  62. bubble_widget_->GetWindowBoundsInScreen().height());
  63. // Activate the bubble so ChromeVox can announce the toast.
  64. if (Shell::Get()->accessibility_controller()->spoken_feedback().enabled()) {
  65. bubble_widget_->widget_delegate()->SetCanActivate(true);
  66. bubble_widget_->Activate();
  67. }
  68. }
  69. void PrivacyScreenToastController::HideToast() {
  70. close_timer_.Stop();
  71. if (!bubble_widget_ || bubble_widget_->IsClosed())
  72. return;
  73. bubble_widget_->Close();
  74. tray_->SetTrayBubbleHeight(0);
  75. }
  76. void PrivacyScreenToastController::BubbleViewDestroyed() {
  77. close_timer_.Stop();
  78. bubble_view_ = nullptr;
  79. bubble_widget_ = nullptr;
  80. }
  81. void PrivacyScreenToastController::OnMouseEnteredView() {
  82. close_timer_.Stop();
  83. mouse_hovered_ = true;
  84. }
  85. void PrivacyScreenToastController::OnMouseExitedView() {
  86. StartAutoCloseTimer();
  87. mouse_hovered_ = false;
  88. }
  89. std::u16string PrivacyScreenToastController::GetAccessibleNameForBubble() {
  90. if (!toast_view_)
  91. return std::u16string();
  92. return toast_view_->GetAccessibleName();
  93. }
  94. void PrivacyScreenToastController::OnPrivacyScreenSettingChanged(
  95. bool enabled,
  96. bool notify_ui) {
  97. if (!notify_ui)
  98. return;
  99. if (tray_->IsBubbleShown())
  100. return;
  101. ShowToast();
  102. }
  103. void PrivacyScreenToastController::StartAutoCloseTimer() {
  104. close_timer_.Stop();
  105. // Don't start the timer if the toast is focused.
  106. if (toast_view_ && toast_view_->IsButtonFocused())
  107. return;
  108. int autoclose_delay = kTrayPopupAutoCloseDelayInSeconds;
  109. if (Shell::Get()->accessibility_controller()->spoken_feedback().enabled())
  110. autoclose_delay = kTrayPopupAutoCloseDelayInSecondsWithSpokenFeedback;
  111. close_timer_.Start(FROM_HERE, base::Seconds(autoclose_delay), this,
  112. &PrivacyScreenToastController::HideToast);
  113. }
  114. void PrivacyScreenToastController::UpdateToastView() {
  115. if (toast_view_) {
  116. auto* privacy_screen_controller = Shell::Get()->privacy_screen_controller();
  117. toast_view_->SetPrivacyScreenEnabled(
  118. /*enabled=*/privacy_screen_controller->GetEnabled(),
  119. /*managed=*/privacy_screen_controller->IsManaged());
  120. int width =
  121. base::clamp(toast_view_->GetPreferredSize().width(),
  122. kPrivacyScreenToastMinWidth, kPrivacyScreenToastMaxWidth);
  123. bubble_view_->SetPreferredWidth(width);
  124. }
  125. }
  126. void PrivacyScreenToastController::ButtonPressed() {
  127. auto* privacy_screen_controller = Shell::Get()->privacy_screen_controller();
  128. privacy_screen_controller->SetEnabled(
  129. !privacy_screen_controller->GetEnabled(),
  130. PrivacyScreenController::kToggleUISurfaceToastButton);
  131. }
  132. void PrivacyScreenToastController::StopAutocloseTimer() {
  133. close_timer_.Stop();
  134. }
  135. } // namespace ash