Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1209)

Unified Diff: ash/wm/power_button_controller.cc

Issue 2474913004: Tablet-like power button behavior on Convertible/Tablet ChromeOS devices (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/wm/power_button_controller.cc
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index 92ca9c12aabcd64eeb6996e10f6ab273b57e803c..ebdd5fa5255153c32e842b0b4d1885d093c19f9d 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -22,12 +22,25 @@
#include "ui/wm/core/compound_event_filter.h"
#if defined(OS_CHROMEOS)
+#include "ash/wm/tablet_power_state_delegate_chromeos.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#endif
namespace ash {
+namespace {
+// 1s timer before starting shutdown animation. If power button released event
+// is not received before timeout, |controller_| will take the duty to start
+// shutdown animation.
+const int kTabletPreStartShutdownAnimationTimeoutMs = 1000;
+} // namespace
+
+PowerButtonController::TestApi::TestApi(PowerButtonController* controller)
+ : controller_(controller) {}
+
+PowerButtonController::TestApi::~TestApi() {}
+
PowerButtonController::PowerButtonController(LockStateController* controller)
: power_button_down_(false),
lock_button_down_(false),
@@ -46,16 +59,30 @@ PowerButtonController::PowerButtonController(LockStateController* controller)
#else
enable_quick_lock_(false),
#endif
- controller_(controller) {
+ controller_(controller),
+ pressed_on_screen_off_(false),
+ backlights_forced_off_(false) {
#if defined(OS_CHROMEOS)
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
this);
Shell::GetInstance()->display_configurator()->AddObserver(this);
#endif
Shell::GetInstance()->PrependPreTargetHandler(this);
+#if defined(OS_CHROMEOS)
+ tablet_power_state_delegate_ =
+ base::MakeUnique<TabletPowerStateDelegateChromeos>();
Daniel Erat 2016/11/03 21:28:08 i don't understand the reason for this delegate.
Qiang(Joe) Xu 2016/11/04 01:14:03 done, thanks. I was thinking using |delegate_| ini
+#endif
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
Daniel Erat 2016/11/03 21:28:08 what's the reason for posting this instead of just
Qiang(Joe) Xu 2016/11/04 01:14:04 I think just GetInitialBacklightsForcedOff should
+ FROM_HERE,
+ base::Bind(&PowerButtonController::GetInitialBacklightsForcedOff,
+ base::Unretained(this)));
}
PowerButtonController::~PowerButtonController() {
+#if defined(OS_CHROMEOS)
+ tablet_power_state_delegate_.reset();
+#endif
Shell::GetInstance()->RemovePreTargetHandler(this);
#if defined(OS_CHROMEOS)
Shell::GetInstance()->display_configurator()->RemoveObserver(this);
@@ -76,16 +103,19 @@ void PowerButtonController::OnPowerButtonEvent(
if (controller_->ShutdownRequested())
return;
+ if (!has_legacy_power_button_ && !MaybeTakeScreenshot(down) &&
Daniel Erat 2016/11/03 21:28:07 instead of calling this helper method twice, why n
Qiang(Joe) Xu 2016/11/04 01:14:04 Done.
+ WmShell::Get()->maximize_mode_controller()->CanEnterMaximizeMode()) {
+ OnTabletPowerButtonEvent(down, timestamp);
+ return;
+ }
+
// Avoid starting the lock/shutdown sequence if the power button is pressed
// while the screen is off (http://crbug.com/128451), unless an external
// display is still on (http://crosbug.com/p/24912).
if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
return;
- if (volume_down_pressed_ && down &&
- WmShell::Get()
- ->maximize_mode_controller()
- ->IsMaximizeModeWindowManagerEnabled()) {
+ if (MaybeTakeScreenshot(down)) {
SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray();
if (system_tray && system_tray->GetTrayAudio())
system_tray->GetTrayAudio()->HideDetailedView(false);
@@ -170,6 +200,7 @@ void PowerButtonController::OnLockButtonEvent(
}
void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
+ WakeOnLaptopMode();
if (event->key_code() == ui::VKEY_VOLUME_DOWN) {
volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED;
#if defined(OS_CHROMEOS)
@@ -183,6 +214,10 @@ void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
}
}
+void PowerButtonController::OnMouseEvent(ui::MouseEvent* event) {
+ WakeOnLaptopMode();
+}
+
#if defined(OS_CHROMEOS)
void PowerButtonController::OnDisplayModeChanged(
const ui::DisplayConfigurator::DisplayStateList& display_states) {
@@ -207,4 +242,105 @@ void PowerButtonController::PowerButtonEventReceived(
}
#endif // defined(OS_CHROMEOS)
+void PowerButtonController::OnTabletPowerButtonEvent(
+ bool down,
+ const base::TimeTicks& timestamp) {
+ if (!tablet_power_state_delegate_)
+ return;
+
+ // When screen is off, SetBacklightsForcedOff(false) takes action on power
+ // button pressed.
+ // When screen is on, SetBacklightsForcedOff(true) takes action when power
+ // button is released before the |tablet_pre_start_shutdown_animation_timer_|
+ // is timeout.
+ if (down) {
+ if (backlights_forced_off_ || brightness_is_zero_) {
+ pressed_on_screen_off_ = true;
Daniel Erat 2016/11/03 21:28:07 it seems a bit safer to set this unconditionally h
Qiang(Joe) Xu 2016/11/04 01:14:03 done. If backlights_forced_off_is true, brightness
Daniel Erat 2016/11/04 16:12:51 i think that 2 is much better, since it ensures th
Qiang(Joe) Xu 2016/11/04 19:29:51 Done.
+ SetBacklightsForcedOff(false);
+ }
+ StartTabletPreStartShutdownAnimationTimer();
+ } else {
+ if (pressed_on_screen_off_) {
+ if (tablet_pre_start_shutdown_animation_timer_.IsRunning())
+ tablet_pre_start_shutdown_animation_timer_.Stop();
+ pressed_on_screen_off_ = false;
+ } else {
+ if (tablet_pre_start_shutdown_animation_timer_.IsRunning()) {
+ tablet_pre_start_shutdown_animation_timer_.Stop();
+ SetBacklightsForcedOff(true);
+ LockScreenIfRequired();
+ }
+ }
+ // When power button is released, Cancel Shutdown animation whenever it is
+ // still cancellable.
+ if (controller_->CanCancelShutdownAnimation())
+ controller_->CancelShutdownAnimation();
+ }
+}
+
+void PowerButtonController::SetBacklightsForcedOff(bool forced_off) {
+ if (!tablet_power_state_delegate_ || backlights_forced_off_ == forced_off)
+ return;
+
+ tablet_power_state_delegate_->SetBacklightsForcedOff(forced_off);
+ backlights_forced_off_ = forced_off;
+}
+
+void PowerButtonController::GetInitialBacklightsForcedOff() {
+ if (!tablet_power_state_delegate_)
+ return;
+
+ tablet_power_state_delegate_->GetBacklightsForcedOff(
+ base::Bind(&PowerButtonController::HandleInitialBacklightsForcedOff,
+ base::Unretained(this)));
+}
+
+void PowerButtonController::HandleInitialBacklightsForcedOff(
+ bool is_forced_off) {
+ backlights_forced_off_ = is_forced_off;
+ if (is_forced_off)
+ SetBacklightsForcedOff(false);
Daniel Erat 2016/11/03 21:28:07 i don't understand why this call is needed. the ba
Qiang(Joe) Xu 2016/11/04 01:14:03 I thought when constructed, user should face non-f
+}
+
+void PowerButtonController::StartTabletPreStartShutdownAnimationTimer() {
+ tablet_pre_start_shutdown_animation_timer_.Stop();
Daniel Erat 2016/11/03 21:28:08 you don't need this call to Stop(); Start() alread
Qiang(Joe) Xu 2016/11/04 01:14:03 Done.
+ tablet_pre_start_shutdown_animation_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromMilliseconds(
+ kTabletPreStartShutdownAnimationTimeoutMs),
+ this, &PowerButtonController::OnTabletPreStartShutdownAnimationTimeout);
+}
+
+void PowerButtonController::OnTabletPreStartShutdownAnimationTimeout() {
+ controller_->StartShutdownAnimation();
+}
+
+void PowerButtonController::LockScreenIfRequired() {
+ SessionStateDelegate* session_state_delegate =
+ WmShell::Get()->GetSessionStateDelegate();
+ if (session_state_delegate->ShouldLockScreenAutomatically() &&
+ session_state_delegate->CanLockScreen() &&
+ !session_state_delegate->IsUserSessionBlocked() &&
+ !controller_->LockRequested()) {
+ session_state_delegate->LockScreen();
+ }
+}
+
+void PowerButtonController::WakeOnLaptopMode() {
Daniel Erat 2016/11/03 21:28:07 using the word "wake" here seems a bit inaccurate;
Qiang(Joe) Xu 2016/11/04 01:14:03 Done.
+ MaximizeModeController* maximize_mode_controller =
+ WmShell::Get()->maximize_mode_controller();
+ if (maximize_mode_controller &&
+ maximize_mode_controller->CanEnterMaximizeMode() &&
+ !maximize_mode_controller->IsMaximizeModeWindowManagerEnabled() &&
Daniel Erat 2016/11/03 21:28:07 i find all of these references to MaximizeModeCont
Qiang(Joe) Xu 2016/11/04 01:14:03 Done.
+ (backlights_forced_off_ || brightness_is_zero_)) {
Daniel Erat 2016/11/03 21:28:07 i don't understand the brightness_is_zero_ check h
Qiang(Joe) Xu 2016/11/04 01:14:03 Yes, brightness_is_zero_ is not needed. Thanks!
+ SetBacklightsForcedOff(false);
+ }
+}
+
+bool PowerButtonController::MaybeTakeScreenshot(bool power_button_pressed) {
+ return volume_down_pressed_ && power_button_pressed &&
+ WmShell::Get()
+ ->maximize_mode_controller()
+ ->IsMaximizeModeWindowManagerEnabled();
+}
+
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698