silence_phone_quick_action_controller.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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/phonehub/silence_phone_quick_action_controller.h"
  5. #include "ash/resources/vector_icons/vector_icons.h"
  6. #include "ash/strings/grit/ash_strings.h"
  7. #include "ash/system/phonehub/phone_hub_metrics.h"
  8. #include "ash/system/phonehub/quick_action_item.h"
  9. #include "base/bind.h"
  10. #include "base/timer/timer.h"
  11. #include "ui/base/l10n/l10n_util.h"
  12. namespace ash {
  13. namespace {
  14. using phone_hub_metrics::LogQuickActionClick;
  15. using phone_hub_metrics::QuickAction;
  16. // Time to wait until we check the state of the phone to prevent showing wrong
  17. // state
  18. constexpr base::TimeDelta kWaitForRequestTimeout = base::Seconds(10);
  19. } // namespace
  20. SilencePhoneQuickActionController::SilencePhoneQuickActionController(
  21. phonehub::DoNotDisturbController* dnd_controller)
  22. : dnd_controller_(dnd_controller) {
  23. DCHECK(dnd_controller_);
  24. dnd_controller_->AddObserver(this);
  25. }
  26. SilencePhoneQuickActionController::~SilencePhoneQuickActionController() {
  27. dnd_controller_->RemoveObserver(this);
  28. }
  29. bool SilencePhoneQuickActionController::IsItemEnabled() {
  30. return item_->IsToggled();
  31. }
  32. QuickActionItem* SilencePhoneQuickActionController::CreateItem() {
  33. DCHECK(!item_);
  34. item_ = new QuickActionItem(this, IDS_ASH_PHONE_HUB_SILENCE_PHONE_TITLE,
  35. kPhoneHubSilencePhoneIcon);
  36. item_->icon_button()->set_button_behavior(
  37. FeaturePodIconButton::DisabledButtonBehavior::
  38. kCanDisplayDisabledToggleValue);
  39. OnDndStateChanged();
  40. return item_;
  41. }
  42. void SilencePhoneQuickActionController::OnButtonPressed(bool is_now_enabled) {
  43. // Button should not be pressed if it is disabled.
  44. DCHECK(state_ != ActionState::kDisabled);
  45. LogQuickActionClick(is_now_enabled ? QuickAction::kToggleQuietModeOff
  46. : QuickAction::kToggleQuietModeOn);
  47. requested_state_ = is_now_enabled ? ActionState::kOff : ActionState::kOn;
  48. SetItemState(requested_state_.value());
  49. check_requested_state_timer_ = std::make_unique<base::OneShotTimer>();
  50. check_requested_state_timer_->Start(
  51. FROM_HERE, kWaitForRequestTimeout,
  52. base::BindOnce(&SilencePhoneQuickActionController::CheckRequestedState,
  53. base::Unretained(this)));
  54. dnd_controller_->RequestNewDoNotDisturbState(!is_now_enabled);
  55. }
  56. void SilencePhoneQuickActionController::OnDndStateChanged() {
  57. if (!dnd_controller_->CanRequestNewDndState()) {
  58. state_ = ActionState::kDisabled;
  59. } else if (dnd_controller_->IsDndEnabled()) {
  60. state_ = ActionState::kOn;
  61. } else {
  62. state_ = ActionState::kOff;
  63. }
  64. SetItemState(state_);
  65. // If |requested_state_| correctly resembles the current state, reset it and
  66. // the timer. Reset also if the state is |kDisabled| since we are not
  67. // requesting a state change.
  68. if (state_ == requested_state_ || state_ == ActionState::kDisabled) {
  69. check_requested_state_timer_.reset();
  70. requested_state_.reset();
  71. }
  72. }
  73. void SilencePhoneQuickActionController::SetItemState(ActionState state) {
  74. bool icon_enabled;
  75. bool button_enabled;
  76. int state_text_id;
  77. int sub_label_text;
  78. switch (state) {
  79. case ActionState::kOff:
  80. icon_enabled = false;
  81. button_enabled = true;
  82. state_text_id = IDS_ASH_PHONE_HUB_QUICK_ACTIONS_DISABLED_STATE_TOOLTIP;
  83. sub_label_text = IDS_ASH_PHONE_HUB_QUICK_ACTIONS_OFF_STATE;
  84. break;
  85. case ActionState::kOn:
  86. icon_enabled = true;
  87. button_enabled = true;
  88. state_text_id = IDS_ASH_PHONE_HUB_QUICK_ACTIONS_ENABLED_STATE_TOOLTIP;
  89. sub_label_text = IDS_ASH_PHONE_HUB_QUICK_ACTIONS_ON_STATE;
  90. break;
  91. case ActionState::kDisabled:
  92. icon_enabled = dnd_controller_->IsDndEnabled();
  93. button_enabled = false;
  94. state_text_id = IDS_ASH_PHONE_HUB_SILENCE_BUTTON_NOT_AVAILABLE_TOOLTIP;
  95. sub_label_text = IDS_ASH_PHONE_HUB_QUICK_ACTIONS_NOT_AVAILABLE_STATE;
  96. }
  97. item_->SetEnabled(button_enabled);
  98. item_->SetToggled(icon_enabled);
  99. item_->SetSubLabel(l10n_util::GetStringUTF16(sub_label_text));
  100. if (state == ActionState::kDisabled) {
  101. item_->SetTooltip(l10n_util::GetStringUTF16(state_text_id));
  102. } else {
  103. std::u16string tooltip_state =
  104. l10n_util::GetStringFUTF16(state_text_id, item_->GetItemLabel());
  105. item_->SetTooltip(l10n_util::GetStringFUTF16(
  106. IDS_ASH_PHONE_HUB_QUICK_ACTIONS_TOGGLE_TOOLTIP, item_->GetItemLabel(),
  107. tooltip_state));
  108. }
  109. }
  110. void SilencePhoneQuickActionController::CheckRequestedState() {
  111. // If the current state is different from the requested state, it means that
  112. // we fail to change the state, so switch back to the original one.
  113. if (state_ != requested_state_)
  114. SetItemState(state_);
  115. check_requested_state_timer_.reset();
  116. requested_state_.reset();
  117. }
  118. SilencePhoneQuickActionController::ActionState
  119. SilencePhoneQuickActionController::GetItemState() {
  120. return state_;
  121. }
  122. } // namespace ash