0

Add "Devices available" sublabel to quick settings Cast feature tile

With QsRevamp the quick settings Cast feature tile has a "devices
available" sub-label when:
* Cast devices are available on the network ("sinks")
* Access code casting is available

Bug: b:252872586
Test: added to ash_unittests
Change-Id: I29e6965976d525bdb444a03a5ede757196eb4b54
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4103203
Reviewed-by: Jiaming Cheng <jiamingc@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1083165}
This commit is contained in:
James Cook
2022-12-14 17:21:27 +00:00
committed by Chromium LUCI CQ
parent 635bda168c
commit 9e43e77e3a
6 changed files with 71 additions and 8 deletions

@ -480,6 +480,9 @@ Style notes:
<message name="IDS_ASH_STATUS_TRAY_CAST_SHORT" desc="The label used for Cast button in system tray bubble. [CHAR_LIMIT=14]">
Cast
</message>
<message name="IDS_ASH_STATUS_TRAY_CAST_DEVICES_AVAILABLE" desc="Subtitle under the Cast button in the system tray bubble when Chromecast devices are available for casting">
Devices available
</message>
<message name="IDS_ASH_STATUS_TRAY_CAST_TOOLTIP" desc="The tooltip text used for Cast button in system tray bubble.">
Show cast devices
</message>

@ -0,0 +1 @@
c35a1d6ab1a9cee8df1789a5720288b62ac31c8a

@ -30,7 +30,7 @@ CastFeaturePodController::CastFeaturePodController(
: tray_controller_(tray_controller) {}
CastFeaturePodController::~CastFeaturePodController() {
if (CastConfigController::Get() && button_)
if (CastConfigController::Get() && (button_ || tile_))
CastConfigController::Get()->RemoveObserver(this);
}
@ -60,10 +60,11 @@ std::unique_ptr<FeatureTile> CastFeaturePodController::CreateTile() {
DCHECK(features::IsQsRevampEnabled());
auto tile = std::make_unique<FeatureTile>(base::BindRepeating(
&CastFeaturePodController::OnIconPressed, weak_factory_.GetWeakPtr()));
tile_ = tile.get();
tile->SetVectorIcon(kUnifiedMenuCastIcon);
tile->SetLabel(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST));
// TODO(b/252872586): Show sublabel with cast device availability.
tile->SetSubLabelVisibility(false);
tile->SetSubLabel(
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_DEVICES_AVAILABLE));
const std::u16string tooltip =
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_TOOLTIP);
tile->SetTooltipText(tooltip);
@ -82,6 +83,12 @@ std::unique_ptr<FeatureTile> CastFeaturePodController::CreateTile() {
TrackVisibilityUMA();
tile->SetVisible(visible);
// Refresh cast devices to update the "Devices available" sublabel visibility.
if (cast_config) {
cast_config->AddObserver(this);
cast_config->RequestDeviceRefresh();
}
UpdateSublabelVisibility();
return tile;
}
@ -116,8 +123,10 @@ void CastFeaturePodController::OnLabelPressed() {
void CastFeaturePodController::OnDevicesUpdated(
const std::vector<SinkAndRoute>& devices) {
DCHECK(!features::IsQsRevampEnabled());
Update();
if (features::IsQsRevampEnabled())
UpdateSublabelVisibility();
else
Update();
}
void CastFeaturePodController::Update() {
@ -132,4 +141,14 @@ void CastFeaturePodController::Update() {
button_->SetVisible(visible);
}
void CastFeaturePodController::UpdateSublabelVisibility() {
DCHECK(features::IsQsRevampEnabled());
DCHECK(tile_);
auto* cast_config = CastConfigController::Get();
bool devices_available =
cast_config && (cast_config->HasSinksAndRoutes() ||
cast_config->AccessCodeCastingEnabled());
tile_->SetSubLabelVisibility(devices_available);
}
} // namespace ash

@ -39,11 +39,17 @@ class ASH_EXPORT CastFeaturePodController
void OnDevicesUpdated(const std::vector<SinkAndRoute>& devices) override;
private:
// Updates feature pod button visibility. Used pre-QsRevamp.
void Update();
// Unowned.
// Updates tile sublabel visibility. Used post-QsRevamp.
void UpdateSublabelVisibility();
UnifiedSystemTrayController* const tray_controller_;
// Owned by views hierarchy.
FeaturePodButton* button_ = nullptr;
FeatureTile* tile_ = nullptr;
base::WeakPtrFactory<CastFeaturePodController> weak_factory_{this};
};

@ -28,9 +28,11 @@ class TestCastConfigController : public CastConfigController {
bool HasMediaRouterForPrimaryProfile() const override {
return has_media_router_;
}
bool HasSinksAndRoutes() const override { return false; }
bool HasSinksAndRoutes() const override { return has_sinks_and_routes_; }
bool HasActiveRoute() const override { return false; }
bool AccessCodeCastingEnabled() const override { return false; }
bool AccessCodeCastingEnabled() const override {
return access_code_casting_enabled_;
}
void RequestDeviceRefresh() override {}
const std::vector<SinkAndRoute>& GetSinksAndRoutes() override {
return sinks_and_routes_;
@ -39,6 +41,8 @@ class TestCastConfigController : public CastConfigController {
void StopCasting(const std::string& route_id) override {}
bool has_media_router_ = true;
bool has_sinks_and_routes_ = false;
bool access_code_casting_enabled_ = false;
std::vector<SinkAndRoute> sinks_and_routes_;
};
@ -79,5 +83,34 @@ TEST_F(CastFeaturePodControllerTest, TileNotVisibleWhenNoMediaRouter) {
EXPECT_FALSE(tile->GetVisible());
}
TEST_F(CastFeaturePodControllerTest, SubLabelVisibleWhenSinksAvailable) {
// When cast devices are available, the sub-label is visible.
cast_config_.has_sinks_and_routes_ = true;
std::unique_ptr<FeatureTile> tile = controller_->CreateTile();
EXPECT_TRUE(tile->sub_label()->GetVisible());
EXPECT_EQ(tile->sub_label()->GetText(), u"Devices available");
}
TEST_F(CastFeaturePodControllerTest,
SubLabelVisibleWhenAccessCodeCastingEnabled) {
// When access code casting is available, the sub-label is visible.
cast_config_.access_code_casting_enabled_ = true;
std::unique_ptr<FeatureTile> tile = controller_->CreateTile();
EXPECT_TRUE(tile->sub_label()->GetVisible());
EXPECT_EQ(tile->sub_label()->GetText(), u"Devices available");
}
TEST_F(CastFeaturePodControllerTest, SubLabelVisibleOnDevicesUpdated) {
// By default the sub-label is hidden.
std::unique_ptr<FeatureTile> tile = controller_->CreateTile();
EXPECT_FALSE(tile->sub_label()->GetVisible());
// If cast devices become available while the tray is open, the sub-label
// becomes visible.
cast_config_.has_sinks_and_routes_ = true;
controller_->OnDevicesUpdated({});
EXPECT_TRUE(tile->sub_label()->GetVisible());
}
} // namespace
} // namespace ash

@ -94,6 +94,7 @@ class ASH_EXPORT FeatureTile : public views::Button {
// Sets the tooltip text of `drill_container_` and `drill_in_button_`.
void SetDrillInButtonTooltipText(const std::u16string& text);
views::Label* sub_label() { return sub_label_; }
views::LabelButton* drill_in_button() { return drill_in_button_; }
private: