| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/system/power/power_button_display_controller.h" |
| |
| #include "ash/accessibility/accessibility_controller_impl.h" |
| #include "ash/media/media_controller_impl.h" |
| #include "ash/shell.h" |
| #include "ash/system/power/scoped_backlights_forced_off.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller.h" |
| #include "base/time/tick_clock.h" |
| #include "chromeos/dbus/power/power_policy_controller.h" |
| #include "ui/events/devices/device_data_manager.h" |
| #include "ui/events/devices/stylus_state.h" |
| #include "ui/events/event.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Returns true if device is currently in tablet/tablet mode, otherwise false. |
| bool IsTabletModeActive() { |
| TabletModeController* tablet_mode_controller = |
| Shell::Get()->tablet_mode_controller(); |
| return tablet_mode_controller && tablet_mode_controller->InTabletMode(); |
| } |
| |
| } // namespace |
| |
| PowerButtonDisplayController::PowerButtonDisplayController( |
| BacklightsForcedOffSetter* backlights_forced_off_setter, |
| const base::TickClock* tick_clock) |
| : backlights_forced_off_setter_(backlights_forced_off_setter), |
| backlights_forced_off_observer_(this), |
| tick_clock_(tick_clock) { |
| chromeos::PowerManagerClient::Get()->AddObserver(this); |
| ui::DeviceDataManager::GetInstance()->AddObserver(this); |
| Shell::Get()->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem); |
| |
| backlights_forced_off_observer_.Add(backlights_forced_off_setter_); |
| } |
| |
| PowerButtonDisplayController::~PowerButtonDisplayController() { |
| Shell::Get()->RemovePreTargetHandler(this); |
| ui::DeviceDataManager::GetInstance()->RemoveObserver(this); |
| chromeos::PowerManagerClient::Get()->RemoveObserver(this); |
| } |
| |
| bool PowerButtonDisplayController::IsScreenOn() const { |
| return backlights_forced_off_setter_->GetScreenState() == ScreenState::ON; |
| } |
| |
| void PowerButtonDisplayController::SetBacklightsForcedOff(bool forced_off) { |
| if ((backlights_forced_off_ != nullptr) == forced_off) |
| return; |
| |
| send_accessibility_alert_on_backlights_forced_off_change_ = true; |
| |
| if (forced_off) { |
| backlights_forced_off_ = |
| backlights_forced_off_setter_->ForceBacklightsOff(); |
| } else { |
| backlights_forced_off_.reset(); |
| } |
| |
| // Let PowerPolicyController update inactivity delays: |
| // https://crbug.com/812504 |
| chromeos::PowerPolicyController::Get() |
| ->HandleBacklightsForcedOffForPowerButton(forced_off); |
| |
| if (forced_off) |
| Shell::Get()->media_controller()->SuspendMediaSessions(); |
| } |
| |
| void PowerButtonDisplayController::OnBacklightsForcedOffChanged( |
| bool forced_off) { |
| if (send_accessibility_alert_on_backlights_forced_off_change_) { |
| Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert( |
| forced_off ? AccessibilityAlert::SCREEN_OFF |
| : AccessibilityAlert::SCREEN_ON); |
| } |
| send_accessibility_alert_on_backlights_forced_off_change_ = false; |
| } |
| |
| void PowerButtonDisplayController::OnScreenStateChanged( |
| ScreenState screen_state) { |
| screen_state_last_changed_ = tick_clock_->NowTicks(); |
| } |
| |
| void PowerButtonDisplayController::SuspendDone( |
| const base::TimeDelta& sleep_duration) { |
| // Stop forcing backlights off on resume to handle situations where the power |
| // button resumed but we didn't receive the event (crbug.com/735291). |
| SetBacklightsForcedOff(false); |
| } |
| |
| void PowerButtonDisplayController::LidEventReceived( |
| chromeos::PowerManagerClient::LidState state, |
| const base::TimeTicks& timestamp) { |
| SetBacklightsForcedOff(false); |
| } |
| |
| void PowerButtonDisplayController::TabletModeEventReceived( |
| chromeos::PowerManagerClient::TabletMode mode, |
| const base::TimeTicks& timestamp) { |
| SetBacklightsForcedOff(false); |
| } |
| |
| void PowerButtonDisplayController::OnKeyEvent(ui::KeyEvent* event) { |
| // Ignore key events generated by the power button since power button activity |
| // is already handled elsewhere. |
| if (event->key_code() == ui::VKEY_POWER) |
| return; |
| |
| if (!IsTabletModeActive()) |
| SetBacklightsForcedOff(false); |
| } |
| |
| void PowerButtonDisplayController::OnMouseEvent(ui::MouseEvent* event) { |
| if (event->flags() & ui::EF_IS_SYNTHESIZED) |
| return; |
| |
| if (!IsTabletModeActive()) |
| SetBacklightsForcedOff(false); |
| } |
| |
| void PowerButtonDisplayController::OnStylusStateChanged(ui::StylusState state) { |
| if (state == ui::StylusState::REMOVED) |
| SetBacklightsForcedOff(false); |
| } |
| |
| } // namespace ash |