| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/capture_mode/capture_mode_bar_view.h" |
| #include "ash/capture_mode/capture_mode_camera_preview_view.h" |
| #include "ash/capture_mode/capture_mode_constants.h" |
| #include "ash/capture_mode/capture_mode_controller.h" |
| #include "ash/capture_mode/capture_mode_metrics.h" |
| #include "ash/capture_mode/capture_mode_session.h" |
| #include "ash/capture_mode/capture_mode_session_focus_cycler.h" |
| #include "ash/capture_mode/capture_mode_session_test_api.h" |
| #include "ash/capture_mode/capture_mode_settings_test_api.h" |
| #include "ash/capture_mode/capture_mode_settings_view.h" |
| #include "ash/capture_mode/capture_mode_test_util.h" |
| #include "ash/capture_mode/capture_mode_types.h" |
| #include "ash/capture_mode/test_capture_mode_delegate.h" |
| #include "ash/constants/ash_features.h" |
| #include "ash/display/window_tree_host_manager.h" |
| #include "ash/game_dashboard/game_dashboard_context_test_api.h" |
| #include "ash/game_dashboard/game_dashboard_controller.h" |
| #include "ash/game_dashboard/game_dashboard_widget.h" |
| #include "ash/public/cpp/capture_mode/capture_mode_test_api.h" |
| #include "ash/public/cpp/window_properties.h" |
| #include "ash/screen_util.h" |
| #include "ash/shell.h" |
| #include "ash/strings/grit/ash_strings.h" |
| #include "ash/style/pill_button.h" |
| #include "ash/test/ash_test_base.h" |
| #include "ash/test/ash_test_util.h" |
| #include "ash/wm/desks/desks_test_util.h" |
| #include "base/system/sys_info.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "chromeos/ui/base/window_properties.h" |
| #include "extensions/common/constants.h" |
| #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/wm/core/window_util.h" |
| |
| namespace message_center { |
| |
| bool operator==(const ButtonInfo& lhs, const ButtonInfo& rhs) { |
| return std::tie(lhs.title, lhs.icon, lhs.placeholder, lhs.type) == |
| std::tie(rhs.title, rhs.icon, rhs.placeholder, rhs.type); |
| } |
| |
| } // namespace message_center |
| |
| namespace ash { |
| |
| namespace { |
| |
| using ::ui::mojom::CursorType; |
| |
| } // namespace |
| |
| using ButtonInfo = message_center::ButtonInfo; |
| |
| class GameDashboardCaptureModeTest : public AshTestBase { |
| public: |
| GameDashboardCaptureModeTest() { |
| scoped_feature_list_.InitWithFeatures( |
| /*enabled_features=*/{features::kGameDashboard, |
| features:: |
| kFeatureManagementGameDashboardRecordGame}, |
| /*disabled_features=*/{}); |
| } |
| GameDashboardCaptureModeTest(const GameDashboardCaptureModeTest&) = delete; |
| GameDashboardCaptureModeTest& operator=(const GameDashboardCaptureModeTest&) = |
| delete; |
| ~GameDashboardCaptureModeTest() override = default; |
| |
| aura::Window* game_window() const { return game_window_.get(); } |
| void CloseGameWindow() { game_window_.reset(); } |
| |
| // AshTestBase: |
| void SetUp() override { |
| AshTestBase::SetUp(); |
| EXPECT_TRUE(features::IsGameDashboardEnabled()); |
| |
| game_window_ = CreateAppWindow(gfx::Rect(0, 100, 300, 200)); |
| game_window_->SetProperty(kAppIDKey, |
| std::string(extension_misc::kGeForceNowAppId)); |
| } |
| |
| void TearDown() override { |
| game_window_.reset(); |
| AshTestBase::TearDown(); |
| } |
| |
| CaptureModeController* StartGameCaptureModeSession() { |
| auto* controller = CaptureModeController::Get(); |
| controller->StartForGameDashboard(game_window_.get()); |
| CHECK(controller->IsActive()); |
| return controller; |
| } |
| |
| // Verifies that the game capture bar is inside the selected game window. And |
| // centered above the fixed distance `kCaptureBarBottomPadding` from the |
| // bottom of the window. |
| void VerifyCaptureBarPosition() { |
| views::Widget* bar_widget = GetCaptureModeBarWidget(); |
| CHECK(bar_widget); |
| const gfx::Rect window_bounds = game_window()->GetBoundsInScreen(); |
| const gfx::Rect bar_bounds = bar_widget->GetWindowBoundsInScreen(); |
| EXPECT_TRUE(window_bounds.Contains(bar_bounds)); |
| EXPECT_EQ(bar_bounds.CenterPoint().x(), window_bounds.CenterPoint().x()); |
| EXPECT_EQ(bar_bounds.bottom() + capture_mode::kGameCaptureBarBottomPadding, |
| window_bounds.bottom()); |
| } |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| |
| std::unique_ptr<aura::Window> game_window_; |
| }; |
| |
| TEST_F(GameDashboardCaptureModeTest, GameDashboardBehavior) { |
| CaptureModeController* controller = StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = controller->capture_mode_session(); |
| CaptureModeBehavior* active_behavior = session->active_behavior(); |
| ASSERT_TRUE(active_behavior); |
| |
| EXPECT_FALSE(active_behavior->ShouldImageCaptureTypeBeAllowed()); |
| EXPECT_TRUE(active_behavior->ShouldVideoCaptureTypeBeAllowed()); |
| EXPECT_FALSE(active_behavior->ShouldFulscreenCaptureSourceBeAllowed()); |
| EXPECT_FALSE(active_behavior->ShouldRegionCaptureSourceBeAllowed()); |
| EXPECT_TRUE(active_behavior->ShouldWindowCaptureSourceBeAllowed()); |
| EXPECT_TRUE( |
| active_behavior->SupportsAudioRecordingMode(AudioRecordingMode::kOff)); |
| EXPECT_TRUE(active_behavior->SupportsAudioRecordingMode( |
| features::IsCaptureModeAudioMixingEnabled() |
| ? AudioRecordingMode::kSystemAndMicrophone |
| : AudioRecordingMode::kMicrophone)); |
| EXPECT_TRUE(active_behavior->ShouldCameraSelectionSettingsBeIncluded()); |
| EXPECT_FALSE(active_behavior->ShouldDemoToolsSettingsBeIncluded()); |
| EXPECT_TRUE(active_behavior->ShouldSaveToSettingsBeIncluded()); |
| EXPECT_FALSE(active_behavior->ShouldGifBeSupported()); |
| EXPECT_TRUE(active_behavior->ShouldShowPreviewNotification()); |
| EXPECT_FALSE(active_behavior->ShouldSkipVideoRecordingCountDown()); |
| EXPECT_FALSE(active_behavior->ShouldCreateRecordingOverlayController()); |
| EXPECT_FALSE(active_behavior->ShouldShowUserNudge()); |
| EXPECT_TRUE(active_behavior->ShouldAutoSelectFirstCamera()); |
| } |
| |
| // Tests that when starting the capture mode session from game dashboard, the |
| // window is pre-selected and won't be altered on mouse hover during the |
| // session. On the destroying of the pre-selected window, the selected window |
| // will be reset. |
| TEST_F(GameDashboardCaptureModeTest, StartForGameDashboardTest) { |
| UpdateDisplay("1000x700"); |
| std::unique_ptr<aura::Window> other_window( |
| CreateAppWindow(gfx::Rect(0, 300, 500, 300))); |
| CaptureModeController* controller = StartGameCaptureModeSession(); |
| BaseCaptureModeSession* capture_mode_session = |
| controller->capture_mode_session(); |
| ASSERT_TRUE(capture_mode_session); |
| EXPECT_EQ(capture_mode_session->GetSelectedWindow(), game_window()); |
| |
| // The selected window will not change when mouse hovers on `other_window`. |
| auto* event_generator = GetEventGenerator(); |
| event_generator->MoveMouseToCenterOf(other_window.get()); |
| EXPECT_EQ(capture_mode_session->GetSelectedWindow(), game_window()); |
| |
| CloseGameWindow(); |
| EXPECT_FALSE(controller->IsActive()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, CaptureBar) { |
| CaptureModeController* controller = StartGameCaptureModeSession(); |
| |
| views::Widget* bar_widget = GetCaptureModeBarWidget(); |
| ASSERT_TRUE(bar_widget); |
| |
| auto* start_recording_button = GetStartRecordingButton(); |
| // Checks that the game capture bar only includes the start recording button, |
| // settings button and close button. |
| EXPECT_TRUE(start_recording_button); |
| EXPECT_FALSE(GetImageToggleButton()); |
| EXPECT_FALSE(GetVideoToggleButton()); |
| EXPECT_FALSE(GetFullscreenToggleButton()); |
| EXPECT_FALSE(GetRegionToggleButton()); |
| EXPECT_FALSE(GetWindowToggleButton()); |
| EXPECT_TRUE(GetSettingsButton()); |
| EXPECT_TRUE(GetCloseButton()); |
| |
| BaseCaptureModeSession* session = controller->capture_mode_session(); |
| EXPECT_EQ(game_window(), session->GetSelectedWindow()); |
| // Clicking the start recording button should start the video recording. |
| ClickOnView(start_recording_button, GetEventGenerator()); |
| WaitForRecordingToStart(); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, CaptureBarPosition) { |
| StartGameCaptureModeSession(); |
| views::Widget* bar_widget = GetCaptureModeBarWidget(); |
| ASSERT_TRUE(bar_widget); |
| |
| VerifyCaptureBarPosition(); |
| |
| // Switching to the tablet mode, the game capture bar should still be inside |
| // the window. And centered above the constant distance from the bottom of the |
| // window. |
| SwitchToTabletMode(); |
| VerifyCaptureBarPosition(); |
| |
| // Switching back to the clamshell mode, the game capture bar should be |
| // positioned back to the constant distance from the bottom center of the |
| // window. |
| LeaveTabletMode(); |
| VerifyCaptureBarPosition(); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, CaptureBarPositionOnDisplayRotation) { |
| StartGameCaptureModeSession(); |
| views::Widget* bar_widget = GetCaptureModeBarWidget(); |
| ASSERT_TRUE(bar_widget); |
| |
| VerifyCaptureBarPosition(); |
| |
| auto* display_manager = Shell::Get()->display_manager(); |
| const int64_t display_id = WindowTreeHostManager::GetPrimaryDisplayId(); |
| |
| // Verifies that the capture bar is still at the bottom center position inside |
| // the selected window after display rotation. |
| for (const auto rotation : |
| {display::Display::ROTATE_90, display::Display::ROTATE_180, |
| display::Display::ROTATE_270}) { |
| display_manager->SetDisplayRotation(display_id, rotation, |
| display::Display::RotationSource::USER); |
| VerifyCaptureBarPosition(); |
| } |
| } |
| |
| // Tests that the game dashboard-initiated capture mode session shows the |
| // notification view with 'Share to YouTube' button and 'delete' buttons. |
| TEST_F(GameDashboardCaptureModeTest, NotificationView) { |
| CaptureModeController* controller = StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = controller->capture_mode_session(); |
| CaptureModeBehavior* active_behavior = session->active_behavior(); |
| ASSERT_TRUE(active_behavior); |
| StartVideoRecordingImmediately(); |
| CaptureModeTestApi().FlushRecordingServiceForTesting(); |
| |
| auto* test_delegate = |
| static_cast<TestCaptureModeDelegate*>(controller->delegate_for_testing()); |
| |
| // Request and wait for a video frame so that the recording service can use it |
| // to create a video thumbnail. |
| test_delegate->RequestAndWaitForVideoFrame(); |
| SkBitmap service_thumbnail = |
| gfx::Image(test_delegate->GetVideoThumbnail()).AsBitmap(); |
| EXPECT_FALSE(service_thumbnail.drawsNothing()); |
| |
| controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| EXPECT_FALSE(controller->can_start_new_recording()); |
| CaptureNotificationWaiter().Wait(); |
| EXPECT_TRUE(controller->can_start_new_recording()); |
| |
| const message_center::Notification* notification = GetPreviewNotification(); |
| EXPECT_TRUE(notification); |
| EXPECT_FALSE(notification->image().IsEmpty()); |
| |
| std::vector<ButtonInfo> expected_buttons_info = { |
| ButtonInfo( |
| l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_SHARE_TO_YOUTUBE)), |
| ButtonInfo( |
| l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_BUTTON_DELETE))}; |
| auto actual_buttons_info = |
| active_behavior->GetNotificationButtonsInfo(/*for_video=*/true); |
| EXPECT_EQ(actual_buttons_info.size(), 2u); |
| EXPECT_TRUE(actual_buttons_info == expected_buttons_info); |
| |
| const int share_to_youtube_button = 0; |
| ClickOnNotification(share_to_youtube_button); |
| EXPECT_FALSE(GetPreviewNotification()); |
| } |
| |
| // Tests that the camera preview widget shows up when starting the game |
| // dashboard initiated capture mode session for the first time. |
| TEST_F(GameDashboardCaptureModeTest, CameraPreviewWidgetTest) { |
| AddDefaultCamera(); |
| auto* camera_controller = CaptureModeController::Get()->camera_controller(); |
| EXPECT_FALSE(camera_controller->selected_camera().is_valid()); |
| |
| auto* controller = StartGameCaptureModeSession(); |
| EXPECT_TRUE(camera_controller->selected_camera().is_valid()); |
| EXPECT_TRUE(camera_controller->should_show_preview()); |
| GetEventGenerator()->MoveMouseToCenterOf(game_window()); |
| EXPECT_TRUE(camera_controller->camera_preview_widget()); |
| |
| controller->StartVideoRecordingImmediatelyForTesting(); |
| EXPECT_TRUE(camera_controller->should_show_preview()); |
| EXPECT_TRUE(camera_controller->camera_preview_widget()); |
| |
| controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton); |
| EXPECT_FALSE(camera_controller->should_show_preview()); |
| EXPECT_FALSE(camera_controller->camera_preview_widget()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, FocusNavigationOfCaptureBar) { |
| UpdateDisplay("1200x1100"); |
| AddDefaultCamera(); |
| auto* camera_controller = CaptureModeController::Get()->camera_controller(); |
| auto* controller = StartGameCaptureModeSession(); |
| ASSERT_TRUE(GetCaptureModeBarWidget()); |
| EXPECT_EQ(controller->capture_mode_session()->GetSelectedWindow(), |
| game_window()); |
| // Make the selected window large enough to hold collapsible camera preview. |
| game_window()->SetBounds({0, 0, 800, 700}); |
| |
| CaptureModeSessionTestApi test_api(controller->capture_mode_session()); |
| using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup; |
| auto* event_generator = GetEventGenerator(); |
| |
| // First tab should focus on the start recording button. |
| auto* start_recording_button = GetStartRecordingButton(); |
| SendKey(ui::VKEY_TAB, event_generator); |
| EXPECT_EQ(FocusGroup::kStartRecordingButton, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(CaptureModeSessionFocusCycler::HighlightHelper::Get( |
| start_recording_button) |
| ->has_focus()); |
| |
| // Tab again should advance the focus to the camera preview. |
| auto* camera_preview_view = camera_controller->camera_preview_view(); |
| SendKey(ui::VKEY_TAB, event_generator); |
| EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(camera_preview_view->has_focus()); |
| |
| // Tab again should advance the focus to the resize button inside the camera |
| // preview. |
| auto* resize_button = camera_preview_view->resize_button(); |
| SendKey(ui::VKEY_TAB, event_generator); |
| EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(1u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(resize_button->has_focus()); |
| |
| // Tab again should advance the focus to the settings button. |
| auto* settings_button = GetSettingsButton(); |
| SendKey(ui::VKEY_TAB, event_generator); |
| EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE( |
| CaptureModeSessionFocusCycler::HighlightHelper::Get(settings_button) |
| ->has_focus()); |
| |
| // Tab again should advance the focus to the close button. |
| auto* close_button = GetCloseButton(); |
| SendKey(ui::VKEY_TAB, event_generator); |
| EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(1u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(CaptureModeSessionFocusCycler::HighlightHelper::Get(close_button) |
| ->has_focus()); |
| |
| // Shift tab should advance the focus from the close button to the settings |
| // button. |
| SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN); |
| EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE( |
| CaptureModeSessionFocusCycler::HighlightHelper::Get(settings_button) |
| ->has_focus()); |
| |
| // Shift tab again should advance the focus from the settings button to the |
| // resize button inside the camera preview. |
| SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN); |
| EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(1u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(resize_button->has_focus()); |
| |
| // Shift tab again should advance the focus from the resize button to the |
| // camera preview. |
| SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN); |
| EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(camera_preview_view->has_focus()); |
| |
| // Shift tab again should advance the focus from the camera preview to the |
| // start recording button. |
| SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN); |
| EXPECT_EQ(FocusGroup::kStartRecordingButton, test_api.GetCurrentFocusGroup()); |
| EXPECT_EQ(0u, test_api.GetCurrentFocusIndex()); |
| EXPECT_TRUE(CaptureModeSessionFocusCycler::HighlightHelper::Get( |
| start_recording_button) |
| ->has_focus()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, GameCaptureModeSessionConfigs) { |
| // Verify capture mode session configs for the game dashboard initiated |
| // capture session. |
| auto* controller = StartGameCaptureModeSession(); |
| EXPECT_EQ(controller->type(), CaptureModeType::kVideo); |
| EXPECT_EQ(controller->source(), CaptureModeSource::kWindow); |
| EXPECT_EQ(controller->recording_type(), RecordingType::kWebM); |
| EXPECT_EQ(controller->audio_recording_mode(), |
| features::IsCaptureModeAudioMixingEnabled() |
| ? AudioRecordingMode::kSystemAndMicrophone |
| : AudioRecordingMode::kMicrophone); |
| EXPECT_EQ(controller->enable_demo_tools(), false); |
| |
| // Update the audio recording mode and demo tools configs and stop the |
| // session. |
| controller->SetAudioRecordingMode(AudioRecordingMode::kSystem); |
| controller->EnableDemoTools(true); |
| controller->Stop(); |
| |
| // Start another game dashboard initiated capture mode session and verify |
| // that the audio recording mode and demo tools settings are restored from |
| // previous session. |
| StartGameCaptureModeSession(); |
| EXPECT_EQ(controller->type(), CaptureModeType::kVideo); |
| EXPECT_EQ(controller->source(), CaptureModeSource::kWindow); |
| EXPECT_EQ(controller->recording_type(), RecordingType::kWebM); |
| EXPECT_EQ(controller->audio_recording_mode(), AudioRecordingMode::kSystem); |
| EXPECT_TRUE(controller->enable_demo_tools()); |
| controller->Stop(); |
| |
| // Verify that the session configs from the game dashboard initiated capture |
| // mode session will not be carried over to the default capture mode session. |
| StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kImage); |
| EXPECT_EQ(controller->type(), CaptureModeType::kImage); |
| EXPECT_EQ(controller->source(), CaptureModeSource::kFullscreen); |
| EXPECT_EQ(controller->recording_type(), RecordingType::kWebM); |
| EXPECT_EQ(controller->audio_recording_mode(), AudioRecordingMode::kOff); |
| EXPECT_FALSE(controller->enable_demo_tools()); |
| controller->Stop(); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, MultiDisplay) { |
| UpdateDisplay("800x700,801+0-900x800"); |
| const auto& displays = display_manager()->active_display_list(); |
| ASSERT_EQ(2u, displays.size()); |
| EXPECT_EQ(displays[0].size(), gfx::Size(800, 700)); |
| EXPECT_EQ(displays[1].size(), gfx::Size(900, 800)); |
| |
| display::Screen* screen = display::Screen::GetScreen(); |
| auto* controller = StartGameCaptureModeSession(); |
| BaseCaptureModeSession* capture_mode_session = |
| controller->capture_mode_session(); |
| auto* event_generator = GetEventGenerator(); |
| EXPECT_EQ(displays[0].id(), |
| screen->GetDisplayNearestWindow(game_window()).id()); |
| EXPECT_EQ(Shell::GetAllRootWindows()[0], |
| capture_mode_session->current_root()); |
| VerifyCaptureBarPosition(); |
| // The current root window should not change if moving the cursor to a |
| // different display as the game window. |
| event_generator->MoveMouseTo(displays[1].bounds().CenterPoint()); |
| EXPECT_EQ(Shell::GetAllRootWindows()[0], |
| capture_mode_session->current_root()); |
| |
| // Using the shortcut ALT+SEARCH+M to move the window to another display. |
| PressAndReleaseKey(ui::VKEY_M, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN); |
| // Verifies that the capture bar and the current root window of the capture |
| // mode session are updated correctly after moving the game window to another |
| // display. |
| EXPECT_EQ(displays[1].id(), |
| screen->GetDisplayNearestWindow(game_window()).id()); |
| EXPECT_EQ(Shell::GetAllRootWindows()[1], |
| capture_mode_session->current_root()); |
| VerifyCaptureBarPosition(); |
| // The current root window should not change if moving the cursor to a |
| // different display as the game window. |
| event_generator->MoveMouseTo(displays[0].bounds().CenterPoint()); |
| EXPECT_EQ(Shell::GetAllRootWindows()[1], |
| capture_mode_session->current_root()); |
| |
| // Using the shortcut ALT+SEARCH+M to move the window back to the previous |
| // display. |
| PressAndReleaseKey(ui::VKEY_M, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN); |
| // Verifies the capture bar and the current root window after moving the game |
| // window back to the previous display. |
| EXPECT_EQ(displays[0].id(), |
| screen->GetDisplayNearestWindow(game_window()).id()); |
| EXPECT_EQ(Shell::GetAllRootWindows()[0], |
| capture_mode_session->current_root()); |
| VerifyCaptureBarPosition(); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, NoLabelInTabletMode) { |
| auto* controller = StartGameCaptureModeSession(); |
| |
| BaseCaptureModeSession* session = controller->capture_mode_session(); |
| ASSERT_EQ(game_window(), session->GetSelectedWindow()); |
| |
| SwitchToTabletMode(); |
| |
| views::Label* label_internal_view = |
| CaptureModeSessionTestApi(session).GetCaptureLabelInternalView(); |
| EXPECT_FALSE(label_internal_view->GetVisible()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightFullAboveBar) { |
| UpdateDisplay("1000x500"); |
| game_window()->SetBounds(gfx::Rect(0, 50, 500, 450)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // There is space for the settings menu to take up its entire preferred size |
| // above the bar view. |
| EXPECT_GE(settings_bounds.y(), |
| capture_mode::kMinDistanceFromSettingsToScreen); |
| EXPECT_EQ(settings_bounds.height(), |
| test_api.GetCaptureModeSettingsView()->GetPreferredSize().height()); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightFullBelowBar) { |
| UpdateDisplay("1000x500"); |
| game_window()->SetBounds(gfx::Rect(0, 0, 500, 100)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // There is space for the settings menu to take up its entire preferred size |
| // below the bar view, but not above it. |
| const auto bar_bounds = test_api.GetCaptureModeBarView()->GetBoundsInScreen(); |
| EXPECT_EQ(settings_bounds.y(), |
| bar_bounds.bottom() + |
| capture_mode::kSpaceBetweenCaptureBarAndSettingsMenu); |
| EXPECT_GE(settings_bounds.y(), |
| capture_mode::kMinDistanceFromSettingsToScreen); |
| EXPECT_EQ(settings_bounds.height(), |
| test_api.GetCaptureModeSettingsView()->GetPreferredSize().height()); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightConstrainedAboveBar) { |
| UpdateDisplay("1000x250"); |
| game_window()->SetBounds(gfx::Rect(0, 50, 500, 200)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // The menu height has been constrained, but has not reached its minimum size. |
| EXPECT_EQ(settings_bounds.y(), |
| capture_mode::kMinDistanceFromSettingsToScreen); |
| EXPECT_LT(settings_bounds.height(), |
| test_api.GetCaptureModeSettingsView()->GetPreferredSize().height()); |
| EXPECT_GT(settings_bounds.height(), capture_mode::kSettingsMenuMinHeight); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightConstrainedBelowBar) { |
| UpdateDisplay("1000x500"); |
| game_window()->SetBounds(gfx::Rect(0, 0, 500, 200)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // The menu height has been constrained, but has not reached its minimum size. |
| const auto bar_bounds = test_api.GetCaptureModeBarView()->GetBoundsInScreen(); |
| EXPECT_EQ(settings_bounds.y(), |
| bar_bounds.bottom() + |
| capture_mode::kSpaceBetweenCaptureBarAndSettingsMenu); |
| EXPECT_LT(settings_bounds.height(), |
| test_api.GetCaptureModeSettingsView()->GetPreferredSize().height()); |
| EXPECT_GT(settings_bounds.height(), capture_mode::kSettingsMenuMinHeight); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightMinimumAboveBar) { |
| UpdateDisplay("1000x100"); |
| game_window()->SetBounds(gfx::Rect(0, 50, 500, 50)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // The menu is at its minimum size and height above the bar view. |
| EXPECT_EQ(settings_bounds.y(), |
| capture_mode::kMinDistanceFromSettingsToScreen); |
| EXPECT_EQ(settings_bounds.height(), capture_mode::kSettingsMenuMinHeight); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, StopOnWindowSentToDifferentDesk) { |
| NewDesk(); |
| auto* controller = StartGameCaptureModeSession(); |
| |
| // Send the window to a different desk using the accelerator. |
| PressAndReleaseKey(ui::VKEY_OEM_6, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); |
| EXPECT_FALSE(controller->IsActive()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, StopOnActiveDeskChanged) { |
| NewDesk(); |
| auto* controller = StartGameCaptureModeSession(); |
| |
| // Switch to the new desk using the accelerator. |
| DeskSwitchAnimationWaiter waiter; |
| PressAndReleaseKey(ui::VKEY_OEM_6, ui::EF_COMMAND_DOWN); |
| waiter.Wait(); |
| EXPECT_FALSE(controller->IsActive()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, SettingsMenuHeightMinimumBelowBar) { |
| UpdateDisplay("1000x100"); |
| game_window()->SetBounds(gfx::Rect(0, 0, 500, 50)); |
| StartGameCaptureModeSession(); |
| BaseCaptureModeSession* session = |
| CaptureModeController::Get()->capture_mode_session(); |
| ASSERT_TRUE(session); |
| |
| // Open the settings menu. |
| ClickOnView(GetSettingsButton(), GetEventGenerator()); |
| CaptureModeSessionTestApi test_api(session); |
| ASSERT_TRUE(test_api.GetCaptureModeSettingsWidget()); |
| |
| const gfx::Rect settings_bounds = |
| test_api.GetCaptureModeSettingsWidget()->GetWindowBoundsInScreen(); |
| |
| // The menu is at its minimum size and height below the bar view. |
| const auto bar_bounds = test_api.GetCaptureModeBarView()->GetBoundsInScreen(); |
| EXPECT_EQ(settings_bounds.y(), |
| bar_bounds.bottom() + |
| capture_mode::kSpaceBetweenCaptureBarAndSettingsMenu); |
| EXPECT_EQ(settings_bounds.height(), capture_mode::kSettingsMenuMinHeight); |
| EXPECT_EQ( |
| settings_bounds.size(), |
| CaptureModeSettingsTestApi().GetSettingsView()->GetVisibleRect().size()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, GameCaptureModeRecordInstantlyTest) { |
| // Start a game dashboard initiated capture mode session and check the initial |
| // configs for game dashboard initiated capture mode. |
| auto* controller = StartGameCaptureModeSession(); |
| EXPECT_FALSE(controller->enable_demo_tools()); |
| EXPECT_EQ(controller->audio_recording_mode(), |
| features::IsCaptureModeAudioMixingEnabled() |
| ? AudioRecordingMode::kSystemAndMicrophone |
| : AudioRecordingMode::kMicrophone); |
| |
| // Update the audio recording mode and demo tools configs for the |
| // game-dashboard initiated capture mode. |
| controller->SetAudioRecordingMode(AudioRecordingMode::kOff); |
| controller->EnableDemoTools(true); |
| controller->Stop(); |
| |
| // Start the recording with the game dashboard instant recording API. |
| controller->StartRecordingInstantlyForGameDashboard(game_window()); |
| |
| // Verify that recording starts immediately. |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| |
| // Verify that the game dashboard capture mode configs are not overwritten. |
| CaptureModeBehavior* behavior = |
| CaptureModeTestApi().GetBehavior(BehaviorType::kGameDashboard); |
| const auto capture_mode_configs = behavior->capture_mode_configs(); |
| EXPECT_EQ(capture_mode_configs.audio_recording_mode, |
| AudioRecordingMode::kOff); |
| EXPECT_TRUE(capture_mode_configs.demo_tools_enabled); |
| |
| // Verify that the configs in `CaptureModeController` are restored. |
| EXPECT_EQ(controller->audio_recording_mode(), AudioRecordingMode::kOff); |
| EXPECT_FALSE(controller->enable_demo_tools()); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, NoDimmingOfGameDashboardWidgets) { |
| auto* controller = CaptureModeController::Get(); |
| controller->StartRecordingInstantlyForGameDashboard(game_window()); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| auto* recording_watcher = controller->video_recording_watcher_for_testing(); |
| ASSERT_EQ(game_window(), recording_watcher->window_being_recorded()); |
| EXPECT_FALSE(recording_watcher->IsWindowDimmedForTesting(game_window())); |
| |
| // The window that hosts the game dashboard button should not be dimmed. |
| GameDashboardContextTestApi context_test_api{ |
| GameDashboardController::Get()->GetGameDashboardContext(game_window()), |
| GetEventGenerator()}; |
| auto* game_dashboard_button_widget = |
| context_test_api.GetGameDashboardButtonWidget(); |
| ASSERT_TRUE(game_dashboard_button_widget); |
| EXPECT_FALSE(recording_watcher->IsWindowDimmedForTesting( |
| game_dashboard_button_widget->GetNativeWindow())); |
| |
| // Open the game dashboard menu, and expect that the window hosting the menu |
| // is not dimmed either. |
| context_test_api.OpenTheMainMenu(); |
| auto* game_dashboard_menu_widget = context_test_api.GetMainMenuWidget(); |
| ASSERT_TRUE(game_dashboard_menu_widget); |
| EXPECT_FALSE(recording_watcher->IsWindowDimmedForTesting( |
| game_dashboard_menu_widget->GetNativeWindow())); |
| |
| // Finally, the toolbar widget should also not be dimmed. |
| context_test_api.OpenTheToolbar(); |
| auto* game_dashboard_toolbar_widget = context_test_api.GetToolbarWidget(); |
| ASSERT_TRUE(game_dashboard_toolbar_widget); |
| EXPECT_FALSE(recording_watcher->IsWindowDimmedForTesting( |
| game_dashboard_toolbar_widget->GetNativeWindow())); |
| } |
| |
| TEST_F(GameDashboardCaptureModeTest, CursorAndClickBehaviorWhenAnchored) { |
| // Create second window on screen that underlaps `game_window_` slightly. |
| std::unique_ptr<aura::Window> window( |
| CreateTestWindow(gfx::Rect(50, 150, 100, 100))); |
| |
| // The game window should be the top most active window. |
| wm::ActivateWindow(game_window()); |
| // TODO(b/316141148): Remove this call once the welcome dialog is disabled by |
| // default for tests. |
| WaitForSeconds(/*seconds=*/4); |
| auto* controller = StartGameCaptureModeSession(); |
| |
| // Hover over empty space where there is no window. |
| auto* event_generator = GetEventGenerator(); |
| event_generator->MoveMouseTo(gfx::Point(0, 0)); |
| auto* cursor_manager = Shell::Get()->cursor_manager(); |
| EXPECT_EQ(CursorType::kPointer, cursor_manager->GetCursor().type()); |
| // Clicking should not start a recording. |
| event_generator->ClickLeftButton(); |
| EXPECT_TRUE(controller->IsActive()); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| |
| // Hover over the non-game window. |
| event_generator->MoveMouseTo(gfx::Point(125, 225)); |
| EXPECT_EQ(CursorType::kPointer, cursor_manager->GetCursor().type()); |
| event_generator->ClickLeftButton(); |
| // Clicking should not start a recording. |
| EXPECT_TRUE(controller->IsActive()); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| |
| // Hover over the anchored window where it overlaps with the non-game window. |
| event_generator->MoveMouseTo(gfx::Point(75, 175)); |
| EXPECT_EQ(CursorType::kCustom, cursor_manager->GetCursor().type()); |
| EXPECT_TRUE( |
| CaptureModeSessionTestApi().IsUsingCustomCursor(CaptureModeType::kVideo)); |
| // Start recording by clicking on the anchored window. |
| event_generator->ClickLeftButton(); |
| WaitForRecordingToStart(); |
| EXPECT_FALSE(controller->IsActive()); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| // GameDashboardCaptureModeHistogramTest: |
| // Test fixture to verify game dashboard initiated screen capture histograms |
| // depending on the test param (true for tablet mode, false for clamshell mode). |
| |
| class GameDashboardCaptureModeHistogramTest |
| : public GameDashboardCaptureModeTest, |
| public ::testing::WithParamInterface<bool> { |
| public: |
| GameDashboardCaptureModeHistogramTest() = default; |
| ~GameDashboardCaptureModeHistogramTest() override = default; |
| |
| // GameDashboardCaptureModeTest: |
| void SetUp() override { |
| GameDashboardCaptureModeTest::SetUp(); |
| if (GetParam()) { |
| SwitchToTabletMode(); |
| } |
| } |
| |
| protected: |
| base::HistogramTester histogram_tester_; |
| }; |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameCaptureConfigurationHistogram) { |
| constexpr char kCaptureConfigurationBase[] = "CaptureConfiguration"; |
| CaptureModeTestApi test_api; |
| const std::string histogram_name = |
| BuildHistogramName(kCaptureConfigurationBase, |
| test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeConfiguration::kWindowRecording, 0); |
| |
| auto* controller = StartGameCaptureModeSession(); |
| StartVideoRecordingImmediately(); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| test_api.StopVideoRecording(); |
| WaitForCaptureFileToBeSaved(); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeConfiguration::kWindowRecording, 1); |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameCaptureConfigurationHistogramForInstantScreenshot) { |
| constexpr char kCaptureConfigurationBase[] = "CaptureConfiguration"; |
| CaptureModeTestApi test_api; |
| const std::string histogram_name = |
| BuildHistogramName(kCaptureConfigurationBase, |
| test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeConfiguration::kWindowScreenshot, 0); |
| |
| CaptureModeController::Get()->CaptureScreenshotOfGivenWindow(game_window()); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeConfiguration::kWindowScreenshot, 1); |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameScreenRecordingLengthHistogram) { |
| constexpr char kRecordLenthHistogramBase[] = "ScreenRecordingLength"; |
| |
| auto* controller = StartGameCaptureModeSession(); |
| StartVideoRecordingImmediately(); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| WaitForSeconds(/*seconds=*/1); |
| |
| CaptureModeTestApi test_api; |
| test_api.StopVideoRecording(); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| WaitForCaptureFileToBeSaved(); |
| |
| histogram_tester_.ExpectUniqueSample( |
| BuildHistogramName(kRecordLenthHistogramBase, |
| test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true), |
| /*sample=*/1, /*expected_bucket_count=*/1); |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameScreenRecordingFileSizeHistogram) { |
| constexpr char kHistogramNameBase[] = "ScreenRecordingFileSize"; |
| |
| CaptureModeTestApi test_api; |
| const auto histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectTotalCount(histogram_name, /*expected_count=*/0); |
| |
| StartGameCaptureModeSession(); |
| StartVideoRecordingImmediately(); |
| test_api.StopVideoRecording(); |
| WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectTotalCount(histogram_name, |
| /*expected_count=*/1); |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, GameSaveToLocationHistogram) { |
| constexpr char kHistogramNameBase[] = "SaveLocation"; |
| |
| CaptureModeTestApi test_api; |
| const auto histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| |
| auto* test_delegate = CaptureModeController::Get()->delegate_for_testing(); |
| |
| // Initialize four different save-to locations for screen capture that |
| // includes default downloads folder, local customized folder, root drive and |
| // a specific folder on drive. |
| const auto downloads_folder = test_delegate->GetUserDefaultDownloadsFolder(); |
| const base::FilePath custom_folder = |
| CreateCustomFolderInUserDownloadsPath("test"); |
| base::FilePath mount_point_path; |
| test_delegate->GetDriveFsMountPointPath(&mount_point_path); |
| const auto root_drive_folder = mount_point_path.Append("root"); |
| const base::FilePath non_root_drive_folder = CreateFolderOnDriveFS("test"); |
| |
| struct { |
| base::FilePath set_save_file_folder; |
| CaptureModeSaveToLocation save_location; |
| } kTestCases[] = { |
| {downloads_folder, CaptureModeSaveToLocation::kDefault}, |
| {custom_folder, CaptureModeSaveToLocation::kCustomizedFolder}, |
| {root_drive_folder, CaptureModeSaveToLocation::kDrive}, |
| {non_root_drive_folder, CaptureModeSaveToLocation::kDriveFolder}, |
| }; |
| |
| for (auto test_case : kTestCases) { |
| histogram_tester_.ExpectBucketCount(histogram_name, test_case.save_location, |
| 0); |
| auto* controller = StartGameCaptureModeSession(); |
| controller->SetCustomCaptureFolder(test_case.set_save_file_folder); |
| StartVideoRecordingImmediately(); |
| test_api.StopVideoRecording(); |
| auto file_saved_path = WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount(histogram_name, test_case.save_location, |
| 1); |
| } |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameRecordingStartsWithCameraHistogram) { |
| UpdateDisplay("1000x700"); |
| constexpr char kHistogramNameBase[] = "RecordingStartsWithCamera"; |
| AddDefaultCamera(); |
| |
| for (const auto camera_on : {true, false}) { |
| CaptureModeTestApi test_api; |
| const std::string histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount(histogram_name, camera_on, 0); |
| |
| auto* controller = StartGameCaptureModeSession(); |
| EXPECT_EQ(controller->type(), CaptureModeType::kVideo); |
| auto* camera_controller = controller->camera_controller(); |
| if (!camera_on) { |
| camera_controller->SetSelectedCamera(CameraId()); |
| } |
| test_api.PerformCapture(); |
| WaitForRecordingToStart(); |
| EXPECT_TRUE(controller->is_recording_in_progress()); |
| |
| test_api.StopVideoRecording(); |
| EXPECT_FALSE(controller->is_recording_in_progress()); |
| WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount(histogram_name, camera_on, 1); |
| } |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameDemoToolsEnabledOnRecordingHistogram) { |
| constexpr char kHistogramNameBase[] = "DemoToolsEnabledOnRecordingStart"; |
| CaptureModeTestApi test_api; |
| for (const auto enable_demo_tools : {false, true}) { |
| const auto histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount(histogram_name, enable_demo_tools, 0); |
| auto* controller = StartGameCaptureModeSession(); |
| controller->EnableDemoTools(enable_demo_tools); |
| StartVideoRecordingImmediately(); |
| test_api.StopVideoRecording(); |
| WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount(histogram_name, enable_demo_tools, 1); |
| } |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, GameAudioRecordingModeHistogram) { |
| constexpr char kHistogramNameBase[] = "AudioRecordingMode"; |
| CaptureModeTestApi test_api; |
| for (const auto audio_mode : |
| {AudioRecordingMode::kOff, AudioRecordingMode::kMicrophone, |
| AudioRecordingMode::kSystem, |
| AudioRecordingMode::kSystemAndMicrophone}) { |
| const auto histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount(histogram_name, audio_mode, 0); |
| auto* controller = StartGameCaptureModeSession(); |
| controller->SetAudioRecordingMode(audio_mode); |
| controller->Stop(); |
| histogram_tester_.ExpectBucketCount(histogram_name, audio_mode, 1); |
| } |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| GameDashboardEndRecordingReasonHistogram) { |
| constexpr char kHistogramNameBase[] = "EndRecordingReason"; |
| |
| CaptureModeTestApi test_api; |
| |
| const std::string histogram_name = BuildHistogramName( |
| kHistogramNameBase, test_api.GetBehavior(BehaviorType::kDefault), |
| /*append_ui_mode_suffix=*/true); |
| |
| // Testing the game dashboard stop recording button enum. |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, |
| /*sample=*/EndRecordingReason::kGameDashboardStopRecordingButton, |
| /*expected_count=*/0); |
| StartGameCaptureModeSession(); |
| StartVideoRecordingImmediately(); |
| CaptureModeController::Get()->EndVideoRecording( |
| EndRecordingReason::kGameDashboardStopRecordingButton); |
| WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, |
| /*sample=*/EndRecordingReason::kGameDashboardStopRecordingButton, |
| /*expected_count=*/1); |
| |
| // Testing the game toolbar stop recording button enum. |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, |
| /*sample=*/EndRecordingReason::kGameToolbarStopRecordingButton, |
| /*expected_count=*/0); |
| StartGameCaptureModeSession(); |
| StartVideoRecordingImmediately(); |
| CaptureModeController::Get()->EndVideoRecording( |
| EndRecordingReason::kGameToolbarStopRecordingButton); |
| WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, |
| /*sample=*/EndRecordingReason::kGameToolbarStopRecordingButton, |
| /*expected_count=*/1); |
| } |
| |
| TEST_P(GameDashboardCaptureModeHistogramTest, |
| CaptureScreenshotOfGivenWindowMetric) { |
| constexpr char kHistogramNameBase[] = "SaveLocation"; |
| const base::FilePath custom_folder = |
| CreateCustomFolderInUserDownloadsPath("test"); |
| const auto histogram_name = BuildHistogramName( |
| kHistogramNameBase, |
| CaptureModeTestApi().GetBehavior(BehaviorType::kGameDashboard), |
| /*append_ui_mode_suffix=*/true); |
| |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeSaveToLocation::kCustomizedFolder, 0); |
| CaptureModeController* controller = CaptureModeController::Get(); |
| controller->SetCustomCaptureFolder(custom_folder); |
| controller->CaptureScreenshotOfGivenWindow(game_window()); |
| const auto file_saved_path = WaitForCaptureFileToBeSaved(); |
| histogram_tester_.ExpectBucketCount( |
| histogram_name, CaptureModeSaveToLocation::kCustomizedFolder, 1); |
| } |
| |
| // Tests that the entry point metrics are recorded correctly for game dashboard |
| // initiated capture mode both with and without a capture mode session. |
| TEST_P(GameDashboardCaptureModeHistogramTest, EntryPointTest) { |
| constexpr char kCaptureConfigurationBase[] = "EntryPoint"; |
| CaptureModeTestApi test_api; |
| const std::string histogram_name = |
| BuildHistogramName(kCaptureConfigurationBase, nullptr, |
| /*append_ui_mode_suffix=*/true); |
| histogram_tester_.ExpectBucketCount(histogram_name, |
| CaptureModeEntryType::kGameDashboard, 0); |
| |
| auto* controller = StartGameCaptureModeSession(); |
| controller->Stop(); |
| histogram_tester_.ExpectBucketCount(histogram_name, |
| CaptureModeEntryType::kGameDashboard, 1); |
| |
| controller->StartRecordingInstantlyForGameDashboard(game_window()); |
| histogram_tester_.ExpectBucketCount(histogram_name, |
| CaptureModeEntryType::kGameDashboard, 2); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(All, |
| GameDashboardCaptureModeHistogramTest, |
| ::testing::Bool()); |
| |
| } // namespace ash |