0

gd: Update Screen Size Row Strings

Updates the subtitle of the Screen Size Row within the main menu to
display additional information that details what options a user has on a
given game. This string changes depending on whether the game is O4C and
the current AMACe state of the game.

Bug: b:311243952
Test: Manual test and added unit tests
Demo: http://b/311243952#comment4
Change-Id: If773d371e199e722bc54bd9510e503779c23263d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5717499
Commit-Queue: Gina Domergue <gdomergue@google.com>
Reviewed-by: Prameet Shah <phshah@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1332703}
This commit is contained in:
Gina Domergue
2024-07-25 00:37:20 +00:00
committed by Chromium LUCI CQ
parent e8652dc898
commit 04e62f4ebe
10 changed files with 238 additions and 14 deletions

@ -7993,6 +7993,18 @@ To shut down the device, press and hold the power button on the device again.
<message name="IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_SETTINGS_TITLE" desc="The display name for the Game Dashboard screen size settings.">
Screen size
</message>
<message name="IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_EXIT_FULLSCREEN" desc="The text displayed within the screen size settings row to indicate that a user must exit fullscreen to resize this game.">
Exit fullscreen to resize
</message>
<message name="IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_FULLSCREEN" desc="The text displayed within the screen size settings row to indicate that this game is only available in fullscreen.">
Only fullscreen available
</message>
<message name="IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_PORTRAIT" desc="The text displayed within the screen size settings row to indicate that only the portrait size is available for this game.">
Only portrait available
</message>
<message name="IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_LANDSCAPE" desc="The text displayed within the screen size settings row to indicate that only the landscape size is available for this game.">
Only landscape available
</message>
<message name="IDS_ASH_GAME_DASHBOARD_SEND_FEEDBACK_TITLE" desc="The display name for the Game Dashboard send feedback button.">
Send feedback
</message>

@ -0,0 +1 @@
41b14aaa6adb7a5537953c5a9d18ea2a371ae503

@ -0,0 +1 @@
0fed4ec9977a330379cd80929297abad889653eb

@ -0,0 +1 @@
d3d9f248397ad6e4b4541eb86191aff59f276723

@ -0,0 +1 @@
5edadad3b6a87d7f59cb2cd2e1edabbcb3ecc7a1

@ -111,6 +111,16 @@ FeatureTile* GameDashboardContextTestApi::GetMainMenuScreenshotTile() {
GetMainMenuViewById(VIEW_ID_GD_SCREENSHOT_TILE));
}
const std::u16string&
GameDashboardContextTestApi::GetMainMenuScreenSizeSubtitle() {
auto* main_menu_view = GetMainMenuView();
CHECK(main_menu_view);
const views::Label* subtitle_label =
main_menu_view->GetScreenSizeRowSubtitle();
CHECK(subtitle_label);
return subtitle_label->GetText();
}
views::Button*
GameDashboardContextTestApi::GetMainMenuScreenSizeSettingsButton() {
return views::AsViewClass<views::Button>(

@ -71,6 +71,7 @@ class GameDashboardContextTestApi {
FeatureTile* GetMainMenuToolbarTile();
FeatureTile* GetMainMenuRecordGameTile();
FeatureTile* GetMainMenuScreenshotTile();
const std::u16string& GetMainMenuScreenSizeSubtitle();
views::Button* GetMainMenuScreenSizeSettingsButton();
views::Button* GetMainMenuGameControlsDetailsButton();
PillButton* GetMainMenuGameControlsSetupButton();

@ -15,6 +15,7 @@
#include "ash/capture_mode/capture_mode_types.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/frame/non_client_frame_view_ash.h"
#include "ash/game_dashboard/game_dashboard_button.h"
#include "ash/game_dashboard/game_dashboard_constants.h"
#include "ash/game_dashboard/game_dashboard_context_test_api.h"
@ -52,6 +53,8 @@
#include "base/test/scoped_feature_list.h"
#include "base/timer/timer.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h"
#include "chromeos/ui/frame/frame_header.h"
#include "chromeos/ui/wm/window_util.h"
#include "components/ukm/test_ukm_recorder.h"
#include "extensions/common/constants.h"
@ -311,6 +314,26 @@ class EventCapturer : public ui::EventHandler {
std::unique_ptr<ui::MouseEvent> last_mouse_event_;
};
// Test model mimicking a default `chromeos::CaptionButtonModel` that ensures
// there's no maximize button within the frame header buttons.
class NonResizableButtonModel : public chromeos::CaptionButtonModel {
public:
NonResizableButtonModel() = default;
NonResizableButtonModel(const NonResizableButtonModel&) = delete;
NonResizableButtonModel& operator=(const NonResizableButtonModel&) = delete;
~NonResizableButtonModel() override = default;
// chromeos::CaptionButtonModel:
bool IsVisible(views::CaptionButtonIcon type) const override {
if (type == views::CAPTION_BUTTON_ICON_MINIMIZE) {
return true;
}
return false;
}
bool IsEnabled(views::CaptionButtonIcon type) const override { return true; }
bool InZoomMode() const override { return false; }
};
} // namespace
class GameDashboardContextTest : public GameDashboardTestBase {
@ -740,7 +763,8 @@ class GameDashboardContextTest : public GameDashboardTestBase {
EXPECT_EQ(test_api_->GetToolbarSnapLocation(), desired_location);
}
void CreateAnArcAppInFullscreen() {
void CreateAnArcAppInFullscreen(std::unique_ptr<chromeos::CaptionButtonModel>
caption_button_model = nullptr) {
// Create an ARC game window.
SetAppBounds(gfx::Rect(50, 50, 800, 700));
CreateGameWindow(/*is_arc_window=*/true,
@ -751,10 +775,23 @@ class GameDashboardContextTest : public GameDashboardTestBase {
views::Widget* button_widget = test_api_->GetGameDashboardButtonWidget();
CHECK(button_widget);
// Set initial state to fullscreen and verify Game Dashboard button widget
// is not visible.
if (caption_button_model) {
// Override the caption button model and ensure the values referencing the
// model are updated.
auto* frame_view = NonClientFrameViewAsh::Get(game_window_.get());
ASSERT_TRUE(frame_view);
frame_view->SetCaptionButtonModel(std::move(caption_button_model));
}
// Set initial state to fullscreen, ensure the animations are complete after
// toggling the fullscreen state, and verify Game Dashboard button widget is
// not visible.
ASSERT_FALSE(test_api_->GetGameDashboardButtonRevealController());
ToggleFullScreen(window_state, /*delegate=*/nullptr);
auto* frame_view = NonClientFrameViewAsh::Get(game_window_.get());
chromeos::FrameCaptionButtonContainerView::TestApi test_api(
frame_view->GetHeaderView()->caption_button_container());
test_api.EndAnimations();
ASSERT_TRUE(window_state->IsFullscreen());
ASSERT_FALSE(button_widget->IsVisible());
ASSERT_TRUE(test_api_->GetGameDashboardButtonRevealController());
@ -1257,6 +1294,115 @@ TEST_F(GameDashboardContextTest, ScreenSizeRowAvailability) {
EXPECT_FALSE(test_api_->GetMainMenuScreenSizeSettingsButton());
}
// Verifies a not O4C resizable app in portrait mode displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_PortraitResizable) {
// Create an ARC game window in portrait mode that is resizable.
SetAppBounds(gfx::Rect(50, 50, 400, 700));
CreateGameWindow(/*is_arc_window=*/true);
game_window_->SetProperty(kArcResizeLockTypeKey,
ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE);
test_api_->OpenTheMainMenu();
EXPECT_EQ(u"Portrait", test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C resizable app in landscape mode displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_LandscapeResizable) {
// Create an ARC game window in landscape mode that is resizable.
CreateGameWindow(/*is_arc_window=*/true);
game_window_->SetProperty(kArcResizeLockTypeKey,
ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE);
test_api_->OpenTheMainMenu();
EXPECT_EQ(u"Landscape", test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C resizable app in resizable mode displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_FreeformResizable) {
// Create an ARC game window in free resizing mode.
CreateGameWindow(/*is_arc_window=*/true);
game_window_->SetProperty(kArcResizeLockTypeKey,
ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE);
test_api_->OpenTheMainMenu();
EXPECT_EQ(u"Resizable", test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C non-resizable app in portrait mode displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_PortraitNonTogglable) {
// Create an ARC game window that only supports portrait mode.
SetAppBounds(gfx::Rect(50, 50, 400, 700));
CreateGameWindow(/*is_arc_window=*/true);
game_window_->SetProperty(kArcResizeLockTypeKey,
ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE);
test_api_->OpenTheMainMenu();
EXPECT_EQ(u"Only portrait available",
test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C non-resizable app in landscape mode displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_LandscapeNonTogglable) {
// Create an ARC game window that only supports landscape mode.
CreateGameWindow(/*is_arc_window=*/true);
game_window_->SetProperty(kArcResizeLockTypeKey,
ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE);
test_api_->OpenTheMainMenu();
EXPECT_EQ(u"Only landscape available",
test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C resizable app in fullscreen displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_FullscreenTogglable) {
// Create an ARC game window in fullscreen that can be resized via the size
// button in the frame header.
CreateAnArcAppInFullscreen();
// Open the Game Dashboard menu with the accelerator.
AcceleratorControllerImpl* controller =
Shell::Get()->accelerator_controller();
const ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
auto* button_widget = test_api_->GetGameDashboardButtonWidget();
CHECK(button_widget);
ASSERT_TRUE(controller->Process(gd_accelerator));
ASSERT_TRUE(button_widget->IsVisible());
EXPECT_EQ(u"Exit fullscreen to resize",
test_api_->GetMainMenuScreenSizeSubtitle());
}
// Verifies a not O4C non-resizable app in fullscreen displays the expected
// description within the screen size row.
TEST_F(GameDashboardContextTest, ScreenSizeRowSubtitle_FullscreenNonTogglable) {
// Create an ARC game window in fullscreen that can't be resized.
CreateAnArcAppInFullscreen(
/*caption_button_model=*/std::make_unique<NonResizableButtonModel>());
// Open the Game Dashboard menu with the accelerator.
AcceleratorControllerImpl* controller =
Shell::Get()->accelerator_controller();
const ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
auto* button_widget = test_api_->GetGameDashboardButtonWidget();
CHECK(button_widget);
ASSERT_TRUE(controller->Process(gd_accelerator));
ASSERT_TRUE(button_widget->IsVisible());
EXPECT_EQ(u"Only fullscreen available",
test_api_->GetMainMenuScreenSizeSubtitle());
}
TEST_F(GameDashboardContextTest, NonCompatModeArcGame) {
// Create an ARC game window that doesn't support Compat Mode.
CreateGameWindow(/*is_arc_window=*/true);
@ -1518,7 +1664,7 @@ TEST_F(GameDashboardContextTest, GameDashboardButtonFullscreen) {
AcceleratorControllerImpl* controller =
Shell::Get()->accelerator_controller();
ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
const ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
auto* window_state = WindowState::Get(game_window_.get());
auto* button_widget = test_api_->GetGameDashboardButtonWidget();
CHECK(button_widget);
@ -1563,7 +1709,7 @@ TEST_F(GameDashboardContextTest, GameDashboardButtonFullscreenWithMainMenu) {
AcceleratorControllerImpl* controller =
Shell::Get()->accelerator_controller();
ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
const ui::Accelerator gd_accelerator(ui::VKEY_G, ui::EF_COMMAND_DOWN);
auto* window_state = WindowState::Get(game_window_.get());
auto* button_widget = test_api_->GetGameDashboardButtonWidget();
CHECK(button_widget);

@ -39,6 +39,8 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h"
#include "chromeos/ui/frame/frame_header.h"
#include "components/strings/grit/components_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/accessibility/ax_enums.mojom-shared.h"
@ -325,6 +327,8 @@ class FeatureHeader : public views::View {
FeatureHeader& operator=(const FeatureHeader) = delete;
~FeatureHeader() override = default;
const views::Label* GetSubtitle() { return sub_title_.get(); }
void UpdateColors(bool is_enabled) {
const auto color_id = is_enabled ? cros_tokens::kCrosSysOnSurface
: cros_tokens::kCrosSysDisabled;
@ -360,6 +364,8 @@ class FeatureHeader : public views::View {
BEGIN_METADATA(FeatureHeader)
END_METADATA
} // namespace
// -----------------------------------------------------------------------------
// ScreenSizeRow:
@ -367,11 +373,12 @@ END_METADATA
// +------------------------------------------------+
// | |feature header| |>| |
// +------------------------------------------------+
class ScreenSizeRow : public views::Button {
class GameDashboardMainMenuView::ScreenSizeRow : public views::Button {
METADATA_HEADER(ScreenSizeRow, views::Button)
public:
ScreenSizeRow(PressedCallback callback,
ScreenSizeRow(GameDashboardMainMenuView* main_menu,
PressedCallback callback,
ResizeCompatMode resize_mode,
ArcResizeLockType resize_lock_type)
: views::Button(std::move(callback)) {
@ -379,19 +386,46 @@ class ScreenSizeRow : public views::Button {
bool enabled = false;
int tooltip = 0;
std::u16string subtitle;
switch (resize_lock_type) {
case ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE:
case ArcResizeLockType::RESIZE_ENABLED_TOGGLABLE:
enabled = true;
subtitle = compat_mode_util::GetText(resize_mode);
break;
case ArcResizeLockType::RESIZE_DISABLED_NONTOGGLABLE:
enabled = false;
tooltip =
IDS_ASH_ARC_APP_COMPAT_DISABLED_COMPAT_MODE_BUTTON_TOOLTIP_PHONE;
DCHECK_NE(resize_mode, ResizeCompatMode::kResizable)
<< "The resize mode should never be resizable with an "
"ArcResizeLockType of RESIZE_DISABLED_NONTOGGLABLE.";
if (resize_mode == ResizeCompatMode::kPhone) {
subtitle = l10n_util::GetStringUTF16(
IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_PORTRAIT);
} else {
subtitle = l10n_util::GetStringUTF16(
IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_LANDSCAPE);
}
break;
case ArcResizeLockType::NONE:
enabled = false;
tooltip = IDS_ASH_GAME_DASHBOARD_FEATURE_NOT_AVAILABLE_TOOLTIP;
// Set the subtitle text based on whether the size button in the frame
// header is present.
auto* frame_header =
chromeos::FrameHeader::Get(views::Widget::GetWidgetForNativeWindow(
main_menu->context_->game_window()));
views::FrameCaptionButton* size_button =
frame_header->caption_button_container()->size_button();
if (size_button && size_button->GetVisible()) {
subtitle = l10n_util::GetStringUTF16(
IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_EXIT_FULLSCREEN);
} else {
subtitle = l10n_util::GetStringUTF16(
IDS_ASH_GAME_DASHBOARD_SCREEN_SIZE_ONLY_FULLSCREEN);
}
break;
}
@ -404,10 +438,10 @@ class ScreenSizeRow : public views::Button {
auto* layout =
ConfigureFeatureRowLayout(this, kBottomMultiRowCorners, enabled);
// Add header.
auto* header = AddChildView(std::make_unique<FeatureHeader>(
feature_header_ = AddChildView(std::make_unique<FeatureHeader>(
enabled, compat_mode_util::GetIcon(resize_mode), title));
layout->SetFlexForView(header, /*flex=*/1);
header->UpdateSubtitle(compat_mode_util::GetText(resize_mode));
layout->SetFlexForView(feature_header_, /*flex=*/1);
feature_header_->UpdateSubtitle(subtitle);
// Add arrow icon.
AddChildView(
std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon(
@ -419,13 +453,16 @@ class ScreenSizeRow : public views::Button {
ScreenSizeRow(const ScreenSizeRow&) = delete;
ScreenSizeRow& operator=(const ScreenSizeRow) = delete;
~ScreenSizeRow() override = default;
FeatureHeader* feature_header() { return feature_header_; }
private:
raw_ptr<FeatureHeader> feature_header_;
};
BEGIN_METADATA(ScreenSizeRow)
BEGIN_METADATA(GameDashboardMainMenuView, ScreenSizeRow)
END_METADATA
} // namespace
// -----------------------------------------------------------------------------
// GameDashboardMainMenuView::GameControlsDetailsRow:
@ -1140,7 +1177,8 @@ void GameDashboardMainMenuView::AddScreenSizeSettingsRow(
views::View* container) {
aura::Window* game_window = context_->game_window();
DCHECK(IsArcWindow(game_window));
container->AddChildView(std::make_unique<ScreenSizeRow>(
screen_size_row_ = container->AddChildView(std::make_unique<ScreenSizeRow>(
this,
base::BindRepeating(
&GameDashboardMainMenuView::OnScreenSizeSettingsButtonPressed,
base::Unretained(this)),
@ -1350,6 +1388,11 @@ GameDashboardMainMenuView::GetGameControlsSetupNudgeForTesting() {
return nullptr;
}
const views::Label* GameDashboardMainMenuView::GetScreenSizeRowSubtitle() {
return screen_size_row_ ? screen_size_row_->feature_header()->GetSubtitle()
: nullptr;
}
void GameDashboardMainMenuView::OnThemeChanged() {
views::View::OnThemeChanged();
set_color(GetColorProvider()->GetColor(

@ -59,6 +59,7 @@ class ASH_EXPORT GameDashboardMainMenuView
private:
friend class GameDashboardContextTestApi;
class ScreenSizeRow;
class GameControlsDetailsRow;
// Callbacks for the tiles and buttons in the main menu view.
@ -150,6 +151,10 @@ class ASH_EXPORT GameDashboardMainMenuView
// For test to access the nudge ID in the anonymous namespace.
AnchoredNudge* GetGameControlsSetupNudgeForTesting();
// Returns the screen size row sub-label. If the screen size row or the
// sub-label aren't available, returns null. Visible for testing.
const views::Label* GetScreenSizeRowSubtitle();
// views::Views:
void OnThemeChanged() override;
@ -173,6 +178,9 @@ class ASH_EXPORT GameDashboardMainMenuView
// screen capture tool, allowing the user to select recording options.
raw_ptr<FeatureTile> record_game_tile_ = nullptr;
// Screen Size Settings detail row. Visible for testing.
raw_ptr<ScreenSizeRow> screen_size_row_ = nullptr;
// Game Controls details row to configure Game Controls.
raw_ptr<GameControlsDetailsRow> game_controls_details_ = nullptr;