Commit 26ae1fd0 authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Commit Bot

GMC+Cast: Show artist names and rearrange labels

This CL adds a secondary_title field to media_router.mojom.MediaStatus,
corresponding to the media.metadata.subtitle field in Cast SDK media
status messages, which contains artist names for media.

The artist name is shown in a Cast notification item in Global Media
Controls. Other labels are also rearranged to match the mocks.

Screenshot:
https://drive.google.com/file/d/1Ecr-7WsGFE7Be3MuPvsau3SEUwKPQPJr/view?usp=sharing

Bug: 1042016
Change-Id: Iff3cc50af41ef24e6a4e8ec10090acbffe049f8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2003388
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732551}
parent 2e6955cc
...@@ -189,6 +189,8 @@ void CastMediaController::UpdateMediaStatus(const base::Value& message_value) { ...@@ -189,6 +189,8 @@ void CastMediaController::UpdateMediaStatus(const base::Value& message_value) {
SetIfValid(&media_session_id_, status_value.FindKey("mediaSessionId")); SetIfValid(&media_session_id_, status_value.FindKey("mediaSessionId"));
SetIfValid(&media_status_.title, SetIfValid(&media_status_.title,
status_value.FindPath("media.metadata.title")); status_value.FindPath("media.metadata.title"));
SetIfValid(&media_status_.secondary_title,
status_value.FindPath("media.metadata.subtitle"));
SetIfValid(&media_status_.current_time, status_value.FindKey("currentTime")); SetIfValid(&media_status_.current_time, status_value.FindKey("currentTime"));
SetIfValid(&media_status_.duration, status_value.FindPath("media.duration")); SetIfValid(&media_status_.duration, status_value.FindPath("media.duration"));
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/ui/global_media_controls/cast_media_notification_item.h" #include "chrome/browser/ui/global_media_controls/cast_media_notification_item.h"
#include "base/i18n/rtl.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/global_media_controls/cast_media_session_controller.h" #include "chrome/browser/ui/global_media_controls/cast_media_session_controller.h"
...@@ -111,6 +112,21 @@ media_session::mojom::MediaSessionInfo::SessionState ToSessionState( ...@@ -111,6 +112,21 @@ media_session::mojom::MediaSessionInfo::SessionState ToSessionState(
} }
} }
base::string16 GetSourceTitle(const media_router::MediaRoute& route) {
if (route.media_sink_name().empty())
return base::UTF8ToUTF16(route.description());
if (route.description().empty())
return base::UTF8ToUTF16(route.media_sink_name());
const char kSeparator[] = " \xC2\xB7 "; // "Middle dot" character.
const std::string source_title =
base::i18n::IsRTL()
? route.media_sink_name() + kSeparator + route.description()
: route.description() + kSeparator + route.media_sink_name();
return base::UTF8ToUTF16(source_title);
}
} // namespace } // namespace
CastMediaNotificationItem::CastMediaNotificationItem( CastMediaNotificationItem::CastMediaNotificationItem(
...@@ -126,8 +142,7 @@ CastMediaNotificationItem::CastMediaNotificationItem( ...@@ -126,8 +142,7 @@ CastMediaNotificationItem::CastMediaNotificationItem(
base::BindRepeating(&CastMediaNotificationItem::ImageChanged, base::BindRepeating(&CastMediaNotificationItem::ImageChanged,
base::Unretained(this))), base::Unretained(this))),
session_info_(CreateSessionInfo()) { session_info_(CreateSessionInfo()) {
metadata_.source_title = base::UTF8ToUTF16(route.media_sink_name()); metadata_.source_title = GetSourceTitle(route);
metadata_.artist = base::UTF8ToUTF16(route.description());
notification_controller_->ShowNotification(media_route_id_); notification_controller_->ShowNotification(media_route_id_);
} }
...@@ -153,6 +168,7 @@ void CastMediaNotificationItem::Dismiss() { ...@@ -153,6 +168,7 @@ void CastMediaNotificationItem::Dismiss() {
void CastMediaNotificationItem::OnMediaStatusUpdated( void CastMediaNotificationItem::OnMediaStatusUpdated(
media_router::mojom::MediaStatusPtr status) { media_router::mojom::MediaStatusPtr status) {
metadata_.title = base::UTF8ToUTF16(status->title); metadata_.title = base::UTF8ToUTF16(status->title);
metadata_.artist = base::UTF8ToUTF16(status->secondary_title);
actions_ = ToMediaSessionActions(*status); actions_ = ToMediaSessionActions(*status);
session_info_->state = ToSessionState(status->play_state); session_info_->state = ToSessionState(status->play_state);
session_info_->playback_state = ToPlaybackState(status->play_state); session_info_->playback_state = ToPlaybackState(status->play_state);
...@@ -171,8 +187,7 @@ void CastMediaNotificationItem::OnRouteUpdated( ...@@ -171,8 +187,7 @@ void CastMediaNotificationItem::OnRouteUpdated(
const media_router::MediaRoute& route) { const media_router::MediaRoute& route) {
DCHECK_EQ(route.media_route_id(), media_route_id_); DCHECK_EQ(route.media_route_id(), media_route_id_);
bool updated = false; bool updated = false;
const base::string16 new_source_title = const base::string16 new_source_title = GetSourceTitle(route);
base::UTF8ToUTF16(route.media_sink_name());
if (metadata_.source_title != new_source_title) { if (metadata_.source_title != new_source_title) {
metadata_.source_title = new_source_title; metadata_.source_title = new_source_title;
updated = true; updated = true;
......
...@@ -24,7 +24,7 @@ using testing::AtLeast; ...@@ -24,7 +24,7 @@ using testing::AtLeast;
namespace { namespace {
constexpr char kRouteDesc[] = "route description"; constexpr char kRouteDesc[] = "My App";
constexpr char kRouteId[] = "route_id"; constexpr char kRouteId[] = "route_id";
constexpr char kSinkName[] = "My Sink"; constexpr char kSinkName[] = "My Sink";
...@@ -119,8 +119,9 @@ class CastMediaNotificationItemTest : public testing::Test { ...@@ -119,8 +119,9 @@ class CastMediaNotificationItemTest : public testing::Test {
}); });
EXPECT_CALL(view_, UpdateWithMediaMetadata(_)) EXPECT_CALL(view_, UpdateWithMediaMetadata(_))
.WillOnce([&](const media_session::MediaMetadata& metadata) { .WillOnce([&](const media_session::MediaMetadata& metadata) {
EXPECT_EQ(base::UTF8ToUTF16(kRouteDesc), metadata.artist); const std::string separator = " \xC2\xB7 ";
EXPECT_EQ(base::UTF8ToUTF16(kSinkName), metadata.source_title); EXPECT_EQ(base::UTF8ToUTF16(kRouteDesc + separator + kSinkName),
metadata.source_title);
}); });
item_->SetView(&view_); item_->SetView(&view_);
testing::Mock::VerifyAndClearExpectations(&view_); testing::Mock::VerifyAndClearExpectations(&view_);
...@@ -167,11 +168,14 @@ TEST_F(CastMediaNotificationItemTest, UpdateSessionInfo) { ...@@ -167,11 +168,14 @@ TEST_F(CastMediaNotificationItemTest, UpdateSessionInfo) {
TEST_F(CastMediaNotificationItemTest, UpdateMetadata) { TEST_F(CastMediaNotificationItemTest, UpdateMetadata) {
SetView(); SetView();
auto status = MediaStatus::New(); auto status = MediaStatus::New();
std::string title = "my title"; const std::string title = "my title";
const std::string secondary_title = "my artist";
status->title = title; status->title = title;
status->secondary_title = secondary_title;
EXPECT_CALL(view_, UpdateWithMediaMetadata(_)) EXPECT_CALL(view_, UpdateWithMediaMetadata(_))
.WillOnce([&](const media_session::MediaMetadata& metadata) { .WillOnce([&](const media_session::MediaMetadata& metadata) {
EXPECT_EQ(base::UTF8ToUTF16(title), metadata.title); EXPECT_EQ(base::UTF8ToUTF16(title), metadata.title);
EXPECT_EQ(base::UTF8ToUTF16(secondary_title), metadata.artist);
}); });
item_->OnMediaStatusUpdated(std::move(status)); item_->OnMediaStatusUpdated(std::move(status));
} }
......
...@@ -117,8 +117,9 @@ TEST_F(CastMediaNotificationProviderTest, UpdateRoute) { ...@@ -117,8 +117,9 @@ TEST_F(CastMediaNotificationProviderTest, UpdateRoute) {
EXPECT_CALL(view, UpdateWithMediaMetadata(_)) EXPECT_CALL(view, UpdateWithMediaMetadata(_))
.WillOnce([&](const media_session::MediaMetadata& metadata) { .WillOnce([&](const media_session::MediaMetadata& metadata) {
EXPECT_EQ(base::UTF8ToUTF16(new_sink), metadata.source_title); const std::string separator = " \xC2\xB7 ";
EXPECT_EQ(base::UTF8ToUTF16(new_description), metadata.artist); EXPECT_EQ(base::UTF8ToUTF16(new_description + separator + new_sink),
metadata.source_title);
}); });
notification_provider_->OnRoutesUpdated({route}, {}); notification_provider_->OnRoutesUpdated({route}, {});
} }
...@@ -31,6 +31,11 @@ struct MediaStatus { ...@@ -31,6 +31,11 @@ struct MediaStatus {
// For a Presentation API route, it is the presentation page title. // For a Presentation API route, it is the presentation page title.
string title; string title;
// The secondary label for the currently playing media. For example, this may
// be the artist name for a video or a song. It may be empty for mirroring or
// non-Cast-SDK Presentation API routes.
string secondary_title;
// If this is true, the media can be played and paused through its // If this is true, the media can be played and paused through its
// MediaController. // MediaController.
bool can_play_pause; bool can_play_pause;
......
...@@ -149,6 +149,7 @@ IPEndpointAdapter.prototype.toNewVersion = function() { ...@@ -149,6 +149,7 @@ IPEndpointAdapter.prototype.toNewVersion = function() {
*/ */
function MediaStatusAdapter(fields) { function MediaStatusAdapter(fields) {
this.title = null; this.title = null;
this.secondary_title = null;
this.can_play_pause = false; this.can_play_pause = false;
this.can_mute = false; this.can_mute = false;
this.can_set_volume = false; this.can_set_volume = false;
...@@ -170,6 +171,7 @@ MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState; ...@@ -170,6 +171,7 @@ MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState;
MediaStatusAdapter.prototype.toNewVersion = function() { MediaStatusAdapter.prototype.toNewVersion = function() {
return new mediaRouter.mojom.MediaStatus({ return new mediaRouter.mojom.MediaStatus({
'title': this.title, 'title': this.title,
'secondaryTitle': this.secondary_title || '',
'canPlayPause': this.can_play_pause, 'canPlayPause': this.can_play_pause,
'canMute': this.can_mute, 'canMute': this.can_mute,
'canSetVolume': this.can_set_volume, 'canSetVolume': this.can_set_volume,
......
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