logout_button_tray.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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/logout_button_tray.h"
  5. #include <memory>
  6. #include "ash/constants/ash_pref_names.h"
  7. #include "ash/public/cpp/ash_typography.h"
  8. #include "ash/resources/vector_icons/vector_icons.h"
  9. #include "ash/session/session_controller_impl.h"
  10. #include "ash/shelf/shelf.h"
  11. #include "ash/shell.h"
  12. #include "ash/style/ash_color_provider.h"
  13. #include "ash/system/session/logout_confirmation_controller.h"
  14. #include "ash/system/status_area_widget.h"
  15. #include "ash/system/tray/tray_constants.h"
  16. #include "ash/system/tray/tray_container.h"
  17. #include "ash/system/user/login_status.h"
  18. #include "base/bind.h"
  19. #include "base/metrics/user_metrics.h"
  20. #include "components/prefs/pref_change_registrar.h"
  21. #include "components/prefs/pref_registry_simple.h"
  22. #include "components/prefs/pref_service.h"
  23. #include "ui/accessibility/ax_node_data.h"
  24. #include "ui/gfx/geometry/size.h"
  25. #include "ui/gfx/paint_vector_icon.h"
  26. #include "ui/views/controls/button/md_text_button.h"
  27. #include "ui/views/layout/fill_layout.h"
  28. namespace ash {
  29. LogoutButtonTray::LogoutButtonTray(Shelf* shelf) : TrayBackgroundView(shelf) {
  30. DCHECK(shelf);
  31. Shell::Get()->session_controller()->AddObserver(this);
  32. button_ =
  33. tray_container()->AddChildView(std::make_unique<views::MdTextButton>(
  34. base::BindRepeating(&LogoutButtonTray::ButtonPressed,
  35. base::Unretained(this)),
  36. std::u16string(), CONTEXT_LAUNCHER_BUTTON));
  37. button_->SetProminent(true);
  38. set_use_bounce_in_animation(false);
  39. SetFocusBehavior(FocusBehavior::NEVER);
  40. }
  41. LogoutButtonTray::~LogoutButtonTray() {
  42. Shell::Get()->session_controller()->RemoveObserver(this);
  43. }
  44. // static
  45. void LogoutButtonTray::RegisterProfilePrefs(PrefRegistrySimple* registry) {
  46. registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false);
  47. registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000);
  48. }
  49. void LogoutButtonTray::UpdateLayout() {
  50. // We must first update the button so that its container can lay it out
  51. // correctly.
  52. UpdateButtonTextAndImage();
  53. tray_container()->UpdateLayout();
  54. }
  55. void LogoutButtonTray::UpdateBackground() {
  56. // The logout button does not have a background.
  57. }
  58. void LogoutButtonTray::OnActiveUserPrefServiceChanged(PrefService* prefs) {
  59. pref_change_registrar_.reset();
  60. pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  61. pref_change_registrar_->Init(prefs);
  62. pref_change_registrar_->Add(
  63. prefs::kShowLogoutButtonInTray,
  64. base::BindRepeating(&LogoutButtonTray::UpdateShowLogoutButtonInTray,
  65. base::Unretained(this)));
  66. pref_change_registrar_->Add(
  67. prefs::kLogoutDialogDurationMs,
  68. base::BindRepeating(&LogoutButtonTray::UpdateLogoutDialogDuration,
  69. base::Unretained(this)));
  70. // Read the initial values.
  71. UpdateShowLogoutButtonInTray();
  72. UpdateLogoutDialogDuration();
  73. }
  74. const char* LogoutButtonTray::GetClassName() const {
  75. return "LogoutButtonTray";
  76. }
  77. void LogoutButtonTray::OnThemeChanged() {
  78. TrayBackgroundView::OnThemeChanged();
  79. auto* color_provider = AshColorProvider::Get();
  80. button_->SetBgColorOverride(color_provider->GetControlsLayerColor(
  81. AshColorProvider::ControlsLayerType::kControlBackgroundColorAlert));
  82. button_->SetEnabledTextColors(color_provider->GetContentLayerColor(
  83. AshColorProvider::ContentLayerType::kButtonLabelColorPrimary));
  84. }
  85. void LogoutButtonTray::UpdateShowLogoutButtonInTray() {
  86. show_logout_button_in_tray_ = pref_change_registrar_->prefs()->GetBoolean(
  87. prefs::kShowLogoutButtonInTray);
  88. UpdateVisibility();
  89. }
  90. void LogoutButtonTray::UpdateLogoutDialogDuration() {
  91. const int duration_ms = pref_change_registrar_->prefs()->GetInteger(
  92. prefs::kLogoutDialogDurationMs);
  93. dialog_duration_ = base::Milliseconds(duration_ms);
  94. }
  95. void LogoutButtonTray::UpdateAfterLoginStatusChange() {
  96. UpdateButtonTextAndImage();
  97. }
  98. void LogoutButtonTray::ClickedOutsideBubble() {}
  99. void LogoutButtonTray::HideBubbleWithView(const TrayBubbleView* bubble_view) {}
  100. std::u16string LogoutButtonTray::GetAccessibleNameForTray() {
  101. return button_->GetText();
  102. }
  103. void LogoutButtonTray::HandleLocaleChange() {
  104. UpdateButtonTextAndImage();
  105. }
  106. void LogoutButtonTray::UpdateVisibility() {
  107. LoginStatus login_status = shelf()->GetStatusAreaWidget()->login_status();
  108. SetVisiblePreferred(show_logout_button_in_tray_ &&
  109. login_status != LoginStatus::NOT_LOGGED_IN &&
  110. login_status != LoginStatus::LOCKED);
  111. }
  112. void LogoutButtonTray::UpdateButtonTextAndImage() {
  113. LoginStatus login_status = shelf()->GetStatusAreaWidget()->login_status();
  114. const std::u16string title =
  115. user::GetLocalizedSignOutStringForStatus(login_status, false);
  116. if (shelf()->IsHorizontalAlignment()) {
  117. button_->SetText(title);
  118. button_->SetImage(views::Button::STATE_NORMAL, gfx::ImageSkia());
  119. button_->SetMinSize(gfx::Size(0, kTrayItemSize));
  120. } else {
  121. button_->SetText(std::u16string());
  122. button_->SetAccessibleName(title);
  123. button_->SetImage(
  124. views::Button::STATE_NORMAL,
  125. gfx::CreateVectorIcon(
  126. kShelfLogoutIcon,
  127. AshColorProvider::Get()->GetContentLayerColor(
  128. AshColorProvider::ContentLayerType::kIconColorPrimary)));
  129. button_->SetMinSize(gfx::Size(kTrayItemSize, kTrayItemSize));
  130. }
  131. UpdateVisibility();
  132. }
  133. void LogoutButtonTray::ButtonPressed() {
  134. if (dialog_duration_ <= base::TimeDelta()) {
  135. if (Shell::Get()->session_controller()->IsDemoSession())
  136. base::RecordAction(base::UserMetricsAction("DemoMode.ExitFromShelf"));
  137. // Sign out immediately if |dialog_duration_| is non-positive.
  138. Shell::Get()->session_controller()->RequestSignOut();
  139. } else if (Shell::Get()->logout_confirmation_controller()) {
  140. Shell::Get()->logout_confirmation_controller()->ConfirmLogout(
  141. base::TimeTicks::Now() + dialog_duration_,
  142. LogoutConfirmationController::Source::kShelfExitButton);
  143. }
  144. }
  145. } // namespace ash