0

capture-game: Implement shortcut to stop screen recording

This CL implements the keyboard shortcut 'Search + Shift + X' to
stop the screen recording. This shortcut will also show in the
new shortcut app.

Demo: http://b/283812684#comment3
Fixed: b/283812684
Test: Added unit test + manually
Change-Id: Ied4c86b63744a3bf71ab328c16eb60e0a0ef7fdb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4554298
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Commit-Queue: Michele Fan <michelefan@chromium.org>
Reviewed-by: Jimmy Gong <jimmyxgong@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1148604}
This commit is contained in:
Michele Fan
2023-05-24 17:13:36 +00:00
committed by Chromium LUCI CQ
parent d1371d5ef4
commit 7fa736cbb2
13 changed files with 70 additions and 3 deletions

@ -586,6 +586,10 @@ bool CanShowStylusTools() {
return GetPaletteTray()->ShouldShowPalette();
}
bool CanStopScreenRecording() {
return CaptureModeController::Get()->is_recording_in_progress();
}
bool CanSwapPrimaryDisplay() {
return display::Screen::GetScreen()->GetNumDisplays() > 1;
}
@ -1141,6 +1145,12 @@ void ShowTaskManager() {
NewWindowDelegate::GetInstance()->ShowTaskManager();
}
void StopScreenRecording() {
CaptureModeController* controller = CaptureModeController::Get();
CHECK(controller->is_recording_in_progress());
controller->EndVideoRecording(EndRecordingReason::kKeyboardShortcut);
}
void Suspend() {
chromeos::PowerManagerClient::Get()->RequestSuspend();
}

@ -85,6 +85,8 @@ ASH_EXPORT bool CanScreenshot(bool take_screenshot);
ASH_EXPORT bool CanShowStylusTools();
ASH_EXPORT bool CanStopScreenRecording();
ASH_EXPORT bool CanSwapPrimaryDisplay();
ASH_EXPORT bool CanToggleCalendar();
@ -284,6 +286,9 @@ ASH_EXPORT void ShowStylusTools();
// Brings up task manager.
ASH_EXPORT void ShowTaskManager();
// Stops the capture mode recording.
ASH_EXPORT void StopScreenRecording();
// Puts device in sleep mode(suspend).
ASH_EXPORT void Suspend();

@ -736,6 +736,8 @@ bool AcceleratorControllerImpl::CanPerformAction(
return accelerators::CanShowStylusTools();
case AcceleratorAction::kStartAssistant:
return true;
case AcceleratorAction::kStopScreenRecording:
return accelerators::CanStopScreenRecording();
case AcceleratorAction::kSwapPrimaryDisplay:
return accelerators::CanSwapPrimaryDisplay();
case AcceleratorAction::kSwitchIme:
@ -1255,6 +1257,9 @@ void AcceleratorControllerImpl::PerformAction(
base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
accelerators::ShiftPrimaryDisplay();
break;
case AcceleratorAction::kStopScreenRecording:
accelerators::StopScreenRecording();
break;
case AcceleratorAction::kSwitchIme:
HandleSwitchIme(accelerator);
break;

@ -3655,6 +3655,9 @@ Connect your device to power.
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_SHOW_EMOJI_PICKER" desc="Label for accelerator action - Open Emoji Picker.">
Open Emoji Picker
</message>
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING" desc="Label for accelerator action - Stop screen recording.">
Stop screen recording
</message>
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_TOGGLE_IME_MENU_BUBBLE" desc="Label for accelerator action - Show list of available input methods.">
Show list of available input methods
</message>

@ -0,0 +1 @@
7e18d091617f1f5f080d966f8054b8913d273f42

@ -39,7 +39,8 @@ enum class EndRecordingReason {
kProjectorTranscriptionError,
kLowDriveFsQuota,
kVideoEncoderReconfigurationFailure,
kMaxValue = kVideoEncoderReconfigurationFailure,
kKeyboardShortcut,
kMaxValue = kKeyboardShortcut,
};
// Enumeration of capture bar buttons that can be pressed while in capture mode.

@ -4660,6 +4660,37 @@ TEST_F(CaptureModeTest, CaptureModeDefaultBehavior) {
expected_behavior();
}
// Tests that the capture mode session can be started with the keyboard shortcut
// 'Ctrl + Shift + Overview' with `kImage` as the default type and `kRegion` as
// the default source. And the screen recording can be ended with the keyboard
// shortcut 'Search + Shift + X'.
TEST_F(CaptureModeTest, KeyboardShortcutTest) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectBucketCount(
kEndRecordingReasonInClamshellHistogramName,
EndRecordingReason::kKeyboardShortcut, 0);
auto* event_generator = GetEventGenerator();
event_generator->PressAndReleaseKey(ui::VKEY_MEDIA_LAUNCH_APP1,
ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
auto* controller = CaptureModeController::Get();
EXPECT_TRUE(controller->IsActive());
EXPECT_EQ(controller->type(), CaptureModeType::kImage);
EXPECT_EQ(controller->source(), CaptureModeSource::kRegion);
controller->SetType(CaptureModeType::kVideo);
controller->SetSource(CaptureModeSource::kFullscreen);
StartVideoRecordingImmediately();
EXPECT_TRUE(controller->is_recording_in_progress());
event_generator->PressAndReleaseKey(ui::VKEY_X,
ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
EXPECT_FALSE(controller->is_recording_in_progress());
histogram_tester.ExpectBucketCount(
kEndRecordingReasonInClamshellHistogramName,
EndRecordingReason::kKeyboardShortcut, 1);
}
namespace {
// -----------------------------------------------------------------------------

@ -107,6 +107,7 @@ namespace ash {
ACCELERATOR_ACTION_ENTRY(ShowStylusTools) \
ACCELERATOR_ACTION_ENTRY(ShowTaskManager) \
ACCELERATOR_ACTION_ENTRY(StartAssistant) \
ACCELERATOR_ACTION_ENTRY(StopScreenRecording) \
ACCELERATOR_ACTION_ENTRY(Suspend) \
ACCELERATOR_ACTION_ENTRY(SwapPrimaryDisplay) \
/* Switch to another IME depending on the accelerator. */ \

@ -197,6 +197,8 @@ const AcceleratorData kAcceleratorData[] = {
AcceleratorAction::kToggleMessageCenterBubble},
{true, ui::VKEY_P, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kShowStylusTools},
{true, ui::VKEY_X, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN,
AcceleratorAction::kStopScreenRecording},
{true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kToggleSystemTrayBubble},
// Until we have unified settings and notifications the "hamburger"

@ -284,6 +284,12 @@ constexpr AcceleratorLayoutDetails kAcceleratorLayouts[] = {
mojom::AcceleratorSubcategory::kGeneralControls,
/*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
mojom::AcceleratorSource::kAsh},
{AcceleratorAction::kStopScreenRecording,
IDS_ASH_ACCELERATOR_DESCRIPTION_STOP_SCREEN_RECORDING,
mojom::AcceleratorCategory::kGeneral,
mojom::AcceleratorSubcategory::kGeneralControls,
/*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
mojom::AcceleratorSource::kAsh},
{AcceleratorAction::kLockScreen,
IDS_ASH_ACCELERATOR_DESCRIPTION_LOCK_SCREEN,
mojom::AcceleratorCategory::kGeneral,

@ -24,9 +24,9 @@
namespace {
// The total number of Ash accelerators.
constexpr int kAshAcceleratorsTotalNum = 147;
constexpr int kAshAcceleratorsTotalNum = 148;
// The hash of Ash accelerators.
constexpr char kAshAcceleratorsHash[] = "f8f6508d9e52f67719d38748be42b5bf";
constexpr char kAshAcceleratorsHash[] = "f7a44d1ca086c9feb1910632c2691b1a";
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Internal builds add an extra accelerator for the Feedback app.
// The total number of Chrome accelerators (available on Chrome OS).

@ -31206,6 +31206,7 @@ Called by update_document_policy_enum.py.-->
<int value="17" label="Projector transcription error"/>
<int value="18" label="Low DriveFS free space quota"/>
<int value="19" label="Video encoder does not support reconfiguration"/>
<int value="20" label="Stop screen recording keyboard shortcut"/>
</enum>
<enum name="EnhancedBookmarkViewMode">

@ -214,6 +214,7 @@ chromium-metrics-reviews@google.com.
<variant name="ShowStylusTools"/>
<variant name="ShowTaskManager"/>
<variant name="StartAssistant"/>
<variant name="StopScreenRecording"/>
<variant name="Suspend"/>
<variant name="SwapPrimaryDisplay"/>
<variant name="SwitchIme"/>