Commit 8d2cfc84 authored by Min Chen's avatar Min Chen Committed by Commit Bot

Make PowerButton+VolumeUp can also take screenshot.

Bug: 937907
Change-Id: I2cd5baccd1f5acef58b051937447794eb49b7338
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1607183
Commit-Queue: Min Chen <minch@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#659326}
parent b24394e4
...@@ -50,6 +50,7 @@ bool PowerButtonScreenshotController::OnPowerButtonEvent( ...@@ -50,6 +50,7 @@ bool PowerButtonScreenshotController::OnPowerButtonEvent(
power_button_pressed_ = down; power_button_pressed_ = down;
if (power_button_pressed_) { if (power_button_pressed_) {
volume_down_timer_.Stop(); volume_down_timer_.Stop();
volume_up_timer_.Stop();
power_button_pressed_time_ = tick_clock_->NowTicks(); power_button_pressed_time_ = tick_clock_->NowTicks();
if (InterceptScreenshotChord()) if (InterceptScreenshotChord())
return true; return true;
...@@ -71,81 +72,104 @@ void PowerButtonScreenshotController::OnKeyEvent(ui::KeyEvent* event) { ...@@ -71,81 +72,104 @@ void PowerButtonScreenshotController::OnKeyEvent(ui::KeyEvent* event) {
if (key_code != ui::VKEY_VOLUME_DOWN && key_code != ui::VKEY_VOLUME_UP) if (key_code != ui::VKEY_VOLUME_DOWN && key_code != ui::VKEY_VOLUME_UP)
return; return;
if (key_code == ui::VKEY_VOLUME_DOWN) { const bool is_volume_down = key_code == ui::VKEY_VOLUME_DOWN;
if (event->type() == ui::ET_KEY_PRESSED) { if (event->type() == ui::ET_KEY_PRESSED) {
if (!volume_down_key_pressed_) { if (!volume_down_key_pressed_ && !volume_up_key_pressed_) {
if (is_volume_down) {
volume_down_key_pressed_ = true; volume_down_key_pressed_ = true;
volume_down_key_pressed_time_ = tick_clock_->NowTicks(); volume_down_key_pressed_time_ = tick_clock_->NowTicks();
consume_volume_down_ = false; consume_volume_down_ = false;
InterceptScreenshotChord();
} else {
volume_up_key_pressed_ = true;
volume_up_key_pressed_time_ = tick_clock_->NowTicks();
consume_volume_up_ = false;
InterceptScreenshotChord(); InterceptScreenshotChord();
} }
// Do not propagate volume down key pressed event if the first
// one is consumed by screenshot.
if (consume_volume_down_)
event->StopPropagation();
} else {
volume_down_key_pressed_ = false;
} }
}
if (key_code == ui::VKEY_VOLUME_UP) if (consume_volume_down_ || consume_volume_up_)
volume_up_key_pressed_ = event->type() == ui::ET_KEY_PRESSED; event->StopPropagation();
} else {
is_volume_down ? volume_down_key_pressed_ = false
: volume_up_key_pressed_ = false;
}
// When volume key is pressed, cancel the ongoing power button behavior. // When volume key is pressed, cancel the ongoing power button behavior.
if (volume_down_key_pressed_ || volume_up_key_pressed_) if (volume_down_key_pressed_ || volume_up_key_pressed_)
Shell::Get()->power_button_controller()->CancelPowerButtonEvent(); Shell::Get()->power_button_controller()->CancelPowerButtonEvent();
// On volume down key pressed while power button not pressed yet state, do not // On volume down/up key pressed while power button not pressed yet state, do
// propagate volume down key pressed event for chord delay time. Start the // not propagate volume down/up key pressed event for chord delay time. Start
// timer to wait power button pressed for screenshot operation, and on timeout // the timer to wait power button pressed for screenshot operation, and on
// perform the delayed volume down operation. // timeout perform the delayed volume down/up operation.
if (volume_down_key_pressed_ && !power_button_pressed_) { if (power_button_pressed_)
base::TimeTicks now = tick_clock_->NowTicks(); return;
if (now <= volume_down_key_pressed_time_ + kScreenshotChordDelay) {
event->StopPropagation();
if (!volume_down_timer_.IsRunning()) { base::TimeTicks now = tick_clock_->NowTicks();
volume_down_timer_.Start( if (volume_down_key_pressed_ && is_volume_down &&
FROM_HERE, kScreenshotChordDelay, now <= volume_down_key_pressed_time_ + kScreenshotChordDelay) {
base::BindOnce( event->StopPropagation();
&PowerButtonScreenshotController::OnVolumeDownTimeout, if (!volume_down_timer_.IsRunning()) {
base::Unretained(this), ui::Accelerator(*event))); volume_down_timer_.Start(
} FROM_HERE, kScreenshotChordDelay,
base::BindOnce(
&PowerButtonScreenshotController::OnVolumeControlTimeout,
base::Unretained(this), ui::Accelerator(*event), /*down=*/true));
}
} else if (volume_up_key_pressed_ && !is_volume_down &&
now <= volume_up_key_pressed_time_ + kScreenshotChordDelay) {
event->StopPropagation();
if (!volume_up_timer_.IsRunning()) {
volume_up_timer_.Start(
FROM_HERE, kScreenshotChordDelay,
base::BindOnce(
&PowerButtonScreenshotController::OnVolumeControlTimeout,
base::Unretained(this), ui::Accelerator(*event), /*down=*/false));
} }
} }
} }
bool PowerButtonScreenshotController::InterceptScreenshotChord() { bool PowerButtonScreenshotController::InterceptScreenshotChord() {
if (volume_down_key_pressed_ && power_button_pressed_) { if (!power_button_pressed_ ||
// Record the delay when power button and volume down key are both pressed, (!volume_down_key_pressed_ && !volume_up_key_pressed_)) {
// which indicates user might want to use accelerator to take screenshot. return false;
// This will help us determine the best chord delay among metrics. }
const base::TimeDelta key_pressed_delay =
power_button_pressed_time_ - volume_down_key_pressed_time_; // Record the delay when power button and volume down/up key are both pressed,
UMA_HISTOGRAM_TIMES("Ash.PowerButtonScreenshot.DelayBetweenAccelKeyPressed", // which indicates user might want to use accelerator to take screenshot.
key_pressed_delay.magnitude()); // This will help us determine the best chord delay among metrics.
const base::TimeDelta key_pressed_delay =
base::TimeTicks now = tick_clock_->NowTicks(); volume_down_key_pressed_
if (now <= volume_down_key_pressed_time_ + kScreenshotChordDelay && ? power_button_pressed_time_ - volume_down_key_pressed_time_
now <= power_button_pressed_time_ + kScreenshotChordDelay) { : power_button_pressed_time_ - volume_up_key_pressed_time_;
Shell::Get()->accelerator_controller()->PerformActionIfEnabled( UMA_HISTOGRAM_TIMES("Ash.PowerButtonScreenshot.DelayBetweenAccelKeyPressed",
TAKE_SCREENSHOT, {}); key_pressed_delay.magnitude());
consume_volume_down_ = true;
base::TimeTicks now = tick_clock_->NowTicks();
base::RecordAction( if (now > power_button_pressed_time_ + kScreenshotChordDelay)
base::UserMetricsAction("Accel_PowerButton_Screenshot")); return false;
return true;
} consume_volume_down_ =
volume_down_key_pressed_ &&
now <= volume_down_key_pressed_time_ + kScreenshotChordDelay;
consume_volume_up_ =
volume_up_key_pressed_ &&
now <= volume_up_key_pressed_time_ + kScreenshotChordDelay;
if (consume_volume_down_ || consume_volume_up_) {
Shell::Get()->accelerator_controller()->PerformActionIfEnabled(
TAKE_SCREENSHOT, {});
base::RecordAction(base::UserMetricsAction("Accel_PowerButton_Screenshot"));
} }
return false; return consume_volume_down_ || consume_volume_up_;
} }
void PowerButtonScreenshotController::OnVolumeDownTimeout( void PowerButtonScreenshotController::OnVolumeControlTimeout(
const ui::Accelerator& accelerator) { const ui::Accelerator& accelerator,
Shell::Get()->accelerator_controller()->PerformActionIfEnabled(VOLUME_DOWN, bool down) {
accelerator); Shell::Get()->accelerator_controller()->PerformActionIfEnabled(
down ? VOLUME_DOWN : VOLUME_UP, accelerator);
} }
} // namespace ash } // namespace ash
...@@ -47,31 +47,33 @@ class ASH_EXPORT PowerButtonScreenshotController : public ui::EventHandler { ...@@ -47,31 +47,33 @@ class ASH_EXPORT PowerButtonScreenshotController : public ui::EventHandler {
// indicate that power button and volume down key is consumed by screenshot. // indicate that power button and volume down key is consumed by screenshot.
bool InterceptScreenshotChord(); bool InterceptScreenshotChord();
// Called by |volume_down_timer_| to perform volume down accelerator. // Called by |volume_down_timer_| or |volume_up_timer_| to perform volume down
void OnVolumeDownTimeout(const ui::Accelerator& accelerator); // or up accelerator.
void OnVolumeControlTimeout(const ui::Accelerator& accelerator, bool down);
// True if volume down key is pressed. // True if volume down/up key is pressed.
bool volume_down_key_pressed_ = false; bool volume_down_key_pressed_ = false;
// True if volume up key is pressed.
bool volume_up_key_pressed_ = false; bool volume_up_key_pressed_ = false;
// True if volume down key is consumed by screenshot accelerator. // True if volume down/up key is consumed by screenshot accelerator.
bool consume_volume_down_ = false; bool consume_volume_down_ = false;
bool consume_volume_up_ = false;
// True if power button is pressed. // True if power button is pressed.
bool power_button_pressed_ = false; bool power_button_pressed_ = false;
// Saves the most recent volume down key pressed time. // Saves the most recent volume down/up key pressed time.
base::TimeTicks volume_down_key_pressed_time_; base::TimeTicks volume_down_key_pressed_time_;
base::TimeTicks volume_up_key_pressed_time_;
// Saves the most recent power button pressed time. // Saves the most recent power button pressed time.
base::TimeTicks power_button_pressed_time_; base::TimeTicks power_button_pressed_time_;
// Started when volume down key is pressed and power button is not pressed. // Started when volume down/up key is pressed and power button is not pressed.
// Stopped when power button is pressed. Runs OnVolumeDownTimeout to perform a // Stopped when power button is pressed. Runs OnVolumeControlTimeout to
// volume down accelerator. // perform a volume down/up accelerator.
base::OneShotTimer volume_down_timer_; base::OneShotTimer volume_down_timer_;
base::OneShotTimer volume_up_timer_;
// Time source for performed action times. // Time source for performed action times.
const base::TickClock* tick_clock_; // Not owned. const base::TickClock* tick_clock_; // Not owned.
......
...@@ -25,4 +25,12 @@ bool PowerButtonScreenshotControllerTestApi::TriggerVolumeDownTimer() { ...@@ -25,4 +25,12 @@ bool PowerButtonScreenshotControllerTestApi::TriggerVolumeDownTimer() {
return true; return true;
} }
bool PowerButtonScreenshotControllerTestApi::TriggerVolumeUpTimer() {
if (!controller_->volume_up_timer_.IsRunning())
return false;
controller_->volume_up_timer_.FireNow();
return true;
}
} // namespace ash } // namespace ash
...@@ -24,6 +24,10 @@ class PowerButtonScreenshotControllerTestApi { ...@@ -24,6 +24,10 @@ class PowerButtonScreenshotControllerTestApi {
// and returns true. Otherwise returns false. // and returns true. Otherwise returns false.
bool TriggerVolumeDownTimer() WARN_UNUSED_RESULT; bool TriggerVolumeDownTimer() WARN_UNUSED_RESULT;
// If |controller_->volume_up_timer_| is running, stops it, runs its task,
// and returns true. Otherwise returns false.
bool TriggerVolumeUpTimer() WARN_UNUSED_RESULT;
private: private:
PowerButtonScreenshotController* controller_; PowerButtonScreenshotController* controller_;
......
...@@ -85,149 +85,256 @@ class PowerButtonScreenshotControllerTest : public PowerButtonTestBase { ...@@ -85,149 +85,256 @@ class PowerButtonScreenshotControllerTest : public PowerButtonTestBase {
DISALLOW_COPY_AND_ASSIGN(PowerButtonScreenshotControllerTest); DISALLOW_COPY_AND_ASSIGN(PowerButtonScreenshotControllerTest);
}; };
// Tests power button screenshot accelerator works on tablet mode only. // Tests the functionalities that press the power button first and then press
TEST_F(PowerButtonScreenshotControllerTest, TabletMode) { // volume down and volume up key alternative.
// Tests on tablet mode pressing power button and volume down simultaneously TEST_F(PowerButtonScreenshotControllerTest,
// takes a screenshot. PowerButtonPressedFirst_Screenshot) {
PressPowerButton();
tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay -
base::TimeDelta::FromMilliseconds(5));
PressKey(ui::VKEY_VOLUME_DOWN);
// Verifies screenshot is taken, volume down is consumed.
EXPECT_EQ(1, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Presses volume up key under screenshot chord condition will not take
// screenshot again, volume up is also consumed.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
ResetScreenshotCount();
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Presses volume down key again under screenshot chord condition will not
// take screenshot and still consume volume down event.
ResetScreenshotCount();
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Keeps pressing volume down key outside of screenshot chord condition will
// not take screenshot and still consume volume down event.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Pressing volume up key outside of screenshot chord condition will not take
// screenshot and still consume volume up event.
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Releases power button now should not set display off.
ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed());
// Releases volume down key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed());
}
// Tests the functionalities that press the volume key first and then press
// volume down and volume up key alternative.
TEST_F(PowerButtonScreenshotControllerTest, VolumeKeyPressedFirst_Screenshot) {
// Tests when volume up pressed first, it waits for power button pressed
// screenshot chord.
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_TRUE(LastKeyConsumed());
// Presses power button under screenshot chord condition, and verifies that
// screenshot is taken.
tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay -
base::TimeDelta::FromMilliseconds(5));
PressPowerButton(); PressPowerButton();
EXPECT_EQ(1, GetScreenshotCount());
// Presses volume down key under screenshot chord condition will not take
// screenshot, volume down is also consumed.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
ResetScreenshotCount();
PressKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Presses volume up key under screenshot chord condition again will not take
// screenshot and still consume volume up event.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Keeps pressing volume up key outside of screenshot chord condition will not
// take screenshot and still consume volume up event.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Presses volume down key outside of screenshot chord condition will not take
// screenshot and still consume volume down event.
PressKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed());
// Releases power button now should not set display off.
ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume down key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(ui::VKEY_VOLUME_DOWN);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed());
// Releases volume up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_UP);
EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed());
}
class PowerButtonScreenshotControllerWithKeyCodeTest
: public PowerButtonScreenshotControllerTest,
public testing::WithParamInterface<ui::KeyboardCode> {
public:
PowerButtonScreenshotControllerWithKeyCodeTest() : key_code_(GetParam()) {}
ui::KeyboardCode key_code() const { return key_code_; }
private:
// Value of the |key_code_| will only be ui::VKEY_VOLUME_DOWN or
// ui::VKEY_VOLUME_UP.
ui::KeyboardCode key_code_ = ui::VKEY_UNKNOWN;
DISALLOW_COPY_AND_ASSIGN(PowerButtonScreenshotControllerWithKeyCodeTest);
};
// Tests power button screenshot accelerator works in tablet mode only.
TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest, TabletMode) {
// Tests in tablet mode pressing power button and volume down/up
// simultaneously takes a screenshot.
PressKey(key_code());
PressPowerButton();
ReleaseKey(key_code());
ReleasePowerButton(); ReleasePowerButton();
EXPECT_EQ(1, GetScreenshotCount()); EXPECT_EQ(1, GetScreenshotCount());
// Tests screenshot handling is not active when not on tablet mode. // Tests screenshot handling is not active when not in tablet mode.
ResetScreenshotCount(); ResetScreenshotCount();
EnableTabletMode(false); EnableTabletMode(false);
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
PressPowerButton(); PressPowerButton();
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
ReleasePowerButton(); ReleasePowerButton();
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
} }
// Tests if power-button/volume-down is released before volume-down/power-button // Tests if power-button/volume-down(volume-up) is released before
// is pressed, it does not take screenshot. // volume-down(volume-up)/power-button is pressed, it does not take screenshot.
TEST_F(PowerButtonScreenshotControllerTest, ReleaseBeforeAnotherPressed) { TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
// Releases volume down before power button is pressed. ReleaseBeforeAnotherPressed) {
PressKey(ui::VKEY_VOLUME_DOWN); // Releases volume down/up before power button is pressed.
ReleaseKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
ReleaseKey(key_code());
PressPowerButton(); PressPowerButton();
ReleasePowerButton(); ReleasePowerButton();
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
// Releases power button before volume down is pressed. // Releases power button before volume down/up is pressed.
PressPowerButton(); PressPowerButton();
ReleasePowerButton(); ReleasePowerButton();
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
} }
// Tests power button is pressed first and meets screenshot chord condition. // Tests power button is pressed first and meets screenshot chord condition.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
PowerButtonPressedFirst_ScreenshotChord) { PowerButtonPressedFirst_ScreenshotChord) {
PressPowerButton(); PressPowerButton();
tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay - tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay -
base::TimeDelta::FromMilliseconds(2)); base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
// Verifies screenshot is taken, volume down is consumed. // Verifies screenshot is taken, volume down/up is consumed.
EXPECT_EQ(1, GetScreenshotCount()); EXPECT_EQ(1, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Keeps pressing volume down key under screenshot chord condition will not // Keeps pressing volume down/up key under screenshot chord condition will not
// take screenshot again, volume down is also consumed. // take screenshot again, volume down/up is also consumed.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
ResetScreenshotCount(); ResetScreenshotCount();
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Keeps pressing volume down key off screenshot chord condition will not // Keeps pressing volume down/up key off screenshot chord condition will not
// take screenshot and still consume volume down event. // take screenshot and still consume volume down/up event.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Releases power button now should not set display off. // Releases power button now should not set display off.
ReleasePowerButton(); ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume down key, and verifies nothing happens. // Releases volume down/up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
} }
// Tests power button is pressed first, and then volume down pressed but doesn't // Tests power button is pressed first, and then volume down/up pressed but
// meet screenshot chord condition. // doesn't meet screenshot chord condition.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
PowerButtonPressedFirst_NoScreenshotChord) { PowerButtonPressedFirst_NoScreenshotChord) {
PressPowerButton(); PressPowerButton();
tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay + tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay +
base::TimeDelta::FromMilliseconds(1)); base::TimeDelta::FromMilliseconds(1));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
// Verifies screenshot is not taken, volume down is not consumed. // Verifies screenshot is not taken, volume down/up is not consumed.
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
// Keeps pressing volume down key should continue triggerring volume down. // Keeps pressing volume down/up key should continue triggerring volume
// down/up.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
// Releases power button now should not set display off. // Releases power button now should not set display off.
ReleasePowerButton(); ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume down key, and verifies nothing happens. // Releases volume down/up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
} }
// Tests volume key pressed cancels the ongoing power button behavior. // Tests volume key pressed cancels the ongoing power button behavior.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
PowerButtonPressedFirst_VolumeKeyCancelPowerButton) { PowerButtonPressedFirst_VolumeKeyCancelPowerButton) {
// Tests volume down key can stop power button's shutdown timer and power // Tests volume down/up key can stop power button's shutdown timer and power
// button menu timer. // button menu timer.
PressPowerButton(); PressPowerButton();
EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning()); EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
ReleasePowerButton();
ReleaseKey(ui::VKEY_VOLUME_DOWN);
EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Tests volume up key can stop power button's shutdown timer and power button
// menu timer. Also tests that volume up key is not consumed.
PressPowerButton();
EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
PressKey(ui::VKEY_VOLUME_UP);
EXPECT_FALSE(LastKeyConsumed());
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning()); EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
ReleasePowerButton(); ReleasePowerButton();
ReleaseKey(ui::VKEY_VOLUME_UP); ReleaseKey(key_code());
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
EXPECT_FALSE(LastKeyConsumed());
} }
// Tests volume key pressed can not cancel the started pre-shutdown animation. // Tests volume key pressed can not cancel the started pre-shutdown animation.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
PowerButtonPressedFirst_VolumeKeyNotCancelPowerButton) { PowerButtonPressedFirst_VolumeKeyNotCancelPowerButton) {
PressPowerButton(); PressPowerButton();
ASSERT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout()); ASSERT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning()); EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning());
EXPECT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout()); EXPECT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running()); EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running()); EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
ReleasePowerButton(); ReleasePowerButton();
EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running()); EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
} }
// Tests volume down key pressed first and meets screenshot chord condition. // Tests volume down/up key pressed first and meets screenshot chord condition.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
VolumeDownPressedFirst_ScreenshotChord) { VolumeKeyPressedFirst_ScreenshotChord) {
// Tests when volume down pressed first, it waits for power button pressed // Tests when volume down/up pressed first, it waits for power button pressed
// screenshot chord. // screenshot chord.
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Presses power button under screenshot chord condition, and verifies that // Presses power button under screenshot chord condition, and verifies that
// screenshot is taken. // screenshot is taken.
...@@ -235,81 +342,79 @@ TEST_F(PowerButtonScreenshotControllerTest, ...@@ -235,81 +342,79 @@ TEST_F(PowerButtonScreenshotControllerTest,
base::TimeDelta::FromMilliseconds(2)); base::TimeDelta::FromMilliseconds(2));
PressPowerButton(); PressPowerButton();
EXPECT_EQ(1, GetScreenshotCount()); EXPECT_EQ(1, GetScreenshotCount());
// Keeps pressing volume down key under screenshot chord condition will not // Keeps pressing volume down/up key under screenshot chord condition will not
// take screenshot again, volume down is also consumed. // take screenshot again, volume down/up is also consumed.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
ResetScreenshotCount(); ResetScreenshotCount();
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Keeps pressing volume down key off screenshot chord condition will not take // Keeps pressing volume down/up key off screenshot chord condition will not
// screenshot and still consume volume down event. // take screenshot and still consume volume down/up event.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Releases power button now should not set display off. // Releases power button now should not set display off.
ReleasePowerButton(); ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume down key, and verifies nothing happens. // Releases volume down/up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
} }
// Tests volume down key pressed first, and then power button pressed but // Tests volume down/up key pressed first, and then power button pressed but
// doesn't meet screenshot chord condition. // doesn't meet screenshot chord condition.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
VolumeDownPressedFirst_NoScreenshotChord) { VolumeKeyPressedFirst_NoScreenshotChord) {
// Tests when volume down pressed first, it waits for power button pressed // Tests when volume down/up pressed first, it waits for power button pressed
// screenshot chord. // screenshot chord.
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_TRUE(LastKeyConsumed()); EXPECT_TRUE(LastKeyConsumed());
// Advances |tick_clock_| to off screenshot chord point. This will also // Advances |tick_clock_| to off screenshot chord point. This will also
// trigger volume down timer timeout, which will perform a volume down // trigger volume down/up timer timeout, which will perform a volume down/up
// operation. // operation.
tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay + tick_clock_.Advance(PowerButtonScreenshotController::kScreenshotChordDelay +
base::TimeDelta::FromMilliseconds(1)); base::TimeDelta::FromMilliseconds(1));
EXPECT_TRUE(screenshot_test_api_->TriggerVolumeDownTimer()); if (key_code() == ui::VKEY_VOLUME_DOWN)
EXPECT_TRUE(screenshot_test_api_->TriggerVolumeDownTimer());
else
EXPECT_TRUE(screenshot_test_api_->TriggerVolumeUpTimer());
// Presses power button would not take screenshot. // Presses power button would not take screenshot.
PressPowerButton(); PressPowerButton();
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
// Keeps pressing volume down key should continue triggerring volume down. // Keeps pressing volume down/up key should continue triggerring volume
// down/up.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2)); tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2));
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
// Releases power button now should not set display off. // Releases power button now should not set display off.
ReleasePowerButton(); ReleasePowerButton();
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Releases volume down key, and verifies nothing happens. // Releases volume down/up key, and verifies nothing happens.
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_EQ(0, GetScreenshotCount()); EXPECT_EQ(0, GetScreenshotCount());
EXPECT_FALSE(LastKeyConsumed()); EXPECT_FALSE(LastKeyConsumed());
} }
// Tests volume key pressed first invalidates the power button behavior. // Tests volume key pressed first invalidates the power button behavior.
TEST_F(PowerButtonScreenshotControllerTest, TEST_P(PowerButtonScreenshotControllerWithKeyCodeTest,
VolumeKeyPressedFirst_InvalidateConvertiblePowerButton) { VolumeKeyPressedFirst_InvalidateConvertiblePowerButton) {
// Tests volume down key invalidates the power button behavior. // Tests volume down/up key invalidates the power button behavior.
PressKey(ui::VKEY_VOLUME_DOWN); PressKey(key_code());
PressPowerButton(); PressPowerButton();
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning()); EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
ReleasePowerButton(); ReleasePowerButton();
ReleaseKey(ui::VKEY_VOLUME_DOWN); ReleaseKey(key_code());
EXPECT_FALSE(power_manager_client()->backlights_forced_off()); EXPECT_FALSE(power_manager_client()->backlights_forced_off());
// Tests volume up key invalidates the power button behavior. Also
// tests that volume up key is not consumed.
PressKey(ui::VKEY_VOLUME_UP);
PressPowerButton();
EXPECT_FALSE(LastKeyConsumed());
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
ReleasePowerButton();
ReleaseKey(ui::VKEY_VOLUME_UP);
EXPECT_FALSE(power_manager_client()->backlights_forced_off());
EXPECT_FALSE(LastKeyConsumed());
} }
INSTANTIATE_TEST_SUITE_P(AshPowerButtonScreenshot,
PowerButtonScreenshotControllerWithKeyCodeTest,
testing::Values(ui::VKEY_VOLUME_DOWN,
ui::VKEY_VOLUME_UP));
} // namespace ash } // namespace ash
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment